/**android的消息处理有三个核心类:Looper,Handler和Message。其实还有一个MessageQueue(消息队列),
* 但是MessageQueue被封装到Looper里面了。
*
* Looper
*
* Looper 循环着。被设计用来使一个普通线程变成Looper线程。
* Looper.prepare()将当前线程初始化为Looper线程
* ....实例化Handler,处理消息
* Looper.loop()开始循环处理消息队列。调用后开始不断从Looper内部的消息队列中取出消息执行
*
* 注意:Looper.loop()之后的方法不会再执行到。一个Thread只能有一个Looper对象
* Looper类还有一些方法:Looper.myLooper()得到当前线程looper对象
* Looper.getThread()得到looper对象所属线程
* Looper.quit()结束looper循环
*
*
* Handler
*
* Handler扮演了往MessageQueue上添加消息和处理消息的角色(只处理由自己发出的消息)。
* 即通知MessageQueue它要执行一个任务(sendMessage),并在循环到自己的时候执行该任务(handleMessage),整个过程是异步的。
* Handler创建时会关联一个Looper,默认构造方法将关联当前线程的looper.
*
* 一个线程可以有多个Handler,但只能有一个Looper.
*
*拿到handler引用之后,我们就可以使用它的方法。比如:
* post(Runnable) //其实post发出的Runnable对象最后都被封装成Message对象了
* postAtTime(Runnable,long)
* postDelayed(Runnable,long)
* sendEmptyMessage(int)
* sendMessage(Message)
* sendMessageAtTime(Message,long)
* sendMessageDelayed(Message,long)
*
*
* Message类
* Message被存放在MessageQueue中,一个MessageQueue中可以包含多个Message对象。
* Message中包含两个额外的int字段和一个Object字段。
* Message.arg1 /Message.arg2 存放整形数据
* Message.obj 存放发送给接收器的Object类型的任意对象
* Message.what 用来指定用户自定义的消息代码
*
* 使用Message.obtain()或Handler.obtainMessage()函数来获取Message对象
*
*
* 异步消息处理的流程:
* 首先需要在主线程当中创建一个Handler对象,并重写handlerMessage()方法。
* 然后当子线程中需要进行UI操作时,就创建一个Message对象,并通过Handler将这条消息发送出去。
* 之后这条消息会被添加到MessageQueue的队列中等待被处理,而Looper则会一直尝试从MessageQueue中取出待处理的消息,
* 最后分发回Handler的handlerMessage()方法中。
* 由于Handler是在主线程中创建的,所以此时handlerMessage()方法中的代码也会在主线程中运行,所以可以安心在这里更新UI
*
*
*
*/ public class MainActivity extends AppCompatActivity { ViewPager viewPager;
Button btn_start;
List<Fragment> mList = new ArrayList<>(); Handler mainHandler, childHandler; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView(); } private void initView() {
viewPager = (ViewPager) findViewById(R.id.viewpager);
btn_start = (Button) findViewById(R.id.btn_start); initData(); FragmentManager fm = getSupportFragmentManager();
//如果使用PagerAdapter,需要重写instantiateItem()加载视图,onDestroy()销毁视图
//FragmentPagerAdapter,每一个生成的Fargment都保存在内存中,也就是FragmentManaer中,就算刷新Adapter,还是使用的上次缓存的Fragment
//FragmentStatePagerAdapter的instantiateItem()加载视图的时候会每次重新创建Fragment。
viewPager.setAdapter(new FragmentStatePagerAdapter(fm) {
@Override
public Fragment getItem(int position) {
return mList.get(position%6);
} @Override
public int getCount() {
return Integer.MAX_VALUE;
}
});
viewPager.setCurrentItem(0); //主线程接收子线程消息并处理
mainHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.e("TAG", "最终处理" + (int) msg.obj);
viewPager.setCurrentItem((int) msg.obj); if (childHandler != null) {
Message toChild = childHandler.obtainMessage();
toChild.obj = msg.obj;
childHandler.sendMessageDelayed(toChild, 500);
}
}
}; new myThread().start(); //点击开始轮播图片
btn_start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (childHandler != null) {
Message firstMsg = childHandler.obtainMessage();
firstMsg.obj = viewPager.getCurrentItem();
childHandler.sendMessageDelayed(firstMsg, 500);
}
}
}); } class myThread extends Thread { @Override
public void run() {
Looper.prepare();//初始化消息队列,必须在创建Handler之前
Log.e("TAG", "************"); childHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
Message toMain = mainHandler.obtainMessage();
toMain.obj = (int)msg.obj + 1;
Log.e("TAG", "toMain obj " + (int) (toMain.obj));
mainHandler.sendMessageDelayed(toMain, 500);
}
}; //启动子线程消息队列
Looper.loop(); }
} @Override
protected void onDestroy() {
Log.e("TAG","@@@@@@@@@@@@@@@@@onDestroy");
childHandler.getLooper().quit();
super.onDestroy();
} private void initData() {
mList.add(new OneFragment());
mList.add(new TwoFragment());
mList.add(new ThreeFragment());
mList.add(new FourFragment());
mList.add(new FiveFragment());
mList.add(new SixFragment());
}
}

