博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
结合源代码详解android消息模型
阅读量:5222 次
发布时间:2019-06-14

本文共 7257 字,大约阅读时间需要 24 分钟。

Handler是整个消息系统的核心,是Handler向MessageQueue发送的Message,最后Looper也是把消息通知给Handler,所以就从Handler讲起。

一、Handler

Handler的构造函数有很多,但本质差不多:

public Handler() {          this(null, false);      }

  

public Handler(Callback callback, boolean async) {          //自动绑定当前线程的looper          mLooper = Looper.myLooper();          if (mLooper == null) {              throw new RuntimeException(                  "Can't create handler inside thread that has not called Looper.prepare()");//从这可以看出,创建Handler必须有Looper          }          mQueue = mLooper.mQueue;  //Looper的MessageQueue          mCallback = callback;     //一个回掉接口          mAsynchronous = async;        }

这个是创建给定Looper的Handler  :

public Handler(Looper looper, Callback callback, boolean async) {           mLooper = looper;         mQueue = looper.mQueue;         mCallback = callback;         mAsynchronous = async;     }

二、Looper的源代码:

public static Looper myLooper() {         return sThreadLocal.get();     }

  在一个子线程中创建Looper的一般步骤:(这是我自己写的,不是源代码)

class MyThread extends Thread{          public Handler handler;          public Looper looper;          public void run() {              Looper.prepare();//创建一个looper              looper = Looper.myLooper();              handler = new Handler(){                 @Override              public void handleMessage(Message msg) {                    System.out.println("currentThread->"+Thread.currentThread());                 }             };             Looper.loop();//让消息循环起来          }      }

  下面就看看Looper.prepare,Looper.loop方法:

public static void prepare() {          prepare(true);      }        private static void prepare(boolean quitAllowed) {          if (sThreadLocal.get() != null) {//sThreadLocal使得线程能够保持各自独立的一个对象。              throw new RuntimeException("Only one Looper may be created per thread");          }          sThreadLocal.set(new Looper(quitAllowed));      }

  Looper.prepare():

public static void loop() {          final Looper me = myLooper();          if (me == null) {    //如果Looper为空              throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");          }          final MessageQueue queue = me.mQueue;            。。。。          for (;;) {              Message msg = queue.next(); // 循环下一个              if (msg == null) {                  // No message indicates that the message queue is quitting.                  return;              }               。。。。                msg.target.dispatchMessage(msg);  //分发消息,msg.target就是Handler                if (logging != null) {                  logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);              }              。。。。                msg.recycle();  //回收msg到msgPool          }      }

  从这些代码可以看出Looper不断检查MessagePool是否有《==Message,有的话就通过Handler的dispatchMessage(msg)发送出去,利用Handler与外界交互。

3.Message的源代码:

public static Message obtain() {   //得到Message对象         synchronized (sPoolSync) {             if (sPool != null) {                 Message m = sPool;                 sPool = m.next;                 m.next = null;                 sPoolSize--;                 return m;             }         }         return new Message();  //没有就新建     }

  handler.obtainMessage()方法:

public final Message obtainMessage()     {         return Message.obtain(this);  //通过Message的obtain方法     }

  

public static Message obtain(Handler h) {  //就是这个方法        Message m = obtain();  //最终调用的还是obtain方法        m.target = h;      //target是handler          return m;    }

  看了上边的源代码,相信你一定对Handler,message,Looper有了一定了解,对编程中常遇到的方法,知道是怎么用的啦。其实学android一定要常看源码,源码很有用。

4.下边就是上代码,实例分析:

package com.example.handler_01;    import android.Manifest.permission;  import android.app.Activity;  import android.os.Bundle;  import android.os.Handler;  import android.os.Handler.Callback;  import android.os.Message;  import android.view.Menu;  import android.view.MenuItem;  import android.view.View;  import android.view.View.OnClickListener;  import android.widget.Button;  import android.widget.ImageView;  import android.widget.TextView;  import android.widget.Toast;    public class MainActivity extends Activity implements OnClickListener{        private TextView textView;      private Button button;                  private Handler handler = new Handler(new Callback() {//拦截消息                    public boolean handleMessage(Message msg) {  //截获handler的发送的消息                        Toast.makeText(getApplicationContext(), ""+1, 1).show();              //return false;              return false;//若返回true,则证明截获,下面的handleMessage就不会执行!          }      }){          public void handleMessage(Message msg) {              Toast.makeText(getApplicationContext(), ""+2, 1).show();              Person person = (Person)msg.obj;              System.out.println(person.toString());          }      };            private MyRunnable myRunnable=new MyRunnable();            private ImageView imageView;            private int images[]={R.drawable.a1,R.drawable.a2,R.drawable.a3};      private int index;            class MyRunnable implements Runnable{  //不断的更新图片,3张轮换            @Override          public void run() {            index++;            index=index%3;  //不断循环            imageView.setImageResource(images[index]);            handler.postDelayed(myRunnable, 1000);  //每隔一段时间执行myRunnable            System.out.println("MyRunnable中的线程:"+Thread.currentThread());//运行在当前主线程!          }                }      @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.activity_main);          textView = (TextView) findViewById(R.id.textview);          imageView = (ImageView) findViewById(R.id.imageView1);          button = (Button) findViewById(R.id.button1);          button.setOnClickListener(this);          new Thread(){              @Override              public void run() {                  try {                      Thread.sleep(2000);                      /*Message message = new Message();                    message.arg1=88;*/                     Message message = handler.obtainMessage();                                           Person person = new Person();                     person.age=20;                     person.name="chaochao";                     message.obj=person;                     handler.sendMessage(message);//在子线程中向主线程发消息。                  } catch (InterruptedException e) {                      // TODO Auto-generated catch block                      e.printStackTrace();                  }                                }          }.start();          handler.postDelayed(myRunnable, 1000);      }      @Override      public void onClick(View v) {          switch (v.getId()) {          case R.id.button1:              handler.removeCallbacks(myRunnable);              //handler.sendEmptyMessage(1);              break;            default:              break;          }                }        class Person{          public int age;          public String name;                    public String toString() {            return "name="+name+" age="+age;          }      }  }

  布局很简单,就不上代码啦。

运行结果:

图片自己可以随便能一个。。。。

在后边再详细解析Handler的用法。。

转发请注明出处:http://www.cnblogs.com/jycboy/p/handlerjx.html

转载于:https://www.cnblogs.com/jycboy/p/handlerjx.html

你可能感兴趣的文章
网络知识之ipset
查看>>
Credit Memo和Debit Memo在AR以及AP中的概念比较
查看>>
在Azure上部署Sqlserver网络访问不了的问题
查看>>
hdu 1561 The more, The Better(树形dp入门)
查看>>
最小度限制生成树模板
查看>>
树状数组总结
查看>>
3.shell编程-文件查找之find命令
查看>>
SQL语句使用时间和日期的函数
查看>>
SourceTree windows免注册免登陆使用方法
查看>>
Android Studio 快捷键和常用技巧汇总
查看>>
POJ 1195 Mobile phones(二维树状数组)
查看>>
团队报告
查看>>
GridView 72般绝技 (http://blog.csdn.net/21aspnet/)
查看>>
win7创建共享给windows和linux机器
查看>>
Window.open()方法参数详解
查看>>
Hadoop1 集群安装实验
查看>>
java RE Validation常用
查看>>
GNU make使用(一)
查看>>
How to change MAC address in windows 7
查看>>
log4net的各种Appender配置示例
查看>>