Android消息处理Handler,Message,Looper

来源:互联网 发布:js format date 编辑:程序博客网 时间:2024/05/18 03:26

MessageQueue

消息队列,存放消息的地方.每个线程只能拥有一个MessageQueue

Looper

Adnroid系统中的Looper负责管理线程的MessageQueue.除了主线程外,创建的线程默认是没有Looper和MessageQueue,创建一个Looper会同时创建一个MessageQueue,可以使用Looper.prepare()创建MessageQueue,Looper.loop()进入消息循环,Looper.release()释放资源.

class LooperThread extends Thread {public Handler mHandler;@Overridepublic void run() {// 创建消息队列Looper.prepare();mHandler = new Handler() {public void handleMessage(android.os.Message msg) {// process incoming messages here}};// 进入消息循环Looper.loop();super.run();//释放资源,使用Looper.release方法。} }

Message

消息对象,MessageQueue里存放的对象,可以调用removeMessages()时,将Message从Message Queue中删除和通过Handler对象的obtainMessage()获取一个Message实例,可以在线程中使用Handler对象的sendEmptyMessage()或者sendMessage()来传递Bundle对象到Handler,对Handler类提供handlerMessage(Message msg)判断,通过msg.what来区分每一条信息

Handler

Handler的作用是把消息加入特定的Looper消息队列中,并分发和处理该消息队列中的消息.如另一个线程怎样把消息放入主(UI)线程的消息队列,可以通过Handler对象,通过调用Handler主线程的sendMessage接口,把消息队列放入主线程的消息队列,并在该Handler的handleMessage()来处理消息

下面是模拟多线程并发的例子其中有用到当所有线程执行完毕更新UI需要Handler

/** Called when the activity is first created. */private String URL = "http://www.baidu.com";private int NUM = 100;private Button myButton;private EditText mEditTextURL, mEditTextNUM;private ProgressDialog pd;private static int count = 0;Handler myHandler = new Handler() {public void handleMessage(android.os.Message msg) {if (msg.what == 0)pd.dismiss();super.handleMessage(msg);};};@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);mEditTextURL = (EditText) findViewById(R.id.myEditTextURL);mEditTextNUM = (EditText) findViewById(R.id.myEditTextNUM);myButton = (Button) findViewById(R.id.myButton);myButton.setOnClickListener(new View.OnClickListener() {@Override public void onClick(View v) {// TODO Auto-generated method stubif (!mEditTextURL.getText().toString().trim().equals(""))URL = mEditTextURL.getText().toString().trim();if (!mEditTextNUM.getText().toString().trim().equals(""))NUM = Integer.parseInt(mEditTextNUM.getText().toString().trim());pd = ProgressDialog.show(HttpTestActivity.this, "xxx","xxx...");outFile();for (int i = 0; i < NUM; i++) {

count++;new Thread(new Handl(i)).start();}}});}public void outFile() {PrintStream stream = null;try {File f = new File(Environment.getExternalStorageDirectory(),"xxx.txt");if (!f.exists())f.createNewFile();stream = new PrintStream(f);System.setOut(stream);} catch (Exception e) {// TODO: handle exceptione.printStackTrace();}}class Handl implements Runnable {private int No;public Handl(int no) {this.No = no;}@Overridepublic void run() {// TODO Auto-generated method stubThread.currentThread().setName(No + "");HttpClient httpClient = new DefaultHttpClient();// 设置请求超时httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 5000);// 设置读取超时httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 3000);HttpGet get = new HttpGet(URL);String strResult = "";try {HttpResponse response = httpClient.execute(get);if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {strResult = EntityUtils.toString(response.getEntity());System.out.println("ThreadID:"+ Thread.currentThread().getName());System.out.println(strResult);} else {System.out.println(Thread.currentThread().getName()+ "请求失败");}Thread.sleep((long) Math.random() * 1000);} catch (InterruptedException e) {// TODO: handle exceptione.printStackTrace();} catch (IOException e) {// TODO: handle exceptione.printStackTrace();} catch (Exception e) {// TODO: handle exceptione.printStackTrace();} finally {synchronized (this) {count--;}}Message message = new Message();message.what = count; myHandler.sendMessage(message);}

消息的处理者,handler负责将需要传递的信息封装成Message,通过调用handler对象的obtainMessage()来实现; 将消息传递给Looper,这是通过handler对象的sendMessage()来实现的。继而由Looper将Message放入MessageQueue中。 当Looper对象看到MessageQueue中含有Message,就将其广播出去。该handler对象收到该消息后,调用相应的handler对象的handleMessage()方法 对其进行处理。

更多参考:

倒计时程序

线程之间的消息传递

 

原创粉丝点击