HandlerThread,Handler,Thread使用方法


Handler會關聯一個單獨的線程和消息隊列。Handler默認關聯主線程,雖然要提供Runnable參數 ,但默認是直接調用Runnable中的run()方法。也就是默認下會在主線程執行,如果在這里面的操作會有阻塞,界面也會卡住。如果要在其他線程執行,可以使用HandlerThread。

HandlerThread的使用                                                                                                      

//Handler handler = new Handler() {
//...
//}
HandlerThread uIhandlerThread = new HandlerThread("update");
uIhandlerThread.start();
//Handler UIhandler = new Handler(uIhandlerThread.getLooper());
Handler uIhandler = new Handler(uIhandlerThread.getLooper(),new Callback() {
    public boolean handleMessage(Message msg) {
        Bundle b = msg.getData();  
        int age = b.getInt("age");  
        String name = b.getString("name");  
        System.out.println("age is " + age + ", name is" + name);  
        System.out.println("Handler--->" + Thread.currentThread().getId());  
        System.out.println("handlerMessage");  
        return true;  
     }
});

當要停止uIhandlerThread執行時用:

if(uIhandlerThread!=null) {
    pointThread.quit();
}

Handler的使用                                                                                                                    
目前常使用的有兩種用法,
一種是自定義Handler,在handleMessage進行事件的處理, 這個Message可以是在其他線程中send的,或者在主線程中send。
在線程中發送信息到主進程:
1.定義handler

public class MyHandler extends Handler {
      @Override
      public boolean handleMessage(Message msg) {
        switch (msg.what){
           case 1 :
                   ....
          }
      }
  }
  MyHandler myHandler = new MyHandler();

或者

Handler myHandler = new Handler(new Callback(){
     // 參數也可以為(this.getMainLooper(),new Callback(){})不寫則默認為主進程的Looper
    @Override
    public boolean handleMessage(Message msg) {
        // TODO Auto-generated method stub
        return false;
    }
  });

2.新建一個線程

Thread sender = new Thread(){
      @Override
      public void run() {
      ....
      myHandler.obtainMessage( inWhat , inA , inB , inToken );
      myHandler.sendMessage( inMessage );
      //myHandler.sendEmptyMessage( inWhat );
      }
  }
  sender.start();

在主線程中發信息到handler
  直接在主進程,不在線程中mHandler.sendMessage( inMessage );
另一種為post一個線程進去,執行線程。直到線程退出或者是handler被removeCallbacks。
定義一個線程Tread名為sender(不重復了)。
然后執行,myHandler.post(sender);
這樣線程就在handler中執行。如果要停止線程的話:

if(myHandler!=null) {
    myHandler.removeCallbacks(senderObj);
}

也可用一個Runnable來代替Thread

Runnable r = new Runnable() {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        
    }
    
};
myHandler.post(r);

以上兩種,是否使用handler的post來啟動,差別在與是否開啟新線程來執行處理。使用post方法時,直接調用Thread或Runnable的run方法,所有處理都在主線程中進行,並沒有開啟定義的Thread或Runnable新的線程!!

==============================================================================================
關於Thread和Runnable的區別
參考網址:http://www.360doc.com/content/10/1219/22/573136_79607619.shtml
Thread和Runnable是實現java多線程的兩種方式,Thread是類,Runnable為接口,建議使用Runnable來實現多線程。
如果讓一個線程實現Runnable接口,那么當調用這個線程的對象開啟多個線程時,可以讓這些線程調用同一個變量;
若這個線程是由繼承Thread類而來,則要通過內部類來實現上述的功能,利用的就是內部類可任意訪問外部類變量這個特性。(精辟!!)
例子程序:

public class ThreadTest
{
public static void main(String[] args)
{
   MyThread mt=new MyThread();
   new Thread(mt).start();     //通過實現Runnable的類的對象來開辟第一個線程
   new Thread(mt).start();     //通過實現Runnable的類的對象來開辟第二個線程
   new Thread(mt).start();     //通過實現Runnable的類的對象來開辟第三個線程
   //由於這三個線程是通過同一個對象mt開辟的,所以run()里方法訪問的是同一個index
}
}
class MyThread implements Runnable    //實現Runnable接口
{
int index=0;
public void run()
{
   for(;index<=200;)
    System.out.println(Thread.currentThread().getName()+":"+index++);
}
}

------------------------------------------------------

public class ThreadTest
{
public static void main(String[] args)
{
   MyThread mt=new MyThread();
   mt.getThread().start();       //通過返回內部類的對象來開辟第一個線程
   mt.getThread().start();      //通過返回內部類的對象來開辟第二個線程
   mt.getThread().start();      //通過返回內部類的對象來開辟第三個線程
   //由於這三個線程是通過同一個匿名對象來開辟的,所以run()里方法訪問的是同一個index
}
}
class MyThread
{
int index=0;
private class InnerClass extends Thread    //定義一個內部類,繼承Thread
{
   public void run()
   {
    for(;index<=200;)
     System.out.println(getName()+":"+index++);
   }
}
Thread getThread()     //這個函數的作用是返回InnerClass的一個匿名對象
{
   return new InnerClass();
}
}
// 這里有一個問題:如果內部類要訪問一個外部變量或方法,那么這個變量或方法必須定義為final,但為什么這里的變量index不用定義為final就可以被內部類訪問?

=============================================================================================
Thread的使用                                                                                                                          
線程的定義於執行

Thread sender = new Thread(){
    @Override
    public void run() {
    ....
    }
}
sender.start();

線程的停止

if (sender != null) {
    //sender.quit();
     sender.join(); // 執行完畢當前處理后停止線程
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM