package cn.com.src;
import cn.com.chenzheng_java.utils.R;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class HanlderMessageTest extends Activity implements OnClickListener{
Button button ;
MyHandler handler ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button = (Button) this.findViewById(R.id.button1);
button.setOnClickListener(this);
}
// 聲明自己的handler
private class MyHandler extends Handler{
public MyHandler() {
super();
}
public MyHandler(Looper looper){
super(looper);
}
// 處理具體的message,該方法由父類中進行繼承.
@Override
public void handleMessage(Message msg) {
int whatNumber = msg.what;
Bundle bundle = (Bundle)msg.obj;
Log.i("what", whatNumber+"");
Log.i("名稱", bundle.getString("name"));
Log.i("性別", bundle.getString("sex"));
Log.i("年齡", bundle.getString("age"));
super.handleMessage(msg);
}
}
// 我自定義的任務,一般都會實現Runnable
private class MyThread implements Runnable {
@Override
public void run() {
try {
Thread.sleep(6000);
Message message = Message.obtain(handler);
message.what = 10 ;
Bundle bundle = new Bundle();
bundle.putString("name", "chenzheng");
bundle.putString("sex", "純爺們");
bundle.putString("age", "生卒年不詳");
message.obj = bundle ;
Log.i("通知", "開始發message了哦");
Log.i("通知thread_id:", ""+Thread.currentThread().getId());
message.sendToTarget();
} catch (Exception e) {
Log.i("通知", "線程sleep時出錯了!");
e.printStackTrace();
}
}
}
@Override
public void onClick(View v) {
Log.i("通知thread_id:", ""+Thread.currentThread().getId());
// 創建一個包含Looper的線程,這裏如果沒有HandlerThread的調用,會直接將後邊的MyThread放到UI線程隊列
HandlerThread myHandlerThread = new HandlerThread("chenzheng_java");
// 啓動新線程
myHandlerThread.start();
// 將handler綁定到新線程
handler = new MyHandler(myHandlerThread.getLooper());
// 在新線程中執行任務
handler.post(new MyThread());
}
}
Android Handler實現原理
下面介紹最本質的多線程:hanlder和message機制:
爲何需要多線程:
在日常應用中,我們通常需要處理一些“後臺,用戶不可見”的操作,例如說,我們需要下載一個音樂,要是你的應用必須等用戶下載完成之後纔可以進行別的操作,那肯定讓用戶非常的不爽。這時候,我們通常的做法是,讓這些操作去後臺執行,然後等後臺執行完畢之後,再給用戶彈出相應的提示信息。這時候,我們就需要使用多線程機制,然後通過創建一個新的線程來執行這些操作。
明白了,實現需求,我們就準備着手實現了。但是,經過進一步的瞭解,我們悲劇的發現,android中的線程機制是,只能在UI線程中和用戶進行交互。當我們創建了一個新線程,執行了一些後臺操作,執行完成之後,我們想要給用戶彈出對話框以確認,但是卻悲劇的發現,我們根本無法返回UI主線程了。
(說明:何爲UI線程:UI線程就是你當前看到的這些交互界面所屬的線程)。
這時候,我們如果想要實現這些功能,我們就需要一個android爲我們提供的handler和message機制。
先講解下編程機制:
我們通常在UI線程中創建一個handler,handler相當於一個處理器,它主要負責處理和綁定到該handler的線程中的message。每一個handler都必須關聯一個looper,並且兩者是一一對應的,注意,這點很重要哦!此外,looper負責從其內部的messageQueue中拿出一個個的message給handler進行處理。因爲我們這裏handler是在UI線程中實現的,所以經過這麼一個handler、message機制,我們就可以回到UI線程中了。
何爲handler:處理後臺進程返回數據的工作人員。
何爲message:後臺進程返回的數據,裏面可以存儲bundle等數據格式
何爲messageQueue:是線程對應looper的一部分,負責存儲從後臺進程中拋回的和當前handler綁定的message,是一個隊列。
何爲looper:looper相當於一個messageQueue的管理人員,它會不停的循環的遍歷隊列,然後將符合條件的message一個個的拿出來交給handler進行處理。
注意,handler是在UI線程中聲明的,如果我們直接用類似代碼執行一個線程的話,實際上並沒有創建一個新的線程,因爲handler已經跟默認的UI線程中的looper綁定了。
如果有興趣的話,可以去看下Handler的默認空構造函數便知道原因了,裏面直接綁定了當前UI線程的looper。
下面給出一個比較簡單,並且實用的實例。
源碼打印?
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.