問題:
寫了一個sdk給其他人用,提供一個回調函數,函數使用了handler處理消息
// handler監聽網絡請求,完成后操作回調函數 final Handler trigerGfHandler = new Handler() { public void handleMessage(Message msg) { listener.onGeofenceTrigger(gfMatchIds); } };
在使用這個sdk提供的函數時,報錯:
01-02 15:46:10.498: E/AndroidRuntime(16352): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
使用方式是在service中使用。在activity中使用正常。
問題解決:
在調用handler的方法前執行Looper.prepare()。Looper用於封裝了android線程中的消息循環,默認情況下一個線程是不存在消息循環(message loop)的,需要調用Looper.prepare()來給線程創建一個消息循環,調用Looper.loop()來使消息循環起作用。
因為activity的主線程是自己創建消息隊列的,所以在Activity中新建Handler時,不需要先調用Looper.prepare()
代碼:
Looper.prepare(); // handler監聽網絡請求,完成后操作回調函數 final Handler trigerGfHandler = new Handler() { public void handleMessage(Message msg) { listener.onGeofenceTrigger(gfMatchIds); } };
Looper.loop();
參考:http://www.myexception.cn/mobile/410671.html
========================
新問題:
當此函數在activity中調用時,也會報錯,因為activity已經自動創建了消息隊列。所以重復創建會出錯。
查看官網關於Looper的例子:
class LooperThread extends Thread { public Handler mHandler; public void run() { Looper.prepare(); mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; Looper.loop(); } }
將handler寫在一個線程中。使此消息隊列與主線程中消息隊列分離。
最終寫法為:
class LooperThread extends Thread { public void run() { Looper.prepare(); trigerGfHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here listener.onGeofenceTrigger(gfMatchIds); } }; Looper.loop(); } } LooperThread looper = new LooperThread(); looper.start();