Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/183.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 由于线程未在方向更改前停止,导致空指针错误_Java_Android_Multithreading_Android Handler - Fatal编程技术网

Java 由于线程未在方向更改前停止,导致空指针错误

Java 由于线程未在方向更改前停止,导致空指针错误,java,android,multithreading,android-handler,Java,Android,Multithreading,Android Handler,我有一个显示天气数据的片段,它运行一个后台线程,基本上只是调用主UI中的一个函数来检查我的预测是否仍然有效。此函数更新UI,因此我使用处理程序并将可运行发布到主线程,如下所示: public class WaveFxListFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor>, View.OnClickListener { // ..... // han

我有一个显示天气数据的片段,它运行一个后台线程,基本上只是调用主UI中的一个函数来检查我的预测是否仍然有效。此函数更新UI,因此我使用
处理程序
并将
可运行
发布到主线程,如下所示:

public class WaveFxListFragment extends Fragment implements
        LoaderManager.LoaderCallbacks<Cursor>, View.OnClickListener {

    // .....

    // handler for dealing with synchronising update thread with UI
    private Handler mHandler;
    private UpdateThread mUpdateThread;

    private class UpdateThread extends Thread {
        volatile boolean running = false;

        @Override
        public void run() {
            running = true;

            while (running) {
                // get main UI thread to perform update check:
                Log.d(TAG, "Handler is " + mHandler);
                mHandler.post(new Runnable() { // getting null pointer error here!
                    @Override
                    public void run() {
                        checkValidTime();
                    }
                });

                try {
                    Thread.sleep(1000); // sleep 1 second
                } catch (InterruptedException e) {
                    Log.d(TAG, "Thread was interrupted!");
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Reuse existing handler:
        mHandler = getActivity().getWindow().getDecorView().getHandler();
    }

    @Override
    public void onResume() {
        super.onResume();
        // start update checker:
        mUpdateThread = new UpdateThread();
        mUpdateThread.start();
    }

    @Override
    public void onPause() { 
            // stop update thread
            Log.d(TAG, "Asking thread to stop");
            mUpdateThread.running = false;

            super.onPause();
    }
}
公共类wavexlistfragment扩展了片段实现
LoaderManager.LoaderCallbacks,View.OnClickListener{
// .....
//处理与UI同步更新线程的处理程序
私人经理人;
私有UpdateThread mUpdateThread;
私有类UpdateThread扩展线程{
volatile boolean running=false;
@凌驾
公开募捐{
运行=真;
(跑步时){
//获取主UI线程以执行更新检查:
Log.d(标记“Handler is”+mHandler);
mHandler.post(new Runnable(){//此处获取空指针错误!
@凌驾
公开募捐{
checkValidTime();
}
});
试一试{
Thread.sleep(1000);//睡眠1秒
}捕捉(中断异常e){
Log.d(标记“线程被中断!”);
e、 printStackTrace();
}
}
}
}
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//重用现有处理程序:
mHandler=getActivity().getWindow().getDecorView().getHandler();
}
@凌驾
恢复时公开作废(){
super.onResume();
//启动更新检查器:
mUpdateThread=新的UpdateThread();
mUpdateThread.start();
}
@凌驾
public void onPause(){
//停止更新线程
Log.d(标记“请求线程停止”);
mUpdateThread.running=false;
super.onPause();
}
}
这很好用;问题是当我改变屏幕方向时。当前活动将被销毁,如果线程正在运行,它将尝试向不再存在的UI线程发布
Runnable
。因此,我在
UpdateThread
类中放置了
running
成员变量,并在我的活动调用
onPause
时将if设置为
false
。但是,即使我已经将
UpdateThread.running
变量设置为false,我的线程仍然尝试发布
Runnable
,但是
处理程序现在为null!它不应该走那么远,但它是

我做错了吗?我的日志消息“请求线程停止”被打印出来,所以我知道它正在将running设置为false

有人能提供见解吗


感谢您为解决此问题所做的一些事情

  • 将running设置为false后中断线程。这将导致线程提前退出,或者至少使错误提前出现

  • 检查更新线程中的处理程序是否为null,并在onPause中将其设置为null

  • 将mHandler的分配移动到onResume,以确保在调用更新线程时mHandler有效

  • mHandler=getActivity().getWindow().getDecorView().getHandler();我认为错误来自这里。