Android線程通信


摘要

  andriod提供了 Handler 和 Looper 來滿足線程間的通信。例如一個子線程從網絡上下載了一副圖片,當它下載完成后會發送消息給主線程,這個消息是通過綁定在主線程的Handler來傳遞的。

 

正文

圖解:

代碼示例:

/**
 * @author allin.dev
 *         http://allin.cnblogs.com
 */
public class MainThread extends Activity
{
  
  private static final String TAG = "MainThread";
  private Handler mMainHandler, mChildHandler;
  private TextView info;
  private Button msgBtn;
  
  @Override
  public void onCreate( Bundle savedInstanceState )
  {
    super.onCreate( savedInstanceState );
    setContentView( R.layout.main );
    
    info = (TextView) findViewById( R.id.info );
    msgBtn = (Button) findViewById( R.id.msgBtn );
    
    mMainHandler = new Handler( )
    {
      
      @Override
      public void handleMessage( Message msg )
      {
        Log.i( TAG, "Got an incoming message from the child thread - "
            + (String) msg.obj );
        // 接收子線程的消息
        info.setText( (String) msg.obj );
      }
      
    };
    
    new ChildThread( ).start( );
    
    msgBtn.setOnClickListener( new OnClickListener( )
    {
      
      @Override
      public void onClick( View v )
      {
        
        if ( mChildHandler != null )
        {
          
          // 發送消息給子線程
          Message childMsg = mChildHandler.obtainMessage( );
          childMsg.obj = mMainHandler.getLooper( ).getThread( ).getName( )
              + " says Hello";
          mChildHandler.sendMessage( childMsg );
          
          Log.i( TAG, "Send a message to the child thread - "
              + (String) childMsg.obj );
          
        }
      }
    } );
    
  }
  
  public void onDestroy() {
      super.onDestroy();
    Log.i(TAG, "Stop looping the child thread's message queue");

    mChildHandler.getLooper().quit();
  }
  
  class ChildThread extends Thread
  {
    
    private static final String CHILD_TAG = "ChildThread";
    
    public void run( )
    {
      this.setName( "ChildThread" );
      
      // 初始化消息循環隊列,需要在Handler創建之前
      Looper.prepare( );
      
      mChildHandler = new Handler( )
      {
        @Override
        public void handleMessage( Message msg )
        {
          Log.i( CHILD_TAG, "Got an incoming message from the main thread - "
              + (String) msg.obj );
          
          try
          {
            
            // 在子線程中可以做一些耗時的工作
            sleep( 100 );
            
            Message toMain = mMainHandler.obtainMessage( );
            toMain.obj = "This is " + this.getLooper( ).getThread( ).getName( )
                + ".  Did you send me \"" + (String) msg.obj + "\"?";
            
            mMainHandler.sendMessage( toMain );
            
            Log.i( CHILD_TAG, "Send a message to the main thread - "
                + (String) toMain.obj );
            
          }
          catch ( InterruptedException e )
          {
            // TODO Auto-generated catch block
            e.printStackTrace( );
          }
        }
        
      };
      
      Log.i( CHILD_TAG, "Child handler is bound to - "
          + mChildHandler.getLooper( ).getThread( ).getName( ) );
      
      // 啟動子線程消息循環隊列
      Looper.loop( );
    }
  }
}

 ps:

使用HandlerThread的looper對象創建Handler,如果使用默認的構造方法,很有可能阻塞UI線程,參考http://www.cnblogs.com/ccdc/p/3837798.html。改進方案新開一個線程將主線程的handler使用新開線程的looper替代主線程looper,示意圖如下,

 

參考

shangdawei.android 線程間通信[2014-07-11](2013-03-26).http://www.cnblogs.com/shangdawei/archive/2013/03/26/2983217.html

 

 


免責聲明!

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



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