1:handler机制
1:handler中类的含义。
Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队,终由Handler处理。
Handler:处理者,负责Message的发送及处理。使用Handler时,需要实现handleMessage(Message msg)方法来对特定的Message进行处理,例如更新UI等。
MessageQueue:消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行。当然,存放Message并非实际意义的保存,而是将Message以链表的方式串联起来的,等待Looper的抽取。(FIFO为先进先出------队列,FILO为先进后出--------栈)注:堆,队列优先,先进先出。栈,先进后出
Looper:消息泵,不断地从MessageQueue中抽取Message执行。因此,一个MessageQueue需要一个Looper。
Thread:线程,负责调度整个消息循环,即消息循环的执行场所。
2:Handler,Looper和MessageQueue就是简单的三角关系。
Looper和MessageQueue一一对应,创建一个Looper的同时,会创建一个MessageQueue。
而Handler与它们的关系,只是简单的聚集关系,即Handler里会引用当前线程里的特定Looper和MessageQueue。
这样说来,多个Handler都可以共享同一Looper和MessageQueue了。
这些Handler也就运行在同一个线程里,每个线程一个Loop而 一个MessageQueue。
3:handler的使用
子线程网主线程中发消息,直接在主线程中handler = new Handler(),子线程中可以直接用handler.sendmessage。。。
主线程网子线程中,Looper.prepare()... handler = new Handler()... looper.loop...然后handler.sendmessage
一个Message经由Handler的发送,MessageQueue的入队,Looper的抽取,又再一次地回到Handler的怀抱
Handler的处理过程运行在创建Handler的线程里
一个Looper对应一个MessageQueue
一个线程对应一个Looper
一个Looper可以对应多个Handler
不确定当前线程时,更新UI时尽量调用post方法
private android.os.Handler mHandler = new android.os.Handler() { public void handleMessage(Message msg) { switch (msg.what) { case 1: break; default: break; } } };
Handler先执行下面的代码,然后才执行handlermessage()里面的方法。
2:AsyncTask利用线程任务异步AsyncTask的原理和Handler很接近,都是通过往主线程发送消息来更新主线程的UI,这种方式是异步的,所以就叫AsyncTask。
AsyncTask是为了方便编写后台线程与UI线程交互的辅助类,它的内部实现是一个线程池,每个后台任务会提交到线程池中的线程执行,然后通过向UI线程的Handler传递消息的方式调用相应的回调方法实现UI界面的更新。
AsyncTask的构造方法有三个模板参数:Params(传递给后台任务的参数类型),Progress(后台计算执行过程中,进度单位(progress units)的类型,也就是后台程序已经执行了百分之几)和Result(后台执行返回的结果的类型)。
protected void onProgressUpdate(Integer... progress) {
mProgressBar.setProgress(progress[0]);
}
onProgressUpdate()方法用于更新进度条的进度。
protected void onPostExecute(Bitmap result) {
}
onPostExecute()方法用于处理Result的显示,也就是UI的更新。
protected void onPreExecute() {
}
protected void onCancelled() {
}
这两个方法主要用于在执行前和执行后清空图片和进度。
3:runOnUiThread()
runOnUiThread先执行run()里面的方法再接着往下执行。activity.runOnUiThread(new Runnable() { public void run() { } });
4:部分控件本身支持post()
一些组件本身就有提供方法来更新自己,如ProgressBar本身就有一个post()方法,只要我们传进一个Runnable对象,就能更新它的进度。
只要是继承自View的组件,都可以利用post()方法,而且我们还可以使用postDelay()方法来延迟执行该Runnable对象。
总结
1.如果只是单纯的想要更新UI而不涉及到多线程的话,使用View.post()就可以了;
2.需要另开线程处理数据以免阻塞UI线程,像是IO操作或者是循环,可以使用Activity.runOnUiThread();
3.如果需要传递状态值等信息,像是蓝牙编程中的socket连接,就需要利用状态值来提示连接状态以及做相应的处理,就需要使用Handler + Thread的方式;
4.如果是后台任务,像是下载任务等,就需要使用AsyncTask。