get处理程序在LooperThread中返回null

时间:2014-03-20 08:54:05

标签: android multithreading handler

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应该是静态块的初始值。

2 个答案:

答案 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;
}

mAttachInfodispatchAttachedToWindow中设置,并在dispatchDetachedFromWindow中隐藏。

而不是mapView.getHandler().post(),您可以直接使用mapView.post()(似乎使用getHandler().post()ViewRootImpl.getRunQueue().post())