標籤:ade override except 手動 lan 預設 reader 不能 沒有
在子線程中new一個Handler為什麼會報以下錯誤?
java.lang.RuntimeException:
Can‘t create handler inside thread that has not called Looper.prepare()
這是因為Handler對象與其調用者在同一線程中,如果在Handler中設定了延時操作,則調用線程也會堵塞。每個Handler對象都會綁定一個Looper對象,每個Looper對象對應一個訊息佇列(MessageQueue)。如果在建立Handler時不指定與其綁定的Looper對象,系統預設會將當前線程的Looper綁定到該Handler上。
在主線程中,可以直接使用new Handler()建立Handler對象,其將自動與主線程的Looper對象綁定;在非主線程中直接這樣建立Handler則會報錯,因為Android系統預設情況下非主線程中沒有開啟Looper,而Handler對象必須綁定Looper對象。這種情況下,則有兩種方法可以解決此問題:
方法1:需先在該線程中手動開啟Looper(Looper.prepare()-->Looper.loop()),然後將其綁定到Handler對象上;
final Runnable runnable = new Runnable() {
@Override
public void run() {
//執行耗時操作
try {
Log.e("bm", "runnable線程: " + Thread.currentThread().getId()+ " name:" + Thread.currentThread().getName());
Thread.sleep(2000);
Log.e("bm", "執行完耗時操作了~");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
new Thread() {
public void run() {
Looper.prepare();
new Handler().post(runnable);//在子線程中直接去new 一個handler
Looper.loop(); //這種情況下,Runnable對象是運行在子線程中的,可以進行連網操作,但是不能更新UI
}
}.start();
方法2:通過Looper.getMainLooper(),獲得主線程的Looper,將其綁定到此Handler對象上。
final Runnable runnable = new Runnable() {
@Override
public void run() {
//執行耗時操作
try {
Log.e("bm", "runnable線程: " + Thread.currentThread().getId()+ " name:" + Thread.currentThread().getName());
Thread.sleep(2000);
Log.e("bm", "執行完耗時操作了~");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
new Thread() {
public void run() {
new Handler(Looper.getMainLooper()).post(runnable);//在子線程中直接去new 一個handler
//這種情況下,Runnable對象是運行在主線程中的,不可以進行連網操作,但是可以更新UI
}
}.start();
轉 在子線程中new Handler報錯--Can't create handler inside thread that has not called Looper.prepare()