MainActivity.java

 public class OneFragment extends Fragment {
TextView tv; @Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return View.inflate(getContext(),android.R.layout.simple_list_item_1,null);
} @Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
tv = (TextView) view.findViewById(android.R.id.text1);
tv.setBackgroundResource(R.mipmap.img01);
}
}

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

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

  1. ThreadLocal ——android消息机制handler在非主线程创建not called Looper.prepare() 错误的原因

    引用自:https://www.jianshu.com/p/a8fa72e708d3 引出: 使用Handler的时候,其必须要跟一个Looper绑定.在UI线程可直接初始化Handler来使用.但是 ...

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

    Android消息机制好多人都讲过,但是自己去翻源码的时候才能明白. 今天试着讲一下,因为目标是讲清楚整体逻辑,所以不追究细节. Message是消息机制的核心,所以从Message讲起. 1.Mes ...

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

    综合:http://blog.csdn.net/dadoneo/article/details/7667726 与 http://android.tgbus.com/Android/androidne ...

  4. Android开发之漫漫长途 ⅥI——Android消息机制(Looper Handler MessageQueue Message)

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...

  5. Android开发之漫漫长途 Ⅶ——Android消息机制(Looper Handler MessageQueue Message)

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...

  6. android 进程间通信 messenger 是什么 binder 跟 aidl 区别 intent 进程间 通讯? android 消息机制 进程间 android 进程间 可以用 handler么 messenger 与 handler 机制 messenger 机制 是不是 就是 handler 机制 或 , 是不是就是 消息机制 android messenge

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha messenger 是什么 binder 跟 aidl 区别 intent 进程间 通讯 ...

  7. Android 进阶14:源码解读 Android 消息机制( Message MessageQueue Handler Looper)

    不要心急,一点一点的进步才是最靠谱的. 读完本文你将了解: 前言 Message 如何获取一个消息 Messageobtain 消息的回收利用 MessageQueue MessageQueue 的属 ...

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

    概览 Android消息机制是Android操作系统中比较重要的一块.具体使用方法在这里不再阐述,可以参考Android的官方开发文档. 消息机制的主要用途有两方面: 1.线程之间的通信.比如在子线程 ...

  9. Android进阶——Android消息机制之Looper、Handler、MessageQueen

    Android消息机制可以说是我们Android工程师面试题中的必考题,弄懂它的原理是我们避不开的任务,所以长痛不如短痛,花点时间干掉他,废话不多说,开车啦 在安卓开发中,常常会遇到获取数据后更新UI ...

随机推荐

  1. python 第二章 对象与类型

    可变对象和不可变对象 1,可变对象,list(列表),dict(字典),集合(set),字节数组. 2,不可变对象,数值类型,字符串,字节串,元组(具体形式 ()). 注意条件:可变和不可变指的是该对 ...

  2. Wireshark过滤语句中常用的操作符

    关键字有: eq,== 等于ne,!= 不等于gt,> 比…大lt,< 比…小 ge,>= 大于等于le,<= 小于等于 and,|| 且 or,&& 或 no ...

  3. JSON简介——(0)

    JSON: JavaScript Object Notation(JavaScript 对象表示法) JSON 是存储和交换文本信息的语法.类似 XML. JSON 比 XML 更小.更快,更易解析. ...

  4. Linux下文件目录权限和对应命令的总结

    Linux下的权限有rwx三种,分别对应读,写,执行三种,在对文件和目录时,分别是下列含义: 对应权限的命令为: 文件: r-- cat, more, head, tail w-- echo, vi ...

  5. C++中stringstream样例

    包含头文件 #include <sstream> 初始化可以使用 clear(). str( ) 赋值: 这里的clear方法,实际上是清空stringstream的状态(比如出错等),清 ...

  6. ssh -o 常用选项

    ssh -o ConnectTimeout=3 -o ConnectionAttempts=5 -o PasswordAuthentication=no -o StrictHostKeyCheckin ...

  7. Jmeter组件和属性(二)

    Jmeter脚本开发原则 简单.正确.高效.简单:去除无关的组件,同时能复用的尽量复用.正确:对脚本或者业务正确性进行必要的判断,不能少也不能多.(200),业务错误的情况下,也可能返回200,必须用 ...

  8. unittest单元测试

    unittest单元测试框架不仅可以适用于单元测试,还可以适用WEB自动化测试用例的开发与执行,该测试框架可组织执行测试用例,并且提供了丰富的断言方法,判断测试用例是否通过,最终生成测试结果.今天笔者 ...

  9. CCTF部分赛题分析

    这次算是跟着师傅们全程打完了CCTF的线上赛,一些强队的WriteUp也放了出来.这篇文章主要是想跟着大牛的思路把那些题重新再过一遍. PWN3 这个是格式化字符串漏洞的题.printf的格式化串直接 ...

  10. 前端代码编辑器ace 语法提示 代码提示

    本文主要是介绍ace编辑器的语法提示,自动完成.其实没什么可特别介绍的,有始有终吧,把项目中使用到的ace的功能都介绍下. { enableBasicAutocompletion: false, // ...