android 主線程和子線程之間的消息傳遞


從主線程發送消息到子線程(准確地說應該是非UI線程)

  package  com.zhuozhuo;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;

public  class LooperThreadActivity  extends Activity{
     /**  Called when the activity is first created.  */
    
     private  final  int MSG_HELLO = 0;
     private Handler mHandler;
    
    @Override
     public  void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
         new CustomThread().start(); // 新建並啟動CustomThread實例
        
        findViewById(R.id.send_btn).setOnClickListener( new OnClickListener() {
            
            @Override
             public  void onClick(View v) { // 點擊界面時發送消息
                String str = "hello";
                Log.d("Test", "MainThread is ready to send msg:" + str);
                mHandler.obtainMessage(MSG_HELLO, str).sendToTarget(); // 發送消息到CustomThread實例
                
            }
        });
        
    }
    
    
    
    
    
     class CustomThread  extends Thread {
        @Override
         public  void run() {
             // 建立消息循環的步驟
            Looper.prepare(); // 1、初始化Looper
            mHandler =  new Handler(){ // 2、綁定handler到CustomThread實例的Looper對象
                 public  void handleMessage (Message msg) { // 3、定義處理消息的方法
                     switch(msg.what) {
                     case MSG_HELLO:
                        Log.d("Test", "CustomThread receive msg:" + (String) msg.obj);
                    }
                }
            };
            Looper.loop(); // 4、啟動消息循環
        }
    }
}

從非UI線程傳遞消息到UI線程(界面主線程),因為主界面已經有MessageQueue,所以可以直接獲取消息處理消息。而上面由主線程向非UI線程中處理消息的時候,非UI線程需要先添加消息隊列,然后處理消息循環。

public  class ThreadHandlerActivity  extends Activity {
     /**  Called when the activity is first created.  */
    
     private  static  final  int MSG_SUCCESS = 0; // 獲取圖片成功的標識
     private  static  final  int MSG_FAILURE = 1; // 獲取圖片失敗的標識
    
     private ImageView mImageView;
     private Button mButton;
    
     private Thread mThread;
    
     private Handler mHandler =  new Handler() {
         public  void handleMessage (Message msg) { // 此方法在ui線程運行
             switch(msg.what) {
             case MSG_SUCCESS:
                mImageView.setImageBitmap((Bitmap) msg.obj); // imageview顯示從網絡獲取到的logo
                Toast.makeText(getApplication(), getApplication().getString(R.string.get_pic_success), Toast.LENGTH_LONG).show();
                 break;

             case MSG_FAILURE:
                Toast.makeText(getApplication(), getApplication().getString(R.string.get_pic_failure), Toast.LENGTH_LONG).show();
                 break;
            }
        }
    };
    
    @Override
     public  void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mImageView= (ImageView) findViewById(R.id.imageView); // 顯示圖片的ImageView
        mButton = (Button) findViewById(R.id.button);
        mButton.setOnClickListener( new OnClickListener() {
            
            @Override
             public  void onClick(View v) {
                 if(mThread ==  null) {
                    mThread =  new Thread(runnable);
                    mThread.start(); // 線程啟動
                }
                 else {
                    Toast.makeText(getApplication(), getApplication().getString(R.string.thread_started), Toast.LENGTH_LONG).show();
                }
            }
        });
    }
    
    Runnable runnable =  new Runnable() {
        
        @Override
         public  void run() { // run()在新的線程中運行
            HttpClient hc =  new DefaultHttpClient();
            HttpGet hg =  new HttpGet("http://csdnimg.cn/www/images/csdnindex_logo.gif"); // 獲取csdn的logo
             final Bitmap bm;
             try {
                HttpResponse hr = hc.execute(hg);
                bm = BitmapFactory.decodeStream(hr.getEntity().getContent());
            }  catch (Exception e) {
                mHandler.obtainMessage(MSG_FAILURE).sendToTarget(); // 獲取圖片失敗
                 return;
            }
            mHandler.obtainMessage(MSG_SUCCESS,bm).sendToTarget(); // 獲取圖片成功,向ui線程發送MSG_SUCCESS標識和bitmap對象

//             mImageView.setImageBitmap(bm);  // 出錯!不能在非ui線程操作ui元素

//             mImageView.post(new Runnable() { // 另外一種更簡潔的發送消息給ui線程的方法。
//                 
//                 @Override
//                 public void run() { // run()方法會在ui線程執行
//                     mImageView.setImageBitmap(bm);
//                 }
//             });
        }
    };
    

} 


免責聲明!

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



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