HandlerThread继承于Thread,所以它本质就是个Thread。与普通Thread的差别就在于,它有个Looper成员变量。这个Looper其实就是对消息队列以及队列处理逻辑的封装,简单说就是 消息队列+消息循环。
当我们需要一个工作者线程,而不是把它当作一次性消耗品,用过即废弃的话,就可以使用它。
private Handler mHandler = null;
private HandlerThread mHandlerThread = null; private void sentRunnableToWorker(Runnable run){
if (null == mHandlerThread)
{
mHandlerThread = new HandlerThread("WorkerThread"); // 给工作者线程低优先级
mHandlerThread.setPriority(Thread.MIN_PRIORITY);
mHandlerThread.start();
}
if (null == mHandler)
mHandler = new Handler(mHandlerThread.getLooper());
mHandler.post(run); }
AsyncQueryHandler就是基于HandlerThread封装了线程间双向通信,而HandlerThread只做了一半。
源码分析:
1. public class HandlerThread extends Thread{
2. //线程的优先级
3. private int mPriority;
4. //线程的id
5. private int mTid=-1;
6. private Looper mLooper;
7. public HandlerThread(String name){
8. super(name);
9. //设置优先级为默认线程
10. mPriority=Process.THREAD_PRIORITY_DEFAULT;
11. }
12. public HandlerThread(String name,int priority){
13. super(name);
14. mPriority=priority;
15. }
16. //这个如果有需要的话可以继承重写,例如可以在里面声明个Handler 关联此线程。
17. protected void onLooperPrepared(){}
18. //这个很熟悉吧
19. public void run(){
20. //得到当前线程的id
21. mTid=Process.myTid;
22. //一旦调用这句代码,就在此线程中创建了Looper 对象。这就是为什么我们要在调用线程的start()方法后
23. //才能得到Looper 对象即 当 调用Looper.myLooper()时不为Null。
24. Looper.prepare();
25. //同步代码块,意思就是当获得mLooper对象后,唤醒所有线程。(会在以后的例子中有所体现)
26. synchronized(this){
27. mLooper=Looper.myLooper();
28. notifyAll();
29. }
30. //设置线程的优先级
31. Process.setThreadPriority(mPriority);
32. //调用上面的方法(需要用户重写)
33. onLooperPrepared();
34. //建立了消息循环
35. Looper.loop();
36. mTid=-1;
37. }
38. public Looper getLooper(){
39. //线程死了,那就只有NULL了。
40. if(!isAlive()){
41. return null;
42. }
43. //看见没,又是同步代码块,正好和上面的形成对应,就是说只要线程活着并且我的looper为NULL,那么我就让你一直等。。。
44. synchronized(this){
45. while(isAlive()&&mLooper==null){
46. try{
47. wait();
48. }catch(InterruptedException e){}
49. }
50. }
51. return mLooper;
52. }
53. public boolean quit(){
54. Looper looper =getLooper();
55. if(looper!=null){
56. //退出消息循环
57. looper.quit();
58. return true;
59. }
60. return false;
61. }
62. //返回线程ID
63. public int getThreadId(){
64. return mTid;
65. }
66. }
复制代码
整体来说代码还是比较浅显易懂的。主要的作用是建立了一个线程,并且创立了消息队列,有来自己的looper,可以让我们在自己的线程中分发和处理消息。具体的使用示例,我会在下一帖中体现。还有要说明的是handler 与谁相关联不是看声明在什么地方,是看与哪个线程的looper挂钩。默认是主线程的looper.因为主线程中默认就有了looper,消息循环队列。
每天进步一点点之AsyncQueryHandler学习
AsyncQueryHandler:异步的查询操作帮助类,其实它同样可以处理增删改
1。AsyncQueryHandler的作用
查询其API便可知,它担供:
startInsert
startDelete
startUpdate
startQuery
onXXXComplete方法,以供操作完数据库后进行其它的操作,这四个onXXXComplete方法都是空实现,以便我们只需要去实现我们关注的操作。
2。为什么要使用AsyncQueryHandler
当然你也可以使用ContentProvider去操作数据库。
这在数据量很小的时候是没有问题的,但是如果数据量大了,可能导致UI线程发生ANR事件。
当然你也可以写个Handler去做这些操作,只是你每次使用ContentProvider时都要再写个Handler,必然降低了效率。
因此API提供了一个操作数据库的通用方法。
3。如何使用AsyncQueryHandler
onXXXComplete方法的实现(可以实现任何一个或多个,当然你也可以一个也不实现,如果你不关注操作数据库的結果),在你的实现中做一些对数据库操作完成的处理。
使用时直接调用startXXX方法即可。传入的通用参数如下:
onXXXComplete方法
Object cookie,你想传给onXXXComplete方法使用的一个对象。(没有的话传递null即可。基本发现这个变量没太大作用)
Uri uri,(不解释)
4。AsyncQueryHandler还为我们做了什么
AsyncQueryHandler中使用了一个WeakReference<ContentResolver>对象,即ContentResolver的弱引用 作用:当contentProvied发生变化时候同步更新仍可以通过使用AsyncQueryHandler类来达到这一要求(暂时还没理解这个作用)
同时,在它执行操作数据库时,吃掉了所有的异常。见如下代码。
catch (Exception e) {
Log.w(TAG, e.toString());
cursor = null;
}