1. 程式人生 > >Android消息機制——Handler

Android消息機制——Handler

code port 過程 imp set mpat current ppc 銷毀

技術分享
  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

Android消息機制——Handler