【问题标题】:NullPointerException on getActivity().runOnUiThread(new Runnable(){ [duplicate]getActivity().runOnUiThread(new Runnable(){ [重复] 上的 NullPointerException
【发布时间】:2014-07-12 14:18:28
【问题描述】:

我知道NPE 有很多不同的原因,但我的有点奇怪(至少对我而言)。

所以我已经成功地将我的Activities 转换为Fragments,但我的问题似乎来自显示日期的函数。当应用程序运行时,一切正常。但是只要你按下后退按钮。应用程序强制关闭,然后在日志中显示我在第 102 行收到NullPointerException。所以查看代码,我对此进行了研究,但不幸的是什么也没得到。

这是您按下后退按钮时错误所在的行。

getActivity().runOnUiThread(new Runnable(){

我还尝试禁用后退按钮(因为我正在构建启动器并且不需要它)。但它似乎不起作用。

这是整个日期显示方法/功能的代码。

// (Calendar) Date function - Displays dateview on Card
final boolean keepRunning1 = true;
Thread thread_two = new Thread(){
    @Override
    public void run(){

        while(keepRunning1){

            // Make the thread wait half a second. If you want...
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                Toast.makeText(getActivity().getApplicationContext(), "Default Signature Fail", Toast.LENGTH_LONG).show();
                e.printStackTrace();
            }

                getActivity().runOnUiThread(new Runnable(){
                @Override
                public void run(){
                    TextView date = (TextView) getView().findViewById(R.id.date);
                    date.setText(DateUtils.formatDateTime(getActivity().getBaseContext(), System.currentTimeMillis(),DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR));
                }
            });
        }
    }
};

thread_two.start();

感谢您抽出宝贵时间,希望您能阐明我做错了什么。

Logcat -

05-23 21:17:33.216: E/AndroidRuntime(6906): java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v4.app.FragmentActivity.runOnUiThread(java.lang.Runnable)' on a null object reference
05-23 21:17:33.216: E/AndroidRuntime(6906):     at com.activelauncher.fragments.UtilsFragment$2.run(UtilsFragment.java:102)

【问题讨论】:

  • Activity 可能会在单击后退按钮时关闭,因此您将 getActivity() 设为 null
  • @Apoorv 如何在单击后退按钮时阻止活动关闭?

标签: java android eclipse class nullpointerexception


【解决方案1】:

我几乎可以肯定这是由于线程完成其工作但活动不再可见时引起的。

您应该检查getActivity() 调用是否返回null,并且...

要对您的代码应用更正,请查看以下内容:

// (Calendar) Date function - Displays dateview on Card
final boolean keepRunning1 = true;
Thread thread_two = new Thread(){

@Override
public void run(){

    while(keepRunning1){

        // Make the thread wait half a second. If you want...
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            Toast.makeText(getActivity().getApplicationContext(), "Default Signature                         Fail", Toast.LENGTH_LONG).show();
            e.printStackTrace();
        }

        // here you check the value of getActivity() and break up if needed
        if(getActivity() == null)
            return;

        getActivity().runOnUiThread(new Runnable(){
        @Override
        public void run(){
           TextView date = (TextView) getView().findViewById(R.id.date);
           date.setText(DateUtils.formatDateTime(getActivity().getBaseContext(), System.currentTimeMillis(),DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR));
           }
         });
    }
}
};thread_two.start();

【讨论】:

  • @FaroukTouzi 无论如何我都想执行runOnUiThread 中的代码。如果我这样做,那么它里面的代码根本不会被执行吗?
  • 就像我上面说的,如果 main Activity 不再可见,runOnUiThread 里面的代码就不会被执行。这就是为什么您应该始终检查主要活动的可见性,以避免应用崩溃。
【解决方案2】:

按下返回后,您的后台线程仍在运行。当该线程到达getActivity().runOnUiThread() 代码时,该活动不再存在。检查活动是否仍然存在,如下所示:

if (getActivity() != null) {
        getActivity().runOnUiThread(new Runnable(){
                @Override
                public void run(){
                    TextView date = (TextView) getView().findViewById(R.id.date);
                    date.setText(DateUtils.formatDateTime(getActivity().getBaseContext(), System.currentTimeMillis(),DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR));
            }
        });
}

【讨论】:

    【解决方案3】:

    if(getActivity() == null)
            return;
    

    getActivity().runOnUiThread(new Runnable(){ 之前,当后退按钮关闭并且您的Thread 仍在运行时,它将检查调用Activity 是否仍然存在。

    如果没有,它会return

    【讨论】:

    • 但是应该进行的操作呢?如果getActivity() 为null,则您return,但随后必须再次调用该方法,以便在getActivity() 不为null 时完成...
    【解决方案4】:

    NPE 的原因是您的线程未绑定到片段生命周期。一旦片段与其托管活动分离,getActivity() 将返回 null。

    作为一种解决方案,请考虑完全删除线程,只需在 UI 线程上的 Handler 上使用 postDelayed() 即可发布 Runnables,以便在延迟后执行您想要的更新。

    【讨论】:

    • Handler 的 postDelayed 方法内部 getActivity() 为 null :(
    【解决方案5】:

    试试这个

    TextView date = (TextView) getView().findViewById(R.id.date);
    

    日期是否为空或不检查

    if(date !=null){
                        date.setText(DateUtils.formatDateTime(getActivity().getBaseContext(), System.currentTimeMillis(),DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR));
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-04
      • 2018-12-08
      • 2019-06-01
      • 2018-03-02
      • 1970-01-01
      • 2012-01-07
      • 1970-01-01
      相关资源
      最近更新 更多