我们先来看一些术语:
1.Parcel:其实就是一个容器,我们来看官方描述:Container for a message (data and object references) that can be sent through an IBinder。很简单,就是一个消息的集合,而这样的集合是可以通过IBinder接口发送的。
2.Message:Defines a message containing a description and arbitrary data object that can be sent to aHandler. :消息就是一种包含描述和任意数据而且能够发送给Handler的数据结构。
3.Handler:A Handler allows you to send and process Message and Runnable objects associated with a thread'sMessageQueue. Each Handler instance is associated with a single thread and that thread's message queue.:Handler 允许你发送以及处理与某个线程的消息队列关联的消息和Runnable对象。每个Handler实例是和单个线程以及它的消息队列是关联起来的。
4.Looper:Class used to run a message loop for a thread. Threads by default do not have a message loop associated with them; to create one, callprepare() in the thread that is to run the loop, and thenloop() to have it process messages until the loop is stopped.
Most interaction with a message loop is through the Handler class.:一个类,什么样的类呢?用于运行某个线程的消息循环的类。通常情况下,一个线程是不含一个与自身关联的消息loop的。如果new一个thread,需要在你的线程中调用prepare()函数来启动loop,然后loop()在终止之前会自己处理消息。对于一般的主线程来说,会自动创建一个mainloop与主线程绑定。可以使用getMainLooper()来获取主线程的loop函数。
5.MessageQueue:Low-level class holding the list of messages to be dispatched by aLooper. Messages are not added directly to a MessageQueue, but rather throughMessageQueue.IdleHandler objects associated with the Looper.You can retrieve the MessageQueue for the current thread withLooper.myQueue().:也是一个类,什么样的类呢?保存了N个用于被Looper分发的Message的类。因为我们的Message不是直接add到MessageQueue里面的,而是通过一个MessageQueue.IdleHandler的对象来和Looper关联起来的,我们可以通过Looper.myQueue()来获取到当前线程的消息队列。
好了,上面的术语基本上都是Android消息机制相关的术语,也做了一些简单翻译,讨厌看的童鞋可以看看英文原始注释。俺们一起来理下思路:
· N个消息放一起,堆在一个容器里面,该容器里面的东东而且能够通过IBinder形式发送,这就形成了Parcel。(Parcel的用法暂时不单独提了,后面相关技术文档会涉及到了就说,这个在Android Framework里面用的比较多。)
·通常我们的Message不是发一条就处理一条的,它首先是放在消息队列里面的进行逐条处理,怎么放到消息队列里面的呢?不是直接的add进去,而是和Looper关联的一个MessageQueue.IdleHandler对象来add进去的,这里就看到了,looper起到了Message和MessageQueue的一个桥梁作用(记住:消息队列中的消息也是由Looper给整出去的。),这个还不是最主要的。looper最主要的桥梁作用是Message和Handler,Looper它可以分发消息,分发的消息是给Hander进行发送和处理的。Hanlder通过looper从MessageQueue里面获取Message进行处理。它也可以get 消息,然后add到消息队列里面去。
6.AsyncTask :这是个异步任务机制,也是来捣鼓线程间通信的,该机制将相应操作在线程池中取出一个线程来执行,然后将结果传递给主线程,主线程拿到该结果后即可以进行更新界面等相应操作了。
AsyncTask的使用需要我们去创建一个继承自AsyncTask的类AsyncTask<Params, Progress, Result>,
参数说明如下:
Params, the type of the parameters sent to the task upon execution.:发送给异步任务去执行的参数类型。 Progress, the type of the progress units published during the background computation.:在后台执行程序的时候返回给调用线程进度的参数类型。 Result, the type of the result of the background computation.:后台执行程序计算好的结果类型。该类有如下几个子方法:doInBackground(String... params) :后台执行程序,参数params是由调用线程传递过来。然后将返回的结果送给onPostExecute, onPostExecute可以依据放回的结果来更新UI的操作。在子线程中操作。
onCancelled():可以在处理的过程中取消异步线程处理。如果执行已经结束的话该方式执行失败。在主线程中操作。
onPostExecute(String result):从doInBackground获取执行后的结果,然后可以对UI的主界面进行更新操作。该操作的执行是在主线程中。
onPreExecute() :执行子线程前进行的一系列的准备工作。该操作在主线程中操作。
onProgressUpdate(String... values):主线程中用于显示进度的函数,该函数由doInBackground()调用publishProgress()函数将结果发送过来。在主线程中操作。
以上几个函数都是回调函数,系统会自己调用,切忌不要手动去调用它。
通常情况下我们使用AsyncTask的情况会比较多,因为它比handle机制简单,而且使用起来也比较方便,在后面的例子中将会将两种情况一起使用。
实例: