关于java:getActivity()的NullPointerException .runOnUiThread(new Runnable(){

NullPointerException on getActivity().runOnUiThread(new Runnable(){

本问题已经有最佳答案,请猛点这里访问。

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

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

这是按下后退按钮时出现错误的行。

1
getActivity().runOnUiThread(new Runnable(){

此外,我已经尝试禁用后退按钮(因为我正在构建一个启动器,它不需要)。 但它似乎没有奏效。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// (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 -

1
2
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)


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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// (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();


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

1
2
3
4
5
6
7
8
9
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));
            }
        });
}


1
2
if(getActivity() == null)
        return;

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

如果没有,它将return


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

作为一个解决方案,考虑完全删除线程,只需在UI线程上的Handler上使用postDelayed()发布Runnable,它们会在延迟后发布您想要的更新。


试试这个吧

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

是日期为空或不检查

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