標籤:
Android中的非同步訊息處理機制主要由四個部分組成,Message、Handler、MessageQueueh和Looper。這裡先簡要介紹一下四個部分。
1.Message
Message是線上程之間傳遞的訊息,它可以在內部攜帶少量的資訊,用於在不同線程之間交換資料,Message可以使用what、arg1和arg2欄位來攜帶一些整形資料、使用obj來攜帶一個Object對象。
2.Handler
Handler是處理者的意思,主要用於發送和處理訊息。發送訊息一般是使用Handler的sendMessage()方法,而發出的訊息經過一系列地輾轉處理之後,最終會傳遞到Handler的handleMessage()方法中。
3.MessageQueue
MessageQueue是訊息佇列的意思,它主要用於存放所有通過Handler發送的訊息,這部分訊息會一直存在於訊息佇列中,等待被處理,每個線程中只會有一個MessageQueue對象。
4.Looper
Looper是每個線程中的MessageQueue 的管家,調用Looper的loop()方法後,會進入到一個無限迴圈當中,然後每當發現MessageQueue中存在一條訊息,就會將它取出,並傳遞到Handler的handleMessage()方法中,每個線程中也只會有一個Looper對象。
非同步訊息處理機制流程
android非同步訊息處理的機制也就是首先在主線程中建立一個handler對象,並重寫handleMessage()方法。
1 public class MainActivity extends Activity { 2 3 @Override 4 protected void onCreate(Bundle savedInstanceState) { 5 super.onCreate(savedInstanceState); 6 setContentView(R.layout.activity_main); 7 8 if (savedInstanceState == null) { 9 getFragmentManager().beginTransaction()10 .add(R.id.container, new PlaceholderFragment()).commit();11 }12 }13 14 public void onStart() {15 super.onStart();16 17 TextView tv = (TextView) this.findViewById(R.id.textView1);18 19 Button btn = (Button) this.findViewById(R.id.clickBtn);20 21 //建立一個handler對象22 CounterHandler handler = new CounterHandler(tv);23 24 ClickListener cl = new ClickListener(handler);25 26 btn.setOnClickListener(cl);27 }28 29 @Override30 public boolean onCreateOptionsMenu(Menu menu) {31 32 // Inflate the menu; this adds items to the action bar if it is present.33 getMenuInflater().inflate(R.menu.main, menu);34 return true;35 }36 37 @Override38 public boolean onOptionsItemSelected(MenuItem item) {39 // Handle action bar item clicks here. The action bar will40 // automatically handle clicks on the Home/Up button, so long41 // as you specify a parent activity in AndroidManifest.xml.42 int id = item.getItemId();43 if (id == R.id.action_settings) {44 return true;45 }46 return super.onOptionsItemSelected(item);47 }48 49 /**50 * A placeholder fragment containing a simple view.51 */52 public static class PlaceholderFragment extends Fragment {53 54 public PlaceholderFragment() {55 }56 57 @Override58 public View onCreateView(LayoutInflater inflater, ViewGroup container,59 Bundle savedInstanceState) {60 View rootView = inflater.inflate(R.layout.fragment_main, container,61 false);62 return rootView;63 }64 }65 66 }
然後當子線程中需要進行更新UI操作是,就建立一個Message對象,通過handler對象的sendMessage()方法將訊息發送出去,之後這條訊息會被添加到MessageQueue的隊列中等待被處理,而Looper則會一直嘗試從MessageQueue中取出待處理的訊息,最後分發回Handler的handleMessage()方法中。
1 //handler類 2 public class CounterHandler extends Handler{ 3 TextView tv; 4 5 CounterHandler(TextView tv){ 6 this.tv = tv; 7 } 8 //處理訊息 9 public void handleMessage(Message msg) {10 System.out.println("收到一條訊息"+msg.obj);11 tv.setText((String)msg.obj);12 }13 }
1 //子線程 2 public class Counter implements Runnable{ 3 Handler handler; 4 5 Counter(Handler handler){ 6 this.handler = handler; 7 } 8 9 public void run() {10 int i=0;11 while(i<100){12 i++;13 System.out.println(i);14 //顯示到TextView上15 16 //建立Message17 Message msg = new Message();18 msg.obj="count:"+i;19 //通過handletr發送訊息20 handler.sendMessage(msg);21 22 try {23 Thread.sleep(1000);24 } catch (InterruptedException e) {25 // TODO Auto-generated catch block26 e.printStackTrace();27 }28 29 }30 31 }32 33 }
1 //事件監聽器 2 public class ClickListener implements OnClickListener{ 3 Handler handler; 4 5 ClickListener(Handler handler){ 6 this.handler = handler; 7 } 8 9 10 @Override11 public void onClick(View v) {12 Counter counter = new Counter(handler);13 new Thread(counter).start();14 15 }16 17 }
由於Handler是在主線程中建立的,所以此時handleMessage()方法也會在主線程中運行,於是我們在這裡就可以安心的進行UI操作,這就是android多線程的非同步訊息處理機制。
Android多線程——非同步訊息處理機制