【Android基础知识】Handler、Message、Looper的关系
来源:互联网 发布:微店如何导入淘宝商品 编辑:程序博客网 时间:2024/05/21 15:07
为什么只能在UI线程进行更新UI
最根本的目的就是为了解决多线程并发问题。
假如在一个Activity中,有多个线程去更新UI,并且都没有加锁,那么会产生什么问题?
更新界面错乱
如果对更新UI的操作都进行加锁处理的话又会产生什么问题?
性能下降
为了处理上面的问题,android给我们提供了一套更新UI的handler机制,我们不用关心多线程问题,只需要去遵循这样的机制就可以了。
Handler的基本概念
提供了异步的线程处理。
有很多的操作不能放在onCreate里面,如下载操作等耗时比较长的操作。我们把这些操作放在一些单独的线程里面。
Android 更新UI
错误的更新方式:
在非UI线程中更新UI
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myText = (TextView)findViewById(R.id.text); new Thread(){ @Override public void run() { try {Thread.sleep(2000);myText.setText("hello android");} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();} } }.start(); }
正确的使用方式,使用handler
Handler.post()方法直接执行了线程的run()方法,其实这个线程和Activity在同一个线程中。并没有调用start方法,没有启动新线程。
public class MainActivity extends Activity {private TextView myText ;private Handler handler = new Handler(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myText = (TextView)findViewById(R.id.text); new Thread(){ @Override public void run() { //这里使用post方法后这个线程是运行在UI线程中的 handler.post(new Runnable() {@Overridepublic void run() {try {Thread.sleep(2000);myText.setText("hello android");} catch (InterruptedException e) {e.printStackTrace();}}}); } }.start(); }}
使用Callback对message进行拦截
需要引入包import android.os.Handler.Callback;
//handler Callback 方法,可以对message进行拦截,如果返回true则拦截private Handler handler2 = new Handler(new Callback() {//这个方法可以对接收到的message进行拦截@Overridepublic boolean handleMessage(Message msg) {Toast.makeText(getApplicationContext(), "1", Toast.LENGTH_SHORT).show();return false;}}){@Overridepublic void handleMessage(Message msg) {Toast.makeText(getApplicationContext(), "2", Toast.LENGTH_SHORT).show();}};
在UI线程创建Handler
Handler handler = new Handler(){@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubsuper.handleMessage(msg);}};
在子线程创建Handler
子线程中没有Looper对象,所以我们要自己去获取一个Loopoer对象,并且需要调用Looper.loop()方法,轮循处理消息。public class LooperThread extends Thread { @Override public void run() { // 将当前线程初始化为Looper线程
//当前线程里就产生了一个Looper对象,在创建Handler的时候会和其关联起来 Looper.prepare(); // ...其他处理,如实例化handler // 开始循环处理消息队列,这是一个死循环,有消息就处理,没有消息就阻塞 Looper.loop(); }}
Android 消息处理机制: Handler Message Looper
一 Handler封装了消息的发送,(主要包括消息发送给谁,一般发送给自己)
Looper
1.内部包含一个消息队列也就是MessageQueue,所有的Handler发送的消息都走向消息队列。
2.Looper.Loop()方法,就是一个死循环,不断从MessageQueue取消息,如果有消息就处理,没有消息就阻塞。
二 MessageQueue ,就是一个消息队列,可以添加消息,并处理消息。
三 Handler也很简单,内部会跟Looper进行关联,也就是说在Handler的内部可以找到Looper,找到了Looper也就找到了MessageQueue,在Handler发送消息时其实是向MessageQueue队列中发送消息。
总结:handler负责发送消息,Looper负责接收Handler发送的消息,并把消息发送给handler自己,MessageQueue就是一个存储消息的容器。
Handler发送消息
有了handler之后,我们就可以使用post(Runnable), postAtTime(Runnable, long), postDelayed(Runnable,long),sendEmptyMessage(int),sendMessage(Message), sendMessageAtTime(Message, long)和sendMessageDelayed(Message, long)这些方法向MQ上发送消息了。光看这些API你可能会觉得handler能发两种消息,一种是Runnable对象,一种是message对象,这是直观的理解,但其实post发出的Runnable对象最后都被封装成message对象了。
1 message.target为该handler对象,这确保了looper执行到该message时能找到处理它的handler,即loop()方法中的关键代码。
Handler处理消息
// 处理消息,该方法由looper调用 public void dispatchMessage(Message msg) { if (msg.callback != null) { // 如果message设置了callback,即runnable消息,处理callback! handleCallback(msg); } else { // 如果handler本身设置了callback,则执行callback if (mCallback != null) { /* 这种方法允许让activity等来实现Handler.Callback接口,避免了自己编写handler重写handleMessage方法。 if (mCallback.handleMessage(msg)) { return; } } // 如果message没有callback,则调用handler的钩子方法handleMessage handleMessage(msg); } } // 处理runnable消息 private final void handleCallback(Message message) { message.callback.run(); //直接调用run方法! } // 由子类实现的钩子方法 public void handleMessage(Message msg) {}
HandlerThread的使用
注意:Handler属于哪个线程不是看它在哪里创建的,而是看其关联的Looper对象在哪个线程实现子线程向主线程互相发送消息,子线程中可以处理耗时任务/* * 如何向子线程发送消息 */public class FourthActivity extends Activity implements OnClickListener{private Button sendButton;private Button stopButton;private HandlerThread thread;private Handler threadHandler;//创建一个和主线程相关的handlerprivate Handler handler = new Handler(){@Overridepublic void handleMessage(android.os.Message msg) {//给子线程发送一个消息Message message = new Message();message.what =1;//这里需要设置和removeMessage方法中的参数一致,不然停止不了threadHandler.sendMessageDelayed(message, 1000);Log.i("meng","main handler");}};@Overridepublic void onCreate(android.os.Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.four);sendButton = (Button)findViewById(R.id.send_message);stopButton = (Button)findViewById(R.id.stop_message);sendButton.setOnClickListener(this);stopButton.setOnClickListener(this); thread = new HandlerThread("handler thread"); thread.start(); //创建一个子线程的handler threadHandler = new Handler(thread.getLooper()){ @Override public void handleMessage(android.os.Message msg) { Message message = new Message(); message.what = 1; //每隔1秒给主线程发送一个消息 handler.sendMessageDelayed(message, 1000); Log.i("meng","thread handler"); } };}@Overridepublic void onClick(View v) {// TODO Auto-generated method stubswitch (v.getId()) {case R.id.send_message://调用handler.sendEmptyMessage(1);break;case R.id.stop_message:handler.removeMessages(1);break;default:break;}}}精彩博客链接: http://blog.csdn.net/lmj623565791/article/details/47079737/
- 【Android基础知识】Handler、Message、Looper的关系
- android Looper Message Handler中三者的关系
- Android 基础知识 Message MessageQueue Handler Looper 关系 图示
- android 中Message、Handler、Message Queue、Looper之间的关系
- android 中Message、Handler、Message Queue、Looper之间的关系
- Handler,Message,Looper的关系
- android Thread HandlerThread Looper Message MessageQueue Handler的关系
- android中MessageQueue,Message,Looper,handler的关系
- android Thread HandlerThread Looper Message MessageQueue Handler的关系
- android中MessageQueue,Message,Looper,handler的关系
- Android笔记--ThreadLocal,Looper,Handler,Message,MessageQueue的关系
- Android异步消息之Looper、Handler、Message、HandlerThread的关系
- Android知识点:Looper、Message、Handler之间的关系
- android Thread HandlerThread Looper Message MessageQueue Handler的关系
- Android消息处理机制---Looper、Handler、Message之间的关系
- Android中Looper Handler Message三者之间的关系
- android中message、messageQueue、Handler、looper的关系
- android Message、Handler、MessageQueue、Looper之间的关系。
- jdk配置方法
- java学习笔记
- RSA之php私钥签名与android、ios公钥加密
- php生成二维码
- **JAVASCRIPT** 浏览器对象
- 【Android基础知识】Handler、Message、Looper的关系
- 如何选择 compileSdkVersion, minSdkVersion 和 targetSdkVersion
- 学习Python指南
- Opengl在线学习资料
- PAT乙级练习题B1051. 复数乘法
- mysql的异步复制
- 超赞的OOM检测(除了mat以外)
- ATOM基础教程一ATOM配置(10)
- Java程序员应该知道的10个调试技巧