Handler是什么? Handler是Android提供的一套用来更新UI的机制,也是一套消息处理机制,可以通过它发送消息,也可以通过它处理消息。 所有Activity生命周期回调的方法(例如onCreate()、onDestory()等等),都是通过handler机制去发送消息的,然后根据不同的消息(message)做相应的分支处理。例如发送一个消息给 Framework,告知需要调用onCreate()或onDestory()方法。实际上在 Framework 当中,Activity的交互大部分都是用AMS(Activity Manager Service)做处理的。整个应用程序的核心的一个类就是 Activity Thread,Activity Thread就是通过handler机制接收到 Activity Manager Service发送的有关Activity生命周期的管理的消息(比如启动)。 为什么要使用Handler? Android在设计的时候,就封装了一套消息的创建、传递、处理机制,如果不遵循这样的机制,就没有办法更新UI信息,并且会抛出异常信息。这样的机制便包含Handler机制。
1. 我们要创建一个handler的时候,它会和默认的一个线程进行绑定,而这个默认的线程当中就有一个MessageQueue(消息队列)。 2. handler的两个用途:(1)定时发送一个Messages或者Runnables对象;(2)可以在一个线程当中去处理并执行一个Action的动作。 3. 主线程运行一个消息队列,并管理着一些顶级的应用对象(top-level application objects),包括Activity、Broadcast Receiver等等,这些对象默认都是创建在Activity Thread(也就是我们常说的UI线程或者主线程)当中。
Handler的示例,实现图片轮播。 代码实现 1. 在主布局中定义一个ImageView控件。 2. 在 MainActivity 中创建并初始化ImageView,定义一个图片数组 images 和数组下标索引 index,创建一个Handler对象。 3. 创建一个内部类 MyRunnable 实现 Runnable 接口,重写 run() 方法: public void run() { index++; index = index%3; // 图片轮播(一般是通过ViewPager实现图片轮播) imageView.setImageResource(images[index]); handler.postDelayed(myRunnable,1000); // 每隔一秒换一次图片 } 4. 在onCreste()方法中调用handler,也就是在主线程中调用handler: handler.postDelayed(myRunnable,1000);
1 public class MainActivity extends ActionBarActivity { 2 private Handler handler1 = new Handler(); 3 private Handler handler2 = new Handler(new Callback() { 4 5 @Override 6 public boolean handleMessage(Message msg) { 7 // TODO Auto-generated method stub 8 Toast.makeText(getApplicationContext(), "1", 1).show(); 9 return false;// 若设为true则后边不执行 10 } 11 }) { 12 13 public void handleMessage(Message msg) { 14 // TODO Auto-generated method stub 15 Toast.makeText(getApplicationContext(), "2", 1).show(); 16 } 17 18 }; 19 20 21 private Handler handler3 = new Handler() { 22 public void handleMessage(android.os.Message msg) { 23 // textView.setText(""+msg.arg1+"-"+msg.arg2); 24 textView.setText("" + msg.obj); 25 }; 26 }; 27 28 29 private TextView textView; 30 private ImageView imageView; 31 private int Image[] = { R.drawable.a, R.drawable.b, R.drawable.c }; 32 private int index; 33 34 @Override 35 protected void onCreate(Bundle savedInstanceState) { 36 super.onCreate(savedInstanceState); 37 setContentView(R.layout.fragment_main); 38 textView = (TextView) findViewById(R.id.textview); 39 imageView = (ImageView) findViewById(R.id.imageView1); 40 new Thread() { 41 public void run() { 42 try { 43 Thread.sleep(2000); 44 // (1) 45 // Message message=new Message(); 46 // message.arg1=88; 47 // message.arg2=100; 48 49 // (2) 50 Message message = handler3.obtainMessage(); 51 52 Person person = new Person(); 53 person.age = 23; 54 person.name = "zy"; 55 message.obj = person; 56 // handler.sendMessage(message);//(1) 57 message.sendToTarget();// (2) 58 59 } catch (InterruptedException e) { 60 // TODO Auto-generated catch block 61 e.printStackTrace(); 62 } 63 }; 64 }.start(); 65 66 /* 67 * new Thread() { 68 * public void run() { 69 * try { Thread.sleep(1000); 70 * handler.post(new Runnable() { 71 * 72 * @Override 73 * public void run() { 74 * // TODO Auto-generated method stub 75 * textView.setText("更新线程"); } }); 76 * 77 * } catch (InterruptedException e) { // TODO Auto-generated catch block 78 * e.printStackTrace(); } }; }.start(); 79 */ 80 81 handler1.postDelayed(myRunnable, 1000);// 1000:一秒钟换一次 82 83 } 84 85 MyRunnable myRunnable = new MyRunnable(); 86 //图片循环播放 87 class MyRunnable implements Runnable { 88 89 @Override 90 public void run() { 91 // TODO Auto-generated method stub 92 index++; 93 index = index % 3; 94 imageView.setImageResource(Image[index]); 95 handler1.postDelayed(myRunnable, 1000); 96 } 97 } 98 99 class Person { 100 public int age; 101 public String name; 102 103 @Override 104 public String toString() { 105 // TODO Auto-generated method stub 106 return "name=" + name + "age=" + age; 107 } 108 } 109 110 public void click(View view) { 111 handler1.removeCallbacks(myRunnable); 112 handler2.sendEmptyMessage(1); 113 } 114 115 }
Android为什么要设计只能通过Handler机制更新UI呢? 最根本的目的就是解决多线程并发的问题。 1. 假如在一个Activity当中,有多个线程去更新UI,并且都没有加锁机制,那么会产生什么样子的问题? --> 更新界面混乱。 2. 如果对更新UI的操作都进行加锁处理的话又会产生什么样子的问题? --> 性能下降。 正是对以上问题的考虑,Android给我们提供了一套更新UI的机制,我们只需遵循这样的机制就可以了,根本不用去关心多线程(并发)的问题,所有的更新UI的操作,都是在主线程的消息队列中去“轮询”处理的。 Handler的原理是什么? 面试经典问题:Looper、Handler、Message(或MessageQueue)三者间的关系? 一、Handler封装了消息的发送(主要是将消息发送给谁(默认是Handler自己),以及什么时候发送)。 Looper: 1.内部包含一个消息队列 MessageQueue,所有的 Handler 发送的消息都走向(加入)这个消息队列。 2.Looper.Looper方法,就是一个死循环,不断地从 MessageQueue 取得消息,如果有消息就处理消息,没有消息就阻塞。 二、MessageQueue MessageQueue 就是一个消息队列,可以添加消息,并处理消息。 三、Handler 也很简单,内部会跟 Looper 进行关联,也就是说,在 Handler 的内部可以找到 Looper,找到了 Looper 也就找到了 Message。在 Handler 中发送消息,其实就是向 MessageQueue 队列中发送消息。 总结:Handler 负责发送消息,Looper 负责接收 Handler 发送的消息,并直接把消息回传给 Handler 自己,MessageQueue就是一个存储消息的容器。
时间: 2024-11-09 02:26:57