public class LooperThread extends Thread {
private Handler handler = null;
public Handler getHandler() {
return handler;
}
@Override
public void run() {
Looper.prepare();
handler = new Handler();
Looper.loop();
}
}
class Helper {
private static LooperThread databaseThread = null;
static {
databaseThread = new LooperThread();
databaseThread.start();
}
public void postRunable(Runnable r) {
databaseThread.getHandler().post(r);
databaseThread.getHandler().sendMessage(new Message());
}
}
//ui thread.
class UIActivity extends Activity {
private Helper helper = new Helper();
public void onCreate(Bundle savedInstanceState) {
helper.postRunnable(new Runnable() {
public void run() {
//work asyn,like query from db.
}
});
}
}
有时会调用databaseThread.getHandler().post(r);
,它会返回null,有时则不会,为什么会这样?通常情况下,handler
应该是静态块的初始值。
答案 0 :(得分:3)
你有时会得到一个空Handler
,因为在静态初始值设定项中调用databaseThread.start();
只能确保线程将在未来的某个时刻启动,这意味着在这之间创建一个竞争条件处理程序在新线程内创建,getHandler()
在旧线程中调用。拥有一个带有背景循环器的线程是Android中非常常见的模式,所以有一个类来帮助我们。
首先删除您的LooperThread
课程,然后使用SDK HandlerThread
。
您的Helper
课程现在应该是
class Helper {
private static final HandlerThread databaseThread;
private static final Handler dbHandler;
static {
databaseThread = new HandlerThread("database thread");
databaseThread.start();
// If you have called HandelerThread#start()
// HandlerThread#getLooper() will block until the looper is initialized and Looping
dbHandler = new Handler(databaseThread.getLooper());
}
public void postRunable(Runnable r) {
dbHandler.post(r);
}
}
答案 1 :(得分:0)
getHandler方法返回null,因为未附加视图:
public Handler getHandler() {
if (mAttachInfo != null) {
return mAttachInfo.mHandler;
}
return null;
}
mAttachInfo
在dispatchAttachedToWindow
中设置,并在dispatchDetachedFromWindow
中隐藏。
而不是mapView.getHandler().post()
,您可以直接使用mapView.post()
(似乎使用getHandler().post()
或ViewRootImpl.getRunQueue().post())
。