一、几个关键概念
1、MessageQueue:是一种数据结构,见名知义,就是一个消息队列,存放消息的地方。每一个线程最多只可以拥有一个MessageQueue数据结构。
创建一个线程的时候,并不会自动创建其MessageQueue。通常使用一个Looper对象对该线程的MessageQueue进行管理。主线程创建时,会创建一
个默认的Looper对象,而Looper对象的创建,将自动创建一个Message Queue。其他非主线程,不会自动创建Looper,要需要的时候,通过调
用prepare函数来实现。
1 final MessageQueue mQueue; 2 private Looper() { 3 mQueue = new MessageQueue(); 4 mRun = true; 5 mThread = Thread.currentThread(); 6 }
下面是prepare方法,静态方法
1 private static final ThreadLocal sThreadLocal = new ThreadLocal(); 2 public static final void prepare() { 3 if (sThreadLocal.get() != null) { 4 throw new RuntimeException("Only one Looper may be created per thread"); 5 } 6 sThreadLocal.set(new Looper()); 7 }
2、Message:消息对象,Message Queue中的存放的对象。一个Message Queue中包含多个Message。
Message实例对象的取得,
通常使用Message类里的静态方法obtain(),
该方法有多个重载版本可供选择;它的创建并不一定是直接创建一个新的实例,
而是先从Message Pool(消息池)中看有没有可用的Message实例,存在则直接取出返回这个实例。如果Message Pool中没有可用的Message实例,
则才用给定的参数创建一个Message对象。调用removeMessages()时,将Message从Message Queue中删除,同时放入到Message Pool中。除了上面这
种方式,也可以通过Handler对象的obtainMessage()获取一个Message实例。
3、Looper:
是MessageQueue的管理者。每一个MessageQueue都不能脱离Looper而存在(正如刚1提到的,一个Looper对一个message对象管理),Looper对象的创建是通过prepare函数来实现的。同时每一个Looper对象
和一个线程关联。通过调用Looper.myLooper()可以获得当前线程的Looper对象
创建一个Looper对象时,会同时创建一个MessageQueue对象。除了主线程有默认的Looper,其他线程默认是没有MessageQueue对象的,所以,不能
接受Message。如需要接受,自己定义一个Looper对象(通过prepare函数),这样该线程就有了自己的Looper对象和MessageQueue数据结构了。
Looper从MessageQueue中取出Message然后,交由Handler的handleMessage进行处理。处理完成后,调用Message.recycle()将其放入Message Pool中。
4、Handler:
消息的处理者,handler负责将需要传递的信息封装成Message,通过调用handler对象的obtainMessage()来实现;
将消息传递给Looper,这是通过handler对象的sendMessage()来实现的。继而由Looper将Message放入MessageQueue中。
当Looper对象看到MessageQueue中含有Message,就将其广播出去。该handler对象收到该消息后,调用相应的handler对象的handleMessage()方法
1 二、线程之间的消息如何进行传递 2 3 1、主线程给自己发送Message 4 5 package test.message; 6 7 import android.app.Activity; 8 import android.os.Bundle; 9 import android.os.Handler; 10 import android.os.Looper; 11 import android.os.Message; 12 import android.view.View; 13 import android.widget.Button; 14 import android.widget.TextView; 15 16 public class MainActivity extends Activity { 17 18 private Button btnTest; 19 private TextView textView; 20 21 private Handler handler; 22 23 @Override 24 public void onCreate(Bundle savedInstanceState) { 25 super.onCreate(savedInstanceState); 26 setContentView(R.layout.main); 27 28 btnTest = (Button)this.findViewById(R.id.btn_01); 29 textView = (TextView)this.findViewById(R.id.view_01); 30 31 btnTest.setOnClickListener(new View.OnClickListener() { 32 33 @Override 34 public void onClick(View arg0) { 35 36 Looper looper = Looper.getMainLooper(); //主线程的Looper对象 37 //这里以主线程的Looper对象创建了handler, 38 //所以,这个handler发送的Message会被传递给主线程的MessageQueue。 39 handler = new MyHandler(looper); 40 handler.removeMessages(0); 41 //构建Message对象 42 //第一个参数:是自己指定的message代号,方便在handler选择性地接收 43 //第二三个参数没有什么意义 44 //第四个参数需要封装的对象 45 Message msg = handler.obtainMessage(1,1,1,"主线程发消息了"); 46 47 handler.sendMessage(msg); //发送消息 48 49 } 50 }); 51 } 52 53 class MyHandler extends Handler{ 54 55 public MyHandler(Looper looper){ 56 super(looper); 57 } 58 59 public void handleMessage(Message msg){ 60 super.handleMessage(msg); 61 textView.setText("我是主线程的Handler,收到了消息:"+(String)msg.obj); 62 } 63 } 64 } 65 66 2、其他线程给主线程发送Message 67 68 package test.message; 69 70 import android.app.Activity; 71 import android.os.Bundle; 72 import android.os.Handler; 73 import android.os.Looper; 74 import android.os.Message; 75 import android.view.View; 76 import android.widget.Button; 77 import android.widget.TextView; 78 79 public class MainActivity extends Activity { 80 81 private Button btnTest; 82 private TextView textView; 83 84 private Handler handler; 85 86 @Override 87 public void onCreate(Bundle savedInstanceState) { 88 super.onCreate(savedInstanceState); 89 setContentView(R.layout.main); 90 91 btnTest = (Button)this.findViewById(R.id.btn_01); 92 textView = (TextView)this.findViewById(R.id.view_01); 93 94 btnTest.setOnClickListener(new View.OnClickListener() { 95 96 @Override 97 public void onClick(View arg0) { 98 99 //可以看出这里启动了一个线程来操作消息的封装和发送的工作 100 //这样原来主线程的发送就变成了其他线程的发送,简单吧?呵呵 101 new MyThread().start(); 102 } 103 }); 104 } 105 106 class MyHandler extends Handler{ 107 108 public MyHandler(Looper looper){ 109 super(looper); 110 } 111 112 public void handleMessage(Message msg){ 113 super.handleMessage(msg); 114 textView.setText("我是主线程的Handler,收到了消息:"+(String)msg.obj); 115 } 116 } 117 118 //加了一个线程类 119 class MyThread extends Thread{ 120 121 public void run(){ 122 Looper looper = Looper.getMainLooper(); //主线程的Looper对象 123 //这里以主线程的Looper对象创建了handler, 124 //所以,这个handler发送的Message会被传递给主线程的MessageQueue。 125 handler = new MyHandler(looper); 126 127 //构建Message对象 128 //第一个参数:是自己指定的message代号,方便在handler选择性地接收 129 //第二三个参数没有什么意义 130 //第四个参数需要封装的对象 131 Message msg = handler.obtainMessage(1,1,1,"其他线程发消息了"); 132 133 handler.sendMessage(msg); //发送消息 134 } 135 } 136 } 137 138 3、主线程给其他线程发送Message 139 140 package test.message; 141 142 import android.app.Activity; 143 import android.os.Bundle; 144 import android.os.Handler; 145 import android.os.Looper; 146 import android.os.Message; 147 import android.view.View; 148 import android.widget.Button; 149 import android.widget.TextView; 150 151 public class MainActivity extends Activity { 152 153 private Button btnTest; 154 private TextView textView; 155 156 private Handler handler; 157 158 @Override 159 public void onCreate(Bundle savedInstanceState) { 160 super.onCreate(savedInstanceState); 161 setContentView(R.layout.main); 162 163 btnTest = (Button)this.findViewById(R.id.btn_01); 164 textView = (TextView)this.findViewById(R.id.view_01); 165 166 167 //启动线程 168 new MyThread().start(); 169 170 btnTest.setOnClickListener(new View.OnClickListener() { 171 172 @Override 173 public void onClick(View arg0) { 174 //这里handler的实例化在线程中 175 //线程启动的时候就已经实例化了 176 Message msg = handler.obtainMessage(1,1,1,"主线程发送的消息"); 177 handler.sendMessage(msg); 178 } 179 }); 180 } 181 182 class MyHandler extends Handler{ 183 184 public MyHandler(Looper looper){ 185 super(looper); 186 } 187 188 public void handleMessage(Message msg){ 189 super.handleMessage(msg); 190 textView.setText("我是主线程的Handler,收到了消息:"+(String)msg.obj); 191 } 192 } 193 194 class MyThread extends Thread{ 195 196 public void run(){ 197 Looper.prepare(); //创建该线程的Looper对象,用于接收消息 198 199 //注意了:这里的handler是定义在主线程中的哦,呵呵, 200 //前面看到直接使用了handler对象,是不是在找,在什么地方实例化的呢? 201 //现在看到了吧???呵呵,开始的时候实例化不了,因为该线程的Looper对象 202 //还不存在呢。现在可以实例化了 203 //这里Looper.myLooper()获得的就是该线程的Looper对象了 204 handler = new ThreadHandler(Looper.myLooper()); 205 206 //这个方法,有疑惑吗? 207 //其实就是一个循环,循环从MessageQueue中取消息。 208 //不经常去看看,你怎么知道你有新消息呢??? 209 Looper.loop(); 210 211 } 212 213 //定义线程类中的消息处理类 214 class ThreadHandler extends Handler{ 215 216 public ThreadHandler(Looper looper){ 217 super(looper); 218 } 219 220 public void handleMessage(Message msg){ 221 //这里对该线程中的MessageQueue中的Message进行处理 222 //这里我们再返回给主线程一个消息 223 handler = new MyHandler(Looper.getMainLooper()); 224 225 Message msg2 = handler.obtainMessage(1,1,1,"子线程收到:"+(String)msg.obj); 226 227 handler.sendMessage(msg2); 228 } 229 } 230 } 231 } 232 233 4、其他线程给自己发送Message 234 235 package test.message; 236 237 import android.app.Activity; 238 import android.os.Bundle; 239 import android.os.Handler; 240 import android.os.Looper; 241 import android.os.Message; 242 import android.view.View; 243 import android.widget.Button; 244 import android.widget.TextView; 245 246 public class MainActivity extends Activity { 247 248 private Button btnTest; 249 private TextView textView; 250 251 private Handler handler; 252 253 @Override 254 public void onCreate(Bundle savedInstanceState) { 255 super.onCreate(savedInstanceState); 256 setContentView(R.layout.main); 257 258 btnTest = (Button)this.findViewById(R.id.btn_01); 259 textView = (TextView)this.findViewById(R.id.view_01); 260 261 262 btnTest.setOnClickListener(new View.OnClickListener() { 263 264 @Override 265 public void onClick(View arg0) { 266 //启动线程 267 new MyThread().start(); 268 } 269 }); 270 } 271 272 class MyHandler extends Handler{ 273 274 public MyHandler(Looper looper){ 275 super(looper); 276 } 277 278 public void handleMessage(Message msg){ 279 super.handleMessage(msg); 280 textView.setText((String)msg.obj); 281 } 282 } 283 284 class MyThread extends Thread{ 285 286 public void run(){ 287 Looper.prepare(); //创建该线程的Looper对象 288 //这里Looper.myLooper()获得的就是该线程的Looper对象了 289 handler = new ThreadHandler(Looper.myLooper()); 290 Message msg = handler.obtainMessage(1,1,1,"我自己"); 291 handler.sendMessage(msg); 292 293 Looper.loop(); 294 295 } 296 297 //定义线程类中的消息处理类 298 class ThreadHandler extends Handler{ 299 300 public ThreadHandler(Looper looper){ 301 super(looper); 302 } 303 304 public void handleMessage(Message msg){ 305 //这里对该线程中的MessageQueue中的Message进行处理 306 //这里我们再返回给主线程一个消息 307 //加入判断看看是不是该线程自己发的信息 308 if(msg.what == 1 && msg.obj.equals("我自己")){ 309 310 handler = new MyHandler(Looper.getMainLooper()); 311 312 Message msg2 = handler.obtainMessage(1,1,1,"禀告主线程:我收到了自己发给自己的Message"); 313 314 handler.sendMessage(msg2); 315 } 316 317 } 318 } 319 } 320 } 321 322 附注: 323 上面四个例子的布局文件是同一个文件main.xml 324 325 <?xml version="1.0" encoding="utf-8"?> 326 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 327 android:rientation="vertical" 328 android:layout_width="fill_parent" 329 android:layout_height="fill_parent" 330 > 331 <TextView android:id="@+id/view_01" 332 android:layout_width="fill_parent" 333 android:layout_height="wrap_content" 334 android:text="@string/hello" 335 /> 336 337 <Button android:id="@+id/btn_01" 338 android:layout_width="fill_parent" 339 android:layout_height="wrap_content" 340 android:text="测试消息" /> 341 </LinearLayout>
==================================================================================================
提供几个链接
http://blog.csdn.net/mylzc/article/details/6771331
http://tanghaibo001.blog.163.com/blog/static/9068612020111287218197/
http://www.cnblogs.com/angeldevil/p/3340644.html
http://www.cnblogs.com/xirihanlin/archive/2011/04/11/2012746.html
http://www.cnblogs.com/angeldevil/p/3340644.html
//个人理解:
引用上面四组代码的例子(final 中的1---321行)
一个线程有一个Looper 管理一个messageQueue 主线程(ui线程的Looper 和messagequeue自动创建 其他线程需要静态方法prepare (Looper) Looper 创建messageQueue也创建,)
messageQueue存贮message
异步处理实际上是不同线程对其他线程handler的操作 ,然后handler负责把生成的message发给自己的messagequeue中,而Looper则负责“常去看看queue里有没有新消息,要是有就获得消息”
<我在回去看看代码理解理解这样理解对不对>
//最终版本
接收发送消息<或者说对messagequeue的操作>全都是属于某一个Looper的一个handler所做的,异步处理实现的关键在于其他线程对handler的调用,严格的说是发送的调用
线程A向线程B发送消息:
线程A调用线程B的handler obtain一个message
然后sendmessage
此时在线程B的messagequeue中就出现新的message了,
通过Looper的监听发现新的message后对这个message做相应的操作
这样就完成了异步处理