何为Handler
Handler是Android为我们提供的一个更新UI的机制,也是一套信息处理的机制,通过他,可以进行发送信息,也可以处理信息。andriod提供了Handler 和 Looper 来满足线程间的通信。Handler先进先出原则。Looper类用来管理特定线程内对象之间的消息交换
1)Looper: 一个线程可以产生一个Looper对象,由它来管理此线程里的MessageQueue(消息队列)。
//当前线程的Looper,在Activity创建时,UI线程已经创建了Looper对象
//在Handler中机制中Looper是最为核心的,它一直处于循环读MessageQueue,有
//要处理的Message就将Message发送给当前的Handler实例来处理
//从以上可以看出,一个Handler实例必须关联一个Looper对象,否则出错
2)Handler: 你可以构造Handler对象来与Looper沟通,以便push新消息到MessageQueue里;或者接收Looper从Message Queue取出)所送来的消息。
3) Message Queue(消息队列):用来存放线程放入的消息。
4)线程:UIthread 通常就是main thread,而Android启动程序时会替它建立一个MessageQueue。 main线程也被叫做UI线程,因为改变UI一般是要通过UI线程来实现的
默认的情况下,Android是不允许在非UI线程中更新UI的,子线程中操作是危险的. 这个时候,Handler就出现了来解决这个复杂的问题,由于Handler运行在主线程中(UI线程中),它与子线程可以通过Message对象来传递数据,这个时候,Handler就承担着接受子线程传过来的(子线程用sedMessage()方法传弟)Message对象,(里面包含数据) , 把这些消息放入主线程队列中,配合主线程进行更新UI。
使用过程
1定义Handler对象并初始化,重写handleMessage()函数
2定义Thread线程对象,通常写成一个类形式(如class ThreadTest implements Runnable),在run()方法中操作数据,并把数据handler.sendMessage()方法传输 到handler对象中,并开启线程。(注意:该步骤不一定用Thread实现,也可以利用TimeTask实现,具体的操作同样放在run()方法中)
3在handleMessage()函数中根据不同的数据形式实现不同的方法。
public class MainAcitivity extends Activity { 12. /** Called when the activity is first created. */ 13. private Handler handler=new Handler(){ 14. public void handleMessage(Message msg){ 15. switch (msg.arg1) { 16. case 1: 17. txtTextView.setText("bbbb"); 18. break; 19. case 2: 20. setTitle("aaa"); 21. default: 22. break; 23. } 24. } 25. }; 26. private Button btn; 27. private TextView txtTextView; 28. @Override 29. public void onCreate(Bundle savedInstanceState) { 30. super.onCreate(savedInstanceState); 31. setContentView(R.layout.main); 32. txtTextView=(TextView)findViewById(R.id.txtView); 33. btn=(Button)findViewById(R.id.btn); 34. btn.setOnClickListener(new OnClickListener() { 35. 36. public void onClick(View arg0) { 37. ThreadTest threadTest=new ThreadTest(); 38. new Thread(threadTest).start(); 39. 40. ThreadTest2 threadTest2=new ThreadTest2(); 41. new Thread(threadTest2).start(); 42. } 43. }); 44. } 45. private class ThreadTest implements Runnable{ 46. 47. public void run() { 48. // TODO Auto-generated method stub 49. try{ 50. Thread.sleep(1000); 51. } 52. catch (Exception e) { 53. e.printStackTrace(); 54. } 55. Message msgMessage=new Message(); 56. msgMessage.arg1=1; 57. handler.sendMessage(msgMessage); 58. Log.e("ThreadName", Thread.currentThread().getName()); 59. } 60. 61. } 62. 63. private class ThreadTest2 implements Runnable{ 64. 65. public void run() { 66. // TODO Auto-generated method stub 67. try{ 68. Thread.sleep(1000); 69. } 70. catch (Exception e) { 71. e.printStackTrace(); 72. } 73. Message msgMessage=new Message(); 74. msgMessage.arg1=2; 75. handler.sendMessage(msgMessage); 76. Log.e("ThreadName", Thread.currentThread().getName()); 77. } 78. 79. } 80.}
实现一个Demo实现从网络上下载图片并实现的例子
public class HandlerPostActivity2 extends Activity { private Button btnDown; private ImageView ivImage; private static String image_path = "http://ww4.sinaimg.cn/bmiddle/786013a5jw1e7akotp4bcj20c80i3aao.jpg"; private ProgressDialog dialog; // 一个静态的Handler,Handler建议声明为静态的 private static Handler handler=new Handler(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.asynctask_activity); btnDown = (Button) findViewById(R.id.btnDown); ivImage = (ImageView) findViewById(R.id.ivSinaImage); dialog = new ProgressDialog(this); dialog.setTitle("提示"); dialog.setMessage("正在下载,请稍后..."); dialog.setCancelable(false); btnDown.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 开启一个子线程,用于下载图片 new Thread(new MyThread()).start(); // 显示对话框 dialog.show(); } }); } public class MyThread implements Runnable { @Override public void run() { // 下载一个图片 HttpClient httpClient = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(image_path); HttpResponse httpResponse = null; try { httpResponse = httpClient.execute(httpGet); if (httpResponse.getStatusLine().getStatusCode() == 200) { byte[] data = EntityUtils.toByteArray(httpResponse .getEntity()); // 得到一个Bitmap对象,并且为了使其在post内部可以访问,必须声明为final final Bitmap bmp=BitmapFactory.decodeByteArray(data, 0, data.length); handler.post(new Runnable() { @Override public void run() { // 在Post中操作UI组件ImageView ivImage.setImageBitmap(bmp); } }); // 隐藏对话框 dialog.dismiss(); } } catch (Exception e) { e.printStackTrace(); } } } }
部分摘抄自:http://blog.sina.com.cn/s/blog_74e9d98d0101g9iw.html