一、概述
handler是更新UI的一套机制,消息处理机制,常用方法有post、postDelayed、sendMessage、sendMessageDelayed等,使用handler的根本目的是为了解决多线程并发问题,因为多线程更新UI都没有加锁机制,会导致更新界面错乱。
二、实际案例
1.handler的基本使用
MainActivity.java
package com.czhappy.handlerdemo.activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.czhappy.handlerdemo.R;
public class MainActivity extends AppCompatActivity {
private TextView textView;
private ImageView imageView;
private Handler handler1 = new Handler();
private Handler handler2 = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
textView.setText(""+msg.arg1+","+msg.arg2);
textView.setText(""+msg.obj.toString());
}
};
//添加callback根据返回值,是否拦截消息执行
private Handler handler3 = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
Toast.makeText(MainActivity.this, "1", Toast.LENGTH_SHORT).show();
//返回true拦截消息
return true;
}
}){
@Override
public void handleMessage(Message msg) {
Toast.makeText(MainActivity.this, "2", Toast.LENGTH_SHORT).show();
super.handleMessage(msg);
}
};
private int images[] = {R.drawable.image1, R.drawable.image2, R.drawable.image3};
private int index;
private MyRunnable myRunnable = new MyRunnable();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
imageView = (ImageView) findViewById(R.id.imageView);
//postDelayed方法
//handler1.postDelayed(myRunnable, 1000);
//sendMessage方法
new Thread(){
@Override
public void run() {
try {
Thread.sleep(2000);
Message message = handler2.obtainMessage();
message.arg1 = 88;
message.arg2 = 100;
Person pp = new Person("zhangsan", 23);
message.obj = pp;
//发送消息,两种方法均可
//handler2.sendMessage(message);
message.sendToTarget();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
class MyRunnable implements Runnable{
@Override
public void run() {
index++;
index = index%3;
imageView.setImageResource(images[index]);
handler1.postDelayed(myRunnable, 1000);
}
}
class Person{
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public void stopImageChange(View view){
handler1.removeCallbacks(myRunnable);
}
}
2.在子线程中使用handler
SecondActivity.java
package com.czhappy.handlerdemo.activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;
/**
* Description:
* User: chenzheng
* Date: 2017/1/7 0007
* Time: 11:50
*/
public class SecondActivity extends AppCompatActivity {
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
//此处不要执行耗时操作
Log.e("tag", "UI---------->"+Thread.currentThread());//主线程
}
};
private MyThread thread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
tv.setText("hello");
setContentView(tv);
thread = new MyThread();
thread.start();
try {
thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.handler.sendEmptyMessage(1);
handler.sendEmptyMessage(1);
}
class MyThread extends Thread{
private Handler handler;
@Override
public void run() {
Looper.prepare();
handler = new Handler(){
@Override
public void handleMessage(Message msg) {
Log.e("tag", ""+Thread.currentThread());//主线程下面的子线程
}
};
Looper.loop();
}
}
}
3.关于HandlerThread
ThirdActivity.java
package com.czhappy.handlerdemo.activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;
/**
* Description: HandlerThread
* User: chenzheng
* Date: 2017/1/7 0007
* Time: 14:11
*/
public class ThirdActivity extends AppCompatActivity{
private HandlerThread thread;
private Handler handler;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
tv.setText("hello");
setContentView(tv);
thread = new HandlerThread("handler looper");
handler = new Handler(thread.getLooper()){
@Override
public void handleMessage(Message msg) {
Log.e("tag", ""+thread.currentThread());
}
};
}
}
4.主线程与子线程之间相互通信
FourActivity.java
package com.czhappy.handlerdemo.activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import com.czhappy.handlerdemo.R;
/**
* Description:主线程与子线程之间相互通信
* User: chenzheng
* Date: 2017/1/7 0007
* Time: 14:26
*/
public class FourActivity extends AppCompatActivity {
//创建主线程的
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
Log.e("tag","main handler");
Message message = new Message();
//向子线程发送消息
threadHandler.sendMessageDelayed(message, 1000);
}
};
private Handler threadHandler;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_four);
HandlerThread thread = new HandlerThread("handlerThread");
thread.start();
//创建子线程的handler
threadHandler = new Handler(thread.getLooper()){
@Override
public void handleMessage(Message msg) {
Log.e("tag","thread handler");
Message message = new Message();
//向主线程发送消息
handler.sendMessageDelayed(message, 1000);
}
};
}
public void doSend(View view){
handler.sendEmptyMessage(1);
}
public void doStop(View view){
handler.removeMessages(1);
}
}
5.更新UI的四种方式
FiveActivity.java
package com.czhappy.handlerdemo.activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import com.czhappy.handlerdemo.R;
/**
* Description:更新UI的几种方式
* User: chenzheng
* Date: 2017/1/7 0007
* Time: 15:29
*/
public class FiveActivity extends AppCompatActivity {
private TextView textView1, textView2, textView3, textView4;
private Handler handler1 = new Handler();
private Handler handler2 = new Handler(){
@Override
public void handleMessage(Message msg) {
textView2.setText("OK");
}
};
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_five);
textView1 = (TextView) findViewById(R.id.textView1);
textView2 = (TextView) findViewById(R.id.textView2);
textView3 = (TextView) findViewById(R.id.textView3);
textView4 = (TextView) findViewById(R.id.textView4);
way1();
way2();
way3();
way4();
}
private void way1() {
new Thread(){
@Override
public void run() {
try {
Thread.sleep(2000);
handler1.post(new Runnable() {
@Override
public void run() {
textView1.setText("OK");
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}
private void way2(){
handler2.sendEmptyMessage(1);
}
private void way3(){
runOnUiThread(new Runnable() {
@Override
public void run() {
textView3.setText("OK");
}
});
}
private void way4(){
textView4.post(new Runnable() {
@Override
public void run() {
textView4.setText("OK");
}
});
}
}
三、总结
- handler封装了消息的发送
- Looper消息承装的载体,内部包含消息队列MessgaeQueue
- Looper.Looper方法是一个死循环,不断的从MessageQueue取消息,有消息就处理消息,没有消息就阻塞
- MessageQueue是一个消息队列,可以添加消息并处理消息
总结:handler负责消息的发送,Looper负责接收handler发送的消息,并直接把消息回传给handler自己,MessageQueue就是一个存储消息的容器