handler是什么?
handler是android给我们提供用来更新UI的一套机制,也是一套消息处理机制,我们可以发送消息,也可以通过它处理消息。
android中更新ui四种方式:
1、runonui
只能在Activity中使用
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
updateUI();
}
}).start();
}
private void updateUI() {
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText("run on UI thread");
}
});
}
2、view.post(runable)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
viewUI();
}
}).start();
}
private void viewUI() {
textView.post(new Runnable() {
@Override
public void run() {
textView.setText("view update UI");
}
});
}
3、handler.post()
private Handler mhandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
new Thread(new Runnable() {
@Override
public void run() {
mhandler.post(new Runnable() {
@Override
public void run() {
textView.setText("update thread");
}
});
}
}).start();
}
4、handler.sendmessage
private Handler mhandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
textView.setText(msg.arg1 + msg.arg2 + msg.obj.toString());
}
};
private TextView textView;
class Person {
private String name;
public Person(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
Message msg = new Message();
msg.arg1 = 1;
msg.arg2 = 2;
msg.obj = new Person("Gomez");
mhandler.sendMessage(msg);
//第二种发送消息方法
// msg = mhandler.obtainMessage();
// msg.sendToTarget();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
子线程创建Handler
private Handler mhandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
System.out.println("UIThread:" + Thread.currentThread());
}
};
private TextView textView;
private MyThread myThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
myThread = new MyThread();
myThread.start();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
myThread.handler.sendEmptyMessage(1);
mhandler.sendEmptyMessage(1);
}
class MyThread extends Thread {
Handler handler;
@Override
public void run() {
super.run();
//初始化looper
Looper.prepare();
handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
System.out.println("currentThread:" + Thread.currentThread());
}
};
//循环读取消息
Looper.loop();
}
}
}
运行效果:
HandlerThread
- HandlerThread本质上是一个线程类,它继承了Thread;
- HandlerThread有自己的内部Looper对象,可以进行looper循环;
- 通过获取HandlerThread的looper对象传递给Handler对象,可以在handleMessage方法中执行异步任务。
- 创建HandlerThread后必须先调用HandlerThread.start()方法,Thread会先调用run方法,创建Looper对象。
通过HandlerThread可以避免自定义线程中很多空指针问题,如上例如果不在主线程中加入延时,那个我们拿到的子线程的handler是为空的。
private HandlerThread handlerThread;
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handlerThread = new HandlerThread("handler thread");
handlerThread.start();
handler = new Handler(handlerThread.getLooper()) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
System.out.println("current thread" + Thread.currentThread());
}
};
handler.sendEmptyMessage(1);
}
在HandlerThread拿到的Looper都是安全的,在内部已经处理多线程同步;
这样所有handleMessage都是在子线程中执行,用HandlerThread模拟一些异步任务,主线程给子线发送消息,子线程执行一些耗时操作,比如一些下载图片,访问服务器都可以这样去执行。