下面的代码会报异常:
SecondActivity.java:
package com.example.handler;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.widget.TextView;
public class SecondActivity extends Activity {
private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
System.out.println("UI---------->"+Thread.currentThread());
};
};
class MyThread extends Thread{
public Handler handler;
public Looper looper;
@Override
public void run() {
Looper.prepare();
looper=Looper.myLooper();
handler =new Handler(){
@Override
public void handleMessage(Message msg) {
System.out.println("currentThread:"+Thread.currentThread());
}
};
Looper.loop();
}
}
private MyThread thread;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
tv.setText("hello handler");
setContentView(tv);
thread = new MyThread();
thread.start();
// try {
// Thread.sleep(500);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// thread.handler.sendEmptyMessage(1);
// handler.sendEmptyMessage(1);
handler = new Handler(thread.looper){
@Override
public void handleMessage(Message msg) {
System.out.println(msg);
}
};
handler.sendEmptyMessage(1);
}
}
之所以会报异常的原因是由于多线程并发引起的,我们在子线程中创建的与主线程的looper会出现冲突,而在主线程运行到handler时,handler内部的looper还没有创建,却要从子线程传入一个looper对象,这就是报空指针异常。
针对以上问题,Android提供了HandlerThread来保证handler的正常运行,不会出现空指针异常,HandlerThread内部实现了同步机制,所以可以有效解决以上问题:
贴出源码:
package com.example.handler;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.widget.TextView;
public class ThreeActivity extends Activity {
private TextView tv;
private HandlerThread thread;
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
tv = new TextView(this);
tv.setText("handler Thread");
setContentView(tv);
thread = new HandlerThread("handler thread");
thread.start();
handler = new Handler(thread.getLooper()){
@Override
public void handleMessage(Message msg) {
System.out.println("current thread------>"+Thread.currentThread());
}
};
handler.sendEmptyMessage(1);
}
}