Android消息机制——Handler

  1 /**android的消息处理有三个核心类:Looper,Handler和Message。其实还有一个MessageQueue(消息队列),
  2  * 但是MessageQueue被封装到Looper里面了。
  3  *
  4  * Looper
  5  *
  6  * Looper  循环着。被设计用来使一个普通线程变成Looper线程。
  7  *         Looper.prepare()将当前线程初始化为Looper线程
  8  *         ....实例化Handler,处理消息
  9  *         Looper.loop()开始循环处理消息队列。调用后开始不断从Looper内部的消息队列中取出消息执行
 10  *
 11  * 注意:Looper.loop()之后的方法不会再执行到。一个Thread只能有一个Looper对象
 12  * Looper类还有一些方法:Looper.myLooper()得到当前线程looper对象
 13  *                      Looper.getThread()得到looper对象所属线程
 14  *                      Looper.quit()结束looper循环
 15  *
 16  *
 17  * Handler
 18  *
 19  * Handler扮演了往MessageQueue上添加消息和处理消息的角色(只处理由自己发出的消息)。
 20  * 即通知MessageQueue它要执行一个任务(sendMessage),并在循环到自己的时候执行该任务(handleMessage),整个过程是异步的。
 21  * Handler创建时会关联一个Looper,默认构造方法将关联当前线程的looper.
 22  *
 23  * 一个线程可以有多个Handler,但只能有一个Looper.
 24  *
 25  *拿到handler引用之后,我们就可以使用它的方法。比如:
 26  *      post(Runnable) //其实post发出的Runnable对象最后都被封装成Message对象了
 27  *      postAtTime(Runnable,long)
 28  *      postDelayed(Runnable,long)
 29  *      sendEmptyMessage(int)
 30  *      sendMessage(Message)
 31  *      sendMessageAtTime(Message,long)
 32  *      sendMessageDelayed(Message,long)
 33  *
 34  *
 35  *  Message类
 36  *  Message被存放在MessageQueue中,一个MessageQueue中可以包含多个Message对象。
 37  *  Message中包含两个额外的int字段和一个Object字段。
 38  *      Message.arg1 /Message.arg2  存放整形数据
 39  *      Message.obj   存放发送给接收器的Object类型的任意对象
 40  *      Message.what  用来指定用户自定义的消息代码
 41  *
 42  *  使用Message.obtain()或Handler.obtainMessage()函数来获取Message对象
 43  *
 44  *
 45  *  异步消息处理的流程:
 46  *  首先需要在主线程当中创建一个Handler对象,并重写handlerMessage()方法。
 47  *  然后当子线程中需要进行UI操作时,就创建一个Message对象,并通过Handler将这条消息发送出去。
 48  *  之后这条消息会被添加到MessageQueue的队列中等待被处理,而Looper则会一直尝试从MessageQueue中取出待处理的消息,
 49  *  最后分发回Handler的handlerMessage()方法中。
 50  *  由于Handler是在主线程中创建的,所以此时handlerMessage()方法中的代码也会在主线程中运行,所以可以安心在这里更新UI
 51  *
 52  *
 53  *
 54  */
 55
 56
 57 public class MainActivity extends AppCompatActivity {
 58
 59     ViewPager viewPager;
 60     Button btn_start;
 61     List<Fragment> mList = new ArrayList<>();
 62
 63     Handler mainHandler, childHandler;
 64
 65     @Override
 66     protected void onCreate(Bundle savedInstanceState) {
 67         super.onCreate(savedInstanceState);
 68         setContentView(R.layout.activity_main);
 69         initView();
 70
 71
 72     }
 73
 74     private void initView() {
 75         viewPager = (ViewPager) findViewById(R.id.viewpager);
 76         btn_start = (Button) findViewById(R.id.btn_start);
 77
 78         initData();
 79
 80         FragmentManager fm = getSupportFragmentManager();
 81         //如果使用PagerAdapter,需要重写instantiateItem()加载视图,onDestroy()销毁视图
 82         //FragmentPagerAdapter,每一个生成的Fargment都保存在内存中,也就是FragmentManaer中,就算刷新Adapter,还是使用的上次缓存的Fragment
 83         //FragmentStatePagerAdapter的instantiateItem()加载视图的时候会每次重新创建Fragment。
 84         viewPager.setAdapter(new FragmentStatePagerAdapter(fm) {
 85             @Override
 86             public Fragment getItem(int position) {
 87                 return mList.get(position%6);
 88             }
 89
 90             @Override
 91             public int getCount() {
 92                 return Integer.MAX_VALUE;
 93             }
 94         });
 95         viewPager.setCurrentItem(0);
 96
 97         //主线程接收子线程消息并处理
 98         mainHandler = new Handler() {
 99             @Override
100             public void handleMessage(Message msg) {
101                 super.handleMessage(msg);
102                 Log.e("TAG", "最终处理" + (int) msg.obj);
103                 viewPager.setCurrentItem((int) msg.obj);
104
105                 if (childHandler != null) {
106                     Message toChild = childHandler.obtainMessage();
107                     toChild.obj = msg.obj;
108                     childHandler.sendMessageDelayed(toChild, 500);
109                 }
110             }
111         };
112
113         new myThread().start();
114
115         //点击开始轮播图片
116         btn_start.setOnClickListener(new View.OnClickListener() {
117             @Override
118             public void onClick(View v) {
119                 if (childHandler != null) {
120                     Message firstMsg = childHandler.obtainMessage();
121                     firstMsg.obj = viewPager.getCurrentItem();
122                     childHandler.sendMessageDelayed(firstMsg, 500);
123                 }
124             }
125         });
126
127     }
128
129     class myThread extends Thread {
130
131         @Override
132         public void run() {
133             Looper.prepare();//初始化消息队列,必须在创建Handler之前
134             Log.e("TAG", "************");
135
136             childHandler = new Handler() {
137                 @Override
138                 public void handleMessage(Message msg) {
139                     Message toMain = mainHandler.obtainMessage();
140                     toMain.obj = (int)msg.obj + 1;
141                     Log.e("TAG", "toMain obj " + (int) (toMain.obj));
142                     mainHandler.sendMessageDelayed(toMain, 500);
143                 }
144             };
145
146             //启动子线程消息队列
147             Looper.loop();
148
149         }
150     }
151
152
153
154     @Override
155     protected void onDestroy() {
156         Log.e("TAG","@@@@@@@@@@@@@@@@@onDestroy");
157         childHandler.getLooper().quit();
158         super.onDestroy();
159     }
160
161     private void initData() {
162         mList.add(new OneFragment());
163         mList.add(new TwoFragment());
164         mList.add(new ThreeFragment());
165         mList.add(new FourFragment());
166         mList.add(new FiveFragment());
167         mList.add(new SixFragment());
168     }
169 }

