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

原文地址:https://www.cnblogs.com/ccdc/p/3837883.html