❤❤❤:
简单的分析一下
因为子线程不能修改主线程的UI(非特殊情况),因此子线程需要通过Handler通知主线程修改UI,进行线程间通信。
首先讲,Handler有四个关键的对象就是 Message,MessageQueue,Lopper,Handler
下面是一段基本用法
public class MainActivity extends AppCompatActivity {
private TextView textView;
private String TAG = "MainActivity";
private int i = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
}
public void onClick(View v){
++i;
//创建新的线程
new Thread(){
@Override
public void run() {
super.run();
doSendMsg();
}
}.start();
}
/**
* 在子线程中做耗时操作,完成之后,通知Handler更新UI
*/
private void doSendMsg(){
try {
Thread.sleep(1000);//模拟耗时操作
} catch (InterruptedException e) {
e.printStackTrace();
}
Message message = Message.obtain();
message.arg1 = i;
message.what = 1;
mHandler.sendMessage(message);
}
Handler mHandler = new Handler(){
/**
* handleMessage接收消息后进行相应的处理
* @param msg
*/
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg.what==1){
textView.setText(msg.arg1+"");
}
}
};
}
MessageQueue:
一个Message就是线程需要处理的一件事情,MessageQueue就是一个处理Message的池,在MessageQueue里面有removeIdleHandler()方法,移除空闲的线程
enqueueMessage() 是将Message放入消息队列当中
next() 方法当中有一个for循环,不断地从消息队列中阻塞式的取出一个Message
Lopper:
Lopper是用来使线程当中的消息循环起来,当创建新线程的时候是没有MessageQueue的,首先要调用Lopper的prepare,然后调用loop。这两个方法都是在线程的run方法里面调用,一个线程最多有一个Lopper
ThreadLocal保存了对当前线程的引用,set方法向ThreadLocal里面传一个Looper,get方法从TreadLocal中取出一个Looper
prepare方法当中如果 threadlocal的get()方法不!=null就抛出异常 如果等于空就会执行set方法绑定Lopper
Lopper的构造方法当中实例化了MessageQueue,进行了关联
执行完prepare方法之后就会执行 my'Lopper方法,会告知我们只能有一个Lopper
loop()方法中首先获得当前的线程所绑定的Looper,如果没有绑定的Looper就会报一个异常,如果绑定执行下面的代码,有一个死循环,不断调用MessageQueue的next()方法从队列中取出message,然后让Handel去处理该Message。
Handler:
本身有4个构造方法
1. publicHandler()
2. publicHandler(Callbackcallback)
3. publicHandler(Looperlooper)
4. publicHandler(Looperlooper, Callbackcallback)
传递的Callback是一个内部接口,重写了handleMessage()方法
sendMessage可以向消息队列中添加消息,sendMessage调用了sendMessageDelayed,sendMessageDelayed又调用了sendMessageAtTime
sendEmptyMessage也是如此
postMessage依赖于sendMessage,区别在于post携带runnable
sendMessageAtTime方法当中调用了enqueueMessage将消息放入消息队列