MainActivity.java

 1 public class OneFragment extends Fragment {
 2     TextView tv;
 3
 4     @Nullable
 5     @Override
 6     public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
 7         return View.inflate(getContext(),android.R.layout.simple_list_item_1,null);
 8     }
 9
10
11     @Override
12     public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
13         super.onViewCreated(view, savedInstanceState);
14         tv = (TextView) view.findViewById(android.R.id.text1);
15         tv.setBackgroundResource(R.mipmap.img01);
16     }
17 }

OneFragment.java

Handler的工作机制简单来说是这样的

1、Handler发送消息仅仅是调用MessageQueue的enqueueMessage向插入一条信息到MessageQueue

2、Looper不断轮询调用MeaasgaQueue的next方法

3、如果发现message就调用handler的dispatchMessage,ldispatchMessage被成功调用,接着调用handlerMessage()

简图

参考:

http://www.jianshu.com/p/9e4d1fab0f36

http://blog.csdn.net/thanklife/article/details/16993085

时间: 2024-08-07 08:37:52

Android消息机制——Handler的相关文章

Android消息机制Handler的实现原理解析

Android的主线程为什么可以一直存在? 线程是一个动态执行的过程,从产生到死亡包括五个状态:新建.就绪.运行.死亡和堵塞.只要线程没有执行完毕或者没有被其它线程杀死,线程就不会进入死亡状态.Android中的主线程一直存在是因为主线程中一直在监听消息,从而使线程无法被执行完毕. 线程的五种状态: 新建new Thread 当创建Thread类的一个实例对象时,此线程进入新建状态未被启动. 就绪runnable 线程已经被启动,正在等待被分配给CPU时间片,也就是说此时线程正在就绪队列中排队等

