Java 由于线程未在方向更改前停止,导致空指针错误
我有一个显示天气数据的片段,它运行一个后台线程,基本上只是调用主UI中的一个函数来检查我的预测是否仍然有效。此函数更新UI,因此我使用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
处理程序
并将可运行
发布到主线程,如下所示:
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();我认为错误来自这里。