Android之Message、handler学习
学习来源:参考自http://www.eoeandroid.com/forum.php?mod=viewthread&tid=49595&highlight=handler
一、相关概念
1.MessageQueue:消息队列,一种数据结构,存放消息的地方。每一个线程最多只可以拥有一个MessageQueue。通常使用Looper对象对该线程的MessageQueue管理。创建一个线程的时候,并不会自动为其创建MessageQueue。主线程创建时,会自动创建一个默认的Looper对象,而Looper对象的建立将自动创建一个MessageQueue。其他非主线程,不会自动创建Looper,需要的时候通过prepar函数实现。
2.Message:消息对象,Message Queue中的存放的对象。一个Message Queue中包含多个Message。
Message实例对象的取得,通常使用Message类里的静态方法obtain(),该方法有多个重载版本可供选择;它的创建并不一定是直接创建一个新的实例,而是先看Message Pool(消息池)中是否有可用的Message实例,有则直接取出返回这个实例,否则使用给定的参数创建一个message对象。调用removeMessages()时,将message从message Queue中删除(如果带了int参数,只是将对应的message清空),同时放入到message pool中。除此,还可以通过handler对象的ObtainMessage()方法获取一个message实例。
3.Looper:是MessageQueue的管理者。每一个MessageQueue都不能脱离Looper而存在,Looper对象的创建是通过prepare函数来实现的。同时每一个Looper对象和一个线程关联。通过调用Looper.myLooper()可以获得当前线程的Looper对象,创建一个Looper对象时,会同时创建一个messagequeue对象。除了主线程有默认的Looper,其他线程默认是没有MessageQueue对象的,所以,不能接受Message。如需要接受,自己定义 一个Looper对象(通过prepare函数),这样该线程就有了自己的Looper对象和MessageQueue数据结构了。Looper从MessageQueue中取出Message然后,交由Handler的handleMessage进行处理。处理完成后,调用Message.recycle()将其放入Message Pool中。
4.Handler:消息的处理者,handler 负责将需要传递的信息封装成Message,通过调用handler 对象的obtainMessage()来实现;将消息传递给Looper,这是通过handler 对象的sendMessage()来实现的。继而由Looper将Message放入MessageQueue中。当Looper对象看到MessageQueue中含有Message,就将其广播出去。该handler 对象收到该消息后,调用相应的handler 对象的handleMessage()方法对其进行处理。
二、Handler的使用
1.处理消息
可以直接创建Handler实例,重写handlerMessage方法
Handler myHandler = new Handler(){ @Override public void handleMessage(Message msg){ super.handleMessage(msg); doWork(); } };
也可以继承Handler,重写handlerMessage方法
class MyHandler extends Handler{ public MyHandler(Looper looper){ super(looper); } @Override public void handleMessage(Message msg){ super.handleMessage(msg); //textView.append((String)msg.obj); //子线程不能操纵UI Log.d("msg", (String)msg.obj); } }
2.发送消息
handler本身不仅可以发送消息,还可以用post的方式添加一个实现Runnable接口的匿名对象到消息队列中,在目标收到消息后就可以回调的方式在自己的线程中执行run的方法体。
handler发送消息的常用方法:
post(Runnable)
postAtTime(Runnable,long)
postDelayed(Runnable long)
sendEmptyMessage(int what)
sendMessage(Message)
sendMessageAtTime(Message,long)
sendMessageDelayed(Message,long)
三、通信
1.主线程给自己发送message
public class MainActivity extends Activity { private TextView textView; private int i = 0; @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = (TextView) findViewById(R.id.text); } public void onTouch(View v){ Looper looper = Looper.getMainLooper(); //主线程的Looper //以主线程的Looper创建Handler,该handler发送的Message会传递给主线程的MessageQueue MyHandler handler = new MyHandler(looper); handler.removeMessages(0); Message msg = handler.obtainMessage(1, 1, 1, "主线程Test" + i++); handler.sendMessage(msg); } class MyHandler extends Handler{ public MyHandler(Looper looper){ super(looper); } @Override public void handleMessage(Message msg){ super.handleMessage(msg); textView.append((String)msg.obj); } } }
2.子线程给主线程发消息
public class MainActivity extends Activity { private TextView textView; private int i = 0; private MyHandler handler; @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = (TextView) findViewById(R.id.text); } public void onTouch(View v){ MyThread mRunnable = new MyThread(); Thread thread = new Thread(mRunnable); thread.start(); } class MyHandler extends Handler{ public MyHandler(Looper looper){ super(looper); } @Override public void handleMessage(Message msg){ super.handleMessage(msg); textView.append((String)msg.obj); } } class MyThread implements Runnable{ @Override public void run() { // TODO Auto-generated method stub Looper looper = Looper.getMainLooper(); //以主线程的Looper创建Handler,该handler发送的Message会传递给主线程的MessageQueue handler = new MyHandler(looper); Message message = handler.obtainMessage(1, "子线程——>主线程Test" + i++); handler.sendMessage(message); } }
3.主线程给其他线程发送消息
public class MainActivity extends Activity { private TextView textView; private int i = 0; private Handler handler; @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = (TextView) findViewById(R.id.text); MyThread mRunnable = new MyThread(); Thread thread = new Thread(mRunnable); thread.start(); } public void onTouch(View v){ Message message = handler.obtainMessage(1, "主线程——>子线程Test" + i++); handler.sendMessage(message); } class MyThread implements Runnable{ @Override public void run() { // TODO Auto-generated method stub Looper.prepare(); //创建该线程的Looper Looper looper = Looper.myLooper(); //以子线程的Looper创建Handler,该handler发送的Message会传递给子线程的MessageQueue handler = new ThreadHandler(looper); Looper.loop();//循环从messagequeue中取消息 } } class ThreadHandler extends Handler{ public ThreadHandler(Looper looper){ super(looper); } @Override public void handleMessage(Message msg){ super.handleMessage(msg); //textView.append((String)msg.obj); //子线程不能操纵UI Log.d("msg", (String)msg.obj); } } }
4.其他线程给自己发消息
public class MainActivity extends Activity { private TextView textView; private int i = 0; private Handler handler; @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = (TextView) findViewById(R.id.text); } public void onTouch(View v){ MyThread mRunnable = new MyThread(); Thread thread = new Thread(mRunnable); thread.start(); } class MyThread implements Runnable{ @Override public void run() { // TODO Auto-generated method stub Looper.prepare(); //创建该线程的Looper Looper looper = Looper.myLooper(); //以子线程的Looper创建Handler,该handler发送的Message会传递给子线程的MessageQueue handler = new ThreadHandler(looper); Message message = handler.obtainMessage(1, "子线程——>子线程Test" + i++); handler.sendMessage(message); //循环从messagequeue中取消息 Looper.loop(); } } class ThreadHandler extends Handler{ public ThreadHandler(Looper looper){ super(looper); } @Override public void handleMessage(Message msg){ super.handleMessage(msg); //textView.append((String)msg.obj); //子线程不能操纵UI Log.d("msg", (String)msg.obj); } } }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。