结合源代码详解android消息模型。
来源:互联网 发布:硅藻泥脚垫 知乎 编辑:程序博客网 时间:2024/06/05 03:47
Handler是整个消息系统的核心,是Handler向MessageQueue发送的Message,最后Looper也是把消息通知给1.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; }2.在看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.下边就是上代码,实例分析:
<pre name="code" class="java">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张轮换@Overridepublic void run() { index++; index=index%3; //不断循环 imageView.setImageResource(images[index]); handler.postDelayed(myRunnable, 1000); //每隔一段时间执行myRunnable System.out.println("MyRunnable中的线程:"+Thread.currentThread());//运行在当前主线程!}}@Overrideprotected 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(){@Overridepublic 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 blocke.printStackTrace();}}}.start();handler.postDelayed(myRunnable, 1000);}@Overridepublic 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;}}}
布局很简单,就不上代码啦。
</pre><p></p><pre>
运行结果:
这次代码先写到这,饿啦去吃饭,在后边再详细解析Handler的用法。。
转载请注明出处:http://blog.csdn.net/jycboy/article/details/46445677
0 0
- 结合源代码详解android消息模型。
- AudioManager详解(结合源代码)
- AudioManager详解(结合源代码)
- AudioManager详解(结合源代码)
- Android消息队列模型
- Android消息队列模型
- Android 消息队列模型
- android中的消息模型
- js原型详解(结合内存模型)
- App布局模型Android源代码
- 结合源码分析android的消息机制
- Android 的消息队列模型
- Android 的消息队列模型
- Android 的消息队列模型
- Android 的消息队列模型
- Android 的消息队列模型
- Android 的消息队列模型
- Android 的消息队列模型
- 插入排序 InsertSort
- 2015-6-10 XML解析之Pull解析方式
- 备忘录:记录网上的一些资源的备忘录
- IOCP配合AcceptEx的例子
- 【Java】Java Socket 通信示例
- 结合源代码详解android消息模型。
- 黑马程序员java学习笔记——网络编程
- OpenGL超级宝典(第五版)环境配置
- Uva - 1589 - Xiangqi
- 每日一得-servlet线程安全问题
- Xcode环境变量 build Settings 设置
- 项目报红叉,但是项目中却没有文件报错
- 读书笔记:机器学习实战(2)——章3的决策树代码和个人理解与注释
- js匹配表单name的值获取value