Android消息机制Handler、Looper、MessageQueue源码分析

1. Handler Looper MessageQueue的关系 2.源码分析 下图表示了Handler.Looper.MessageQueue.Message这四个类之间的关系. Handler必须与一个Looper关联,相关Looper决定了该Handler会向哪个MessageQueue发送Message 每一个Looper中都包含一个MessageQueue Handler中的mQueue引用的就是与之关联的Looper的MessageQueue 不管Handler在哪个线程发送Mes

Android消息机制Handler解析(源码+Demo)

Handler是开发人员在面试过程中最常见的问题之一了,这篇文章将较为全面地对Handler进行解读,包括源码层,以及使用方法. 如果看完文章有疑问,欢迎在评论中一起探讨 基本内容包括: 看完文章之后,可以用这个图片进行复习. 一.什么是Handler Handler是Android提供用来更新UI的一套机制,也是一套消息处理机制,可以用它来发送消息,也可以用它来接收消息. 二.为什么使用Handler Android在设计之时,就封装了一套消息的创建.传递.处理机制,若不遵循这样的处理机制,就

Android的消息机制Handler详解

Android的消息机制详解 Android的消息机制主要指 Handler 的运行机制,Handler的运行需要底层的MessageQueue 和 Looper 的支撑. MessageQueue:消息队列,它的内部存储了一组消息,以队列的形式对外提供插入和删除的工作,其内部存储结构采用单链表的数据结构来存储消息列表. Looper:可理解为消息循环. 由于MessageQueue只是一个消息存储单元,不能去处理消息,而Looper会以无限循环的形式去查找是否有新的消息,如果有的话就处理,否则

Android消息机制:Looper,MessageQueue,Message与handler

Android消息机制好多人都讲过,但是自己去翻源码的时候才能明白. 今天试着讲一下,因为目标是讲清楚整体逻辑,所以不追究细节. Message是消息机制的核心,所以从Message讲起. 1.Message是什么? 看一个从消息池中取出一个msg的方法: public static Message obtain(Handler h, int what, int arg1, int arg2, Object obj) { Message m = obtain(); m.target = h; m

Android消息机制探索(Handler,Looper,Message,MessageQueue)

概览 Android消息机制是Android操作系统中比较重要的一块.具体使用方法在这里不再阐述,可以参考Android的官方开发文档. 消息机制的主要用途有两方面: 1.线程之间的通信.比如在子线程中想更新UI,就通过发送更新消息到UI线程中来实现. 2.任务延迟执行.比如30秒后执行刷新任务等. 消息机制运行的大概示意图如下: 一个线程中只能有一个Looper对象,一个Looper对象中持有一个消息队列,一个消息队列中维护多个消息对象,用一个Looper可以创建多个Handler对象,Han

Android 消息机制 (Handler、Message、Looper)

综合:http://blog.csdn.net/dadoneo/article/details/7667726 与 http://android.tgbus.com/Android/androidnews/201204/421642.shtml 一. 消息机制常用类的介绍和使用 在Android程序运行中,线程之间或者线程内部进行信息交互时经常会使用到消息,如果我们熟悉这些基础的东西及其内部的原理,将会使我们的Android开发变的容易.可以更好地架构系统.在学习Android消息机制之前,我们

【转】Android 消息机制

Android 消息机制 本文首先从整体架构分析了Android整个线程间消息传递机制,然后从源码角度介绍了各个组件的作用和完成的任务.文中并未对基础概念进行介绍,关于threadLacal和垃圾回收等等机制请自行研究. 基础架构 首先,我们需要从整体架构上了解一下Android线程通信都做了哪些工作.我们都知道,进程是操作系统分配资源的最小单位,一个进程中可以启动多个线程来执行任务,这些线程可以共享进程的资源但不分配资源,这里讲的资源主要是只内存资源.Android的线程间消息传递机制其实和我

Android消息机制字典型探

Android消息机制字典型探究(一) Android消息机制字典型探究(二) 带着这篇去通关所有Handler的提问(三)