Handler的基本使用

EltDKBE 8年前發布 | 10K 次閱讀 Java開發

來自: http://my.oschina.net/u/2542711/blog/613931


一、Handler的定義:

主要接受子線程發送的數據, 并用此數據配合主線程更新UI。

解釋:當應用程序啟動時,Android首先會開啟一個主線程 (也就是UI線程) , 主線程為管理界面中的UI控件, 進行事件分發, 比如說, 你要是點擊一個 Button ,Android會分發事件到Button上,來響應你的操作。  如果此時需要一個耗時的操作,例如: 聯網讀取數據,    或者讀取本地較大的一個文件的時候,你不能把這些操作放在主線程中,如果你放在主線程中的話,界面會出現假死現象, 如果5秒鐘還沒有完成的話,會收到Android系統的一個錯誤提示  "強制關閉"。  這個時候我們需要把這些耗時的操作,放在一個子線程中,因為子線程涉及到UI更新,,Android主線程是線程不安全的, 也就是說,更新UI只能在主線程中更新,子線程中操作是危險的。 這個時候,Handler就出現了。,來解決這個復雜的問題 ,由于Handler運行在主線程中(UI線程中),  它與子線程可以通過Message對象來傳遞數據, 這個時候,Handler就承擔著接受子線程傳過來的(子線程用sedMessage()方法傳弟)Message對象,(里面包含數據)  , 把這些消息放入主線程隊列中,配合主線程進行更新UI。

 

 

 

 

========================

 

 

效果圖示例:

 

 

 

 

 

 

====================

 

 

//在主線程創建Handler方式

 

1、res/layout的activity_main.xml布局

 

代碼

 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical" >

 

    <TextView

        android:id="@+id/textview"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="" />

    

     <Button

        android:id="@+id/bt_sendMessage"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="發送消息"

        android:onClick="sendMessage" />

 

</LinearLayout>

 

 

 

=====================

 

 

2、MainActivity類

 

代碼

 

 

public class MainActivity extends Activity {

 

private TextView textview;

//創建一個Handler -- 負責處理子線程發送過來的Message

Handler handler = new Handler(){

//handleMessage方法用來接收子線程發送過來的消息

public void handleMessage(android.os.Message msg) {

//判斷要接收的數據

if(msg.what == 1){

textview.setText((String)msg.obj);

}

};

};

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

this.textview = (TextView) this.findViewById(R.id.textview);

}

public void sendMessage(View view){

//子線程

new Thread(new Runnable() {

@Override

public void run() {

//先獲取一個Message對象 使用Message.obtain拿對象(也可以new一個但是那樣效率比較低不建議)

Message message = Message.obtain();

//有了Message對象就可以利用該對象發送消息了

message.what = 1;//設置主線程接收消息的標識

message.obj = "這是子線程發送過來的消息";//要發送的數據

//發送消息

handler.sendMessage(message);

}

}).start();

}

}

 

 

 

 

 

=============================================

 

 

 

//在子線程創建Handler方式



效果圖示例:






//點擊發送消息 在子線程操作  然后主線程接受消息完把結果打印輸出在日志貓



//1、布局就一個按鈕

 

 

2、MainActivity類

 

代碼



public class MainActivity extends Activity {

 

private Handler handler;

 

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

new MyThread().start();

}

 

public void send(View view) {

// 獲取Meassage 對象

Message message = Message.obtain();

// 用Message對象來發送數據

message.what = 1;

message.obj = "這是我的子線程消息";

// new MyThread().start();

handler.sendMessage(message);

}

 

/**

* 默認情況下, Android創建的線程沒有開啟消息循環Looper,

* 但是主線程例外。 系統自動為主線程創建Looper對象, 開啟消息循環;

* 所以主線程中使用new來創建Handler對象。

* @author Administrator

*/

// 子線程 接收主線程發送過來的消息

class MyThread extends Thread {

@Override

public void run() {

// 1準備Looper -- 消息泵(用來抽取數據)

Looper.prepare();

// 2創建Handler -- 在子線程

handler = new Handler() {

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case 1:

Log.i("data", (String) msg.obj);

break;

}

}

};

// 3循環讀取MessageQueue數據

Looper.loop();

}

}

}


 本文由用戶 EltDKBE 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!