Java getActivity().runOnUiThread(new Runnable(){ 上的 NullPointerException

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23825549/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 01:25:25  来源:igfitidea点击:

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

javaandroideclipseclassnullpointerexception

提问by Robin

I know there are many different causes for NPEbut mine is slightly weird (At least to me).

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

So I have converted my Activitiesto Fragmentssuccessfully, but my problem appears to be coming from the function that displays the date. When the application is running, everything works just fine. But as soon as you press the back button. The app force closes, then in the log it says I'm getting NullPointerExceptionat line 102. So looking at the code, I did research on this but unfortunately got nothing.

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

This is the line where the error is coming from when you press the back button.

当您按下后退按钮时,这是错误来自的行。

getActivity().runOnUiThread(new Runnable(){

Also I have tried disabling the back button (As I'm building a launcher and it's not needed). But it doesn't seem to be working.

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

Here is the code for the whole date displaying method/function.

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

// (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();

Thanks for your time, hopefully you can shed some light on what I'm doing wrong.

感谢您的时间,希望您能阐明我做错了什么。

Logcat -

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.run(UtilsFragment.java:102)

采纳答案by Farouk Touzi

I'm almost sure that this is caused when the thread finish its work but the activity is no longer visible.

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

You should check if the getActivity()call return null, and ...

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

To apply corrections on your code, look at this:

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

// (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();

回答by Macrosoft-Dev

Try this one

试试这个

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

is date is null or not check

日期是否为空或不检查

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

回答by Mark Pazon

After pressing back, your background thread is still running. By the time that thread reaches the getActivity().runOnUiThread()code, the activity no longer exists. Check if the activity still exists like so:

按回后,您的后台线程仍在运行。当线程到达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));
            }
        });
}

回答by laalto

The reason for the NPE is that your thread is not bound to the fragment lifecycle. Once the fragment is detached from its hosting activity, getActivity()returns null.

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

As a solution, consider removing the thread altogether and just use postDelayed()on a Handleron the UI thread to post Runnables that do the updates you want after a delay.

作为一个解决方案,考虑完全移除该线程,只是用postDelayed()HandlerUI线程上张贴Runnables表示你的延迟之后要更新。

回答by Apoorv

Put

if(getActivity() == null)
        return;

before getActivity().runOnUiThread(new Runnable(){that way when the back button is closed and your Threadis still running it will check whether the calling Activitystill exists.

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

If it does not it will return.

如果没有,它会return