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 @Override 30 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 @Override 38 public boolean onOptionsItemSelected(MenuItem item) { 39 // Handle action bar item clicks here. The action bar will 40 // automatically handle clicks on the Home/Up button, so long 41 // 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 @Override 58 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 //创建Message 17 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 block 26 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 @Override 11 public void onClick(View v) { 12 Counter counter = new Counter(handler); 13 new Thread(counter).start(); 14 15 } 16 17 }
由于Handler是在主线程中创建的,所以此时handleMessage()方法也会在主线程中运行,于是我们在这里就可以安心的进行UI操作,这就是android多线程的异步消息处理机制。