android基础知识02——线程安全4:HandlerThread

来源:互联网 发布:sql 查询最高分数的人 编辑:程序博客网 时间:2024/06/08 14:52

  android的UI操作不是线程安全的,同时也只有主线程才能够操作UI,同时主线程对于UI操作有一定的时间限制(最长5秒)。为了能够做一些比较耗时的操作(比如下载、打开大文件等),android提供了一些列机制。《android基础知识02——线程安全》系列文章就是参考了网上许多网友的文章后,整理出来的一个系列,介绍了主要的方法。分别如下:

         android基础知识02——线程安全1:定义及例子

        android基础知识02——线程安全2:handler、message、runnable

        android基础知识02——线程安全3:Message,MessageQueue,Handler,Looper

        android基础知识02——线程安全4:HandlerThread

        android基础知识02——线程安全5: AsyncTask

        

在前面介绍的线程安全中,为了操作主线程的UI,使用子线程进行处理。在android开发中,还可以使用另外两种方法进行处理:

        HandlerThread

        AsyncTask

        本文先介绍HandlerThread。

        HandlerThread继承于Thread,所以它本质就是个Thread。与普通Thread的差别就在于,它有个Looper成员变量。这个Looper其实就是对消息队列以及队列处理逻辑的封装,简单说就是 消息队列+消息循环。
        当我们需要一个工作者线程,而不是把它当作一次性消耗品,用过即废弃的话,就可以使用它。

         其使用方法为:

[java] view plaincopy
  1. public void onCreate(Bundle savedInstanceState) {  
  2.    
  3.         super.onCreate(savedInstanceState);  
  4.    
  5.    
  6.         HandlerThread hThread=new HandlerThread("myThread");  
  7.    
  8.         hThread.start();  
  9.   
  10.    
  11.         myhandler myhandler=new myhandler(hThread.getLooper());  
  12.    
  13.         Message msg=myhandler.obtainMessage();  
  14.    
  15.         msg.sendToTarget();//把 Message发送到目标对象,目标对象就是生成msg的目标对象。  
  16.    
  17.     }  
  18.    
  19. class myhandler extends Handler{  
  20.    
  21.     public myhandler(Looper looper){  
  22.    
  23.         super(looper);  
  24.    
  25.     }  
  26.    
  27.     public void handleMessage(Message msg) {  
  28.    
  29.         Log.e("这是新线程""》》》》》》》》》》》》》》》》》新线程的测试");  
  30.    
  31.     }  
  32.    
  33. }  
这里通过HandlerThread启动一个新线程。
注:这里需要handlerThread.start();先启动线程 才能 handlerThread.getLooper() 获取当前线程的Looper。

        HandlerThread使用是比较简单的,我们翻翻它的源码,也是很简单的。

[java] view plaincopy
  1. /** 
  2.  * Handy class for starting a new thread that has a looper. The looper can then be  
  3.  * used to create handler classes. Note that start() must still be called. 
  4.  */  
  5. public class HandlerThread extends Thread {  
  6.     private int mPriority;  
  7.     private int mTid = -1;  
  8.     private Looper mLooper;  
  9.   
  10.     public HandlerThread(String name) {  
  11.         super(name);  
  12.         mPriority = Process.THREAD_PRIORITY_DEFAULT;  
  13.     }  
  14.       
  15.     /** 
  16.      * Constructs a HandlerThread. 
  17.      * @param name 
  18.      * @param priority The priority to run the thread at. The value supplied must be from  
  19.      * {@link android.os.Process} and not from java.lang.Thread. 
  20.      */  
  21.     public HandlerThread(String name, int priority) {  
  22.         super(name);  
  23.         mPriority = priority;  
  24.     }  
  25.       
  26.     /** 
  27.      * Call back method that can be explicitly over ridden if needed to execute some 
  28.      * setup before Looper loops. 
  29.      */  
  30.     protected void onLooperPrepared() {  
  31.     }  
  32.   
  33.     public void run() {  
  34.         mTid = Process.myTid();  
  35.         Looper.prepare();  
  36.         synchronized (this) {  
  37.             mLooper = Looper.myLooper();  
  38.             Process.setThreadPriority(mPriority);  
  39.             notifyAll();  
  40.         }  
  41.         onLooperPrepared();  
  42.         Looper.loop();  
  43.         mTid = -1;  
  44.     }  
  45.       
  46.     /** 
  47.      * This method returns the Looper associated with this thread. If this thread not been started 
  48.      * or for any reason is isAlive() returns false, this method will return null. If this thread  
  49.      * has been started, this method will block until the looper has been initialized.   
  50.      * @return The looper. 
  51.      */  
  52.     public Looper getLooper() {  
  53.         if (!isAlive()) {  
  54.             return null;  
  55.         }  
  56.           
  57.         // If the thread has been started, wait until the looper has been created.  
  58.         synchronized (this) {  
  59.             while (isAlive() && mLooper == null) {  
  60.                 try {  
  61.                     wait();  
  62.                 } catch (InterruptedException e) {  
  63.                 }  
  64.             }  
  65.         }  
  66.         return mLooper;  
  67.     }  
  68.       
  69.     /** 
  70.      * Ask the currently running looper to quit.  If the thread has not 
  71.      * been started or has finished (that is if {@link #getLooper} returns 
  72.      * null), then false is returned.  Otherwise the looper is asked to 
  73.      * quit and true is returned. 
  74.      */  
  75.     public boolean quit() {  
  76.         Looper looper = getLooper();  
  77.         if (looper != null) {  
  78.             looper.quit();  
  79.             return true;  
  80.         }  
  81.         return false;  
  82.     }  
  83.       
  84.     /** 
  85.      * Returns the identifier of this thread. See Process.myTid(). 
  86.      */  
  87.     public int getThreadId() {  
  88.         return mTid;  
  89.     }  
  90. }