• 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

  • 相关阅读:
    软件设计师考试知识点总结
    HTML和CSS
    JavaScript核心知识点
    操作系统--页面置换算法(缺页数计算)
    中标麒麟系统远程桌面连接
    数据结构 图
    数据结构 二叉树
    MATLAB 大数据剔除坏值
    PTA 邻接表存储图的广度优先遍历(20 分)
    PTA 邻接矩阵存储图的深度优先遍历
  • 原文地址:https://www.cnblogs.com/Claire6649/p/6895482.html
Copyright © 2020-2023  润新知