概念:
MessageQueue:消息队列,存放消息的地方,按照FIFO(先进先出)规则执行,每一个线程只可以拥有一个MessageQueue,在创建looper对象会创建一个MessageQueue对象
Message:消息对象,MessageQueue中存放的对象,一个MessageQueue中可以包含多个Message对象,可以通过Message.obtain()或Message.obtainMessage()获取Message对象,但是并不一定是直接创建一个新的实例,而是先从消息池中看有没有可用的Message实例,存在则直接取出返回这个实例,如果消息池中没有可用的Message实例,则才用给定的参数创建一个Message对象,调用removeMessage()将message对象从MessageQueue中删除,同时放入到消息池中
Looper:操作MessageQueue.一个Looper对应一个MessageQueue.通过调用Loop.myLooper()可以获得当前线程的Looper对象.Looper从MessageQueue中取出Message后,交给Handler的handleMessage()进行处理.处理完后,调用Message.recycle()将其放入消息池中
Handler:消息的处理者,handler负责将需要传递的信息封转成Message对象,然后调用sendMessage()方法将消息放入到MessageQueue中,当MessageQueue循环到该Message,
调用相应的Handler对象的HandleMessage()方法对其进行处理,Handler都可以共享同一个Looper和MessageQueue
handler类允许你发送消息和处理线程消息队列中的消息及runnable对象。handler实例都是与一个线程和该线程的消息队列一起使用,一旦创建了一个新的handler实例,系统就把该实例与一个线程和该线程的消息队列捆绑起来,这将可以发送消息和runnable对象给该消息队列,并在消息队列出口处处理它们。
handler类有两种主要用途:1。按照时间计划,在未来某时刻,对处理一个消息或执行某个runnable实例。2。把一个对另外线程对象的操作请求放入消息队列中,从而避免线程间冲突。
时间类消息通过如下方法使用: post(Runnable), postAtTime(Runnable, long), postDelayed(Runnable, long), sendEmptyMessage(int), sendMessage(Message), sendMessageAtTime(Message, long), and sendMessageDelayed(Message, long)
methods. post之类函数可以传输一个runnable对象给消息队列,并在到达消息队列后被调用。sendmessage之类函数可以传送一个包含数据的message对象,该message对象可以被Handler类的handleMessage(Message) 方法所处理。
post之类函数和sendmessage之类的函数都可以指定消息的执行时机,是立即执行、稍后一段时间执行,还是在某个确定时刻执行。这可以用来实现超时、消息或其他时间相关的操作。
当一个进程启动时,主线程独立执行一个消息队列,该队列管理着应用顶层的对象(如:activities、broadcast receivers等等)和所有创建的窗口。你可以创建自己的一个线程,并通过handler来与主线程进行通信。这可以通过在新的线程中调用主线程的handler的post和sendmessage操作来实现。
1、布局文件main.xml
- <ProgressBar
- android:id="@+id/myProBar"
- style="?android:attr/progressBarStyleHorizontal"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:visibility="gone"/>
-
- <Button
- android:id="@+id/btnStart"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/btnStart"/>
2、Activity文件中的代码如下
- / /声明控件变量
- ProgressBar proBar;
- Button btnStart;
- int i=0;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
-
-
- roBar=(ProgressBar)this.findViewById(R.id.myProBar);
- btnStart=(Button)this.findViewById(R.id.btnStart);
-
-
- btnStart.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View arg0) {
- proBar.setVisibility(View.VISIBLE);
- updateBarHandler.post(updateThread);
- }
-
-
- Handler updateBarHandler=new Handler(){
- @Override
- public void handlerMessage(Message msg) {
-
-
- proBar.setProgress(msg.arg1);
-
-
- updateBarHandler.post(updateThread);
- }
- };
-
- Runnable updateThread=new Runnable()
- {
-
- @Override
- public void run() {
- i+=10;
-
- Message msg=updateBarHandler.obtainMessage();
-
- msg.arg1=i;
- try{
-
- Thread.sleep(1000);
- }
- catch(InterruptedException e) {
- e.printStackTrace();
- }
-
- updateBarHandler.sendMessage(msg);
- if(i==100)
- {
-
- updateBarHandler.removeCallbacks(updateThread);
- }
- }
- };
- });
-
- }
3、运行结果
1.Handler与线程
实际上Handler与Activity处于同一线程当中
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- Handler handler=new Handler();
- handler.post(r);
-
- setContentView(R.layout.main);
-
- System.out.println("activity--->"+Thread.currentThread().getId());
- System.out.println("activity--->"+Thread.currentThread().getName());
-
- }
-
- Runnable r=new Runnable(){
-
- @Override
- public void run() {
- System.out.println("handler--->"+Thread.currentThread().getId());
- System.out.println("handlerName--->"+Thread.currentThread().getName());
-
- try {
- Thread.sleep(10000);
- } catch (InterruptedException e) {
-
- e.printStackTrace();
- }
- }
handersetCotentView()之前,所有要等待10秒,Activity中的内容才显示处理,并且输出的id和name相同,则说明Handler没有启动新线程,
2.在新线程当中处理消息方法,(需要使用Looper对象,改对象提供了循环的从队列中取消息的这种功能),并使用Bundle
- package wei.cao.handler;
-
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.HandlerThread;
- import android.os.Looper;
- import android.os.Message;
-
- public class Handler_03 extends Activity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
- System.out.println("Activity--->"+Thread.currentThread().getId());
-
- HandlerThread handlerThread=new HandlerThread("handler_thread");
-
- handlerThread.start();
-
- MyHandler myHandler=new MyHandler(handlerThread.getLooper());
-
- Message msg=myHandler.obtainMessage();
-
- Bundle b=new Bundle();
- b.putString("name", "wei_cao");
- b.putInt("age", 10);
- msg.obj="abc";
- msg.setData(b);
- msg.sendToTarget();
-
- }
- class MyHandler extends Handler
- {
- public MyHandler(Looper looper)
- {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- String str=(String)msg.obj;
-
- Bundle b=msg.getData();
- String name=b.getString("name");
- int age=b.getInt("age");
- System.out.println("name is "+name+"age is "+age+"str is "+str);
- System.out.println("Handler--->"+Thread.currentThread().getId());
- System.out.println("handleMessage");
- }
-
-
- }
- }