消息处理的五大组成部分:
- Message
- Handler
- Message Queue
- Looper
- ThreadLocal
1、Message数据模型,用于线程之间传递消息,
常用四个字段:
target:消息回调的作用域类,通常是一个handler,为了内部区分多个handler问题;
what:区分不同消息得标识符;
obj:是一个对象类型,可以携带自定义的类;
arg:int类型携带参数;
2、handler主要用于发送和接收消息
sendMessage();主要用于发送和处理消息;
handleMessage();发出的消息经过一系列出来后,最终会传递到handler的handlemessage方法中;
3、MessageQueue消息队列
主要存放所有handler发送过来的消息,这些消息存放在消息队列中,等待被处理,每一个线程只有一个messageQueue队列
4、Looper
每个线程通过Handler发送的消息都保存在messageQueue中,Looper通过调用loop()方法,就会进入到一个无限循坏中,然后每当发现MessageQueue中存在一条消息,就会将它取出,并传递到handler的handleMessage()方法中,每个贤臣中只会有一个Looper对象;
一、Handler常规使用:更新主线程UI
private MyHandler myHandler = new MyHandler(this);
private class MyHandler extends Handler {
private WeakReference<Activity> mWeakReference;
public MyHandler(Activity activity) {
super();
mWeakReference = new WeakReference<>(activity);
}
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
Activity activity = mWeakReference.get();
if (activity == null) return;
switch (msg.what) {
case 1:
/**
* 非静态内部类会隐式地持有外部类的引用(MainActivity中TextView),这回导致外部类对象无法被系统的GC回收;
* 解决:
* 1、静态内部类持有外部类引用
* 2、弱引用的方式来持有外部类引用
*/
System.out.println("----->" + msg);
textView.setText(msg.toString());
break;
}
}
}
...
private void sendThread() {
new Thread(new Runnable() {
@Override
public void run() {
Message message = Message.obtain();
message.what = 1;
message.obj = "线程发送消息----";
//长时间持有Handler引用,handleMessage
myHandler.sendMessage(message);
//mHandler.sendMessageDelayed(message, 10000);
}
}).start();
}
二、Handler跨线程通信
1、接受消息的线程:创建Looper,循环取出消息队列MessageQueue里面的消息,并分发到创建该消息得处理者Handler;
2、发送消息线程:创建Message消息,并使用接收线程中Handler发送消息;
public class MainActivity extends AppCompatActivity {
private TextView textView;
private Handler thread2Handler;
private Handler mainHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message msg) {
textView.setText(msg.toString());
return false;
}
});
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textview);
findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
thread1();
}
});
findViewById(R.id.btn2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();//准备
thread2Handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message msg) {
if (msg != null) {
System.out.println("线程2接收到消息:" + msg);
Message reply = Message.obtain();
reply.obj = msg.obj;
mainHandler.sendMessage(reply);
}
return false;
}
});
Looper.loop();//轮询
}
}).start();
}
private void thread1() {
new Thread(new Runnable() {
@Override
public void run() {
Message message = Message.obtain();
message.obj = "我是线程1";
if (thread2Handler != null) {
thread2Handler.sendMessage(message);
} else {
System.err.println("thread2Handler未准备完成");
}
}
}).start();
}
}
参考:
https://www.jianshu.com/p/ba46bad5af67
https://www.cnblogs.com/liushilin/p/8667917.html?foxhandler=RssReadRenderProcessHandler#commentform