Android-Handler總結

Handler的定義

主要接受子線程發送的數據, 並用此數據配合主線程更新UI。 在平時的安卓開發過程中,Handler一定不少見,Handler是Android消息機制的上層接口,這使得在開發過程中只需要和Handler交互即可。很多人認爲Handler的作用就是更新UI,的確沒錯,但是更新UI僅僅是Handler的一個特殊的使用場景。

爲什麼要使用Handler

我們有時候需要在子線程做一些耗時操作,比如說訪問網絡或者耗時的I/O操作,當這些耗時操作完成時,程序的UI進行相應的改變。由於安卓開發規範的限制,我們不能在子線程中訪問UI控件,因爲UI的控件是線程非安全的,這個時候通過Handler就可以將更新UI的操作切換到主線程中執行

Looper的介紹

Looper我們稱爲循環器,它是連接Message Queue和Handler之間橋樑的角色。
它的作用是不斷的接受Message Queue的Message,然後派發給相應的Handler。

Looper中存放有MessageQueen,MessageQueen中又有很多Message,當我們的Handler發送消息的時候,會獲取當前的Looper,並在當前的Looper的MessageQueen當中存放我們發送的消息,而我們的MessageQueen也會在Looper的帶動下,一直循環的讀取Message信息,並將Message信息發送給Handler,並執行HandlerMessage()方法

MessageQueue

Message Queue(消息隊列):
定義:採用單鏈表的數據結構來存儲消息列表
作用:存放通過Handler發過來的Message,按照先進先出執行
- 怎麼在代碼中用Handler

下面我們可以通過代碼來看一下Handler

package com.example.dfcn.sexmouth;

import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class DownlondActivity extends AppCompatActivity {
private TextView downlond_tv;
private Button downlond_btn;
//創建Handler對象
private Handler handler=new Handler(){
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        String data= (String) msg.obj;//接受數據
        downlond_tv.setText(data);//接受消息完成操作
    }
};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_downlond);
        downlond_btn=findViewById(R.id.downlond_btn);
        downlond_tv=findViewById(R.id.downlond_tv);

        downlond_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(5000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        handler.sendEmptyMessage(1);//發送消息
                        Message msg = new Message();
                        msg.obj = "網絡數據";//可以是基本類型,可以是對象,可以是List、map等;
                        handler.sendMessage(msg);//發送

                    }
                }).start();

            }
        });



    }
}

- 案列解析-簡單的倒計時操作

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.dfcn.sexmouth.TimeActivity">
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="50dp"
    >
    <TextView
        android:gravity="center_vertical"
        android:text="請輸入:"
        android:layout_width="50dp"
        android:layout_height="50dp" />
    <EditText
        android:id="@+id/settime_et"
        android:gravity="center_vertical"
        android:layout_width="30dp"
        android:layout_height="50dp" />
    <TextView
        android:gravity="center_vertical"
        android:text="秒"
        android:layout_width="50dp"
        android:layout_height="50dp" />
</LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="horizontal">
        <TextView
            android:gravity="center"
            android:text="倒計時:"
            android:layout_width="60dp"
            android:layout_height="50dp" />
  <TextView
android:id="@+id/time_tv"
android:text="準備"
android:layout_width="match_parent"
android:layout_height="50dp" />
    </LinearLayout>
<Button
android:id="@+id/time_btn"
android:text="開始計時"
android:layout_width="match_parent"
android:layout_height="50dp" />
    </LinearLayout>
package com.example.dfcn.sexmouth;

import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class TimeActivity extends AppCompatActivity {
private EditText time_et;
private TextView time_tv;
private Button time_btn;
private int time;

private Handler handler=new Handler(){
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        //判斷what碼
        switch (msg.what){
            case 1:
                time_tv.setText(time+"");
                break;
            case 2:
                time_tv.setText("計時完畢");
                break;
            default:
                break;
        }


    }
};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_time);

        bindID();
        time_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        String s=time_et.getText().toString();//得到輸入的秒數
                     //將string類型的s轉換爲int
                        time=Integer.parseInt(s);
                        while (time>0){
                            try {
                                Thread.sleep(1000);//每隔一秒time-1
                                time--;
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            //當time爲0的時候我們傳送“what”碼2
                            if (time==0){
                                handler.sendEmptyMessage(2); 
                            }
                            //當time不爲0時我們傳送“what”碼1
                            else if (time!=0){
                                handler.sendEmptyMessage(1);
                            }

                        }



                        }

                }).start();
            }
        });
    }
//初始化控件
    private void bindID() {
        time_btn=findViewById(R.id.time_btn);
        time_et=findViewById(R.id.settime_et);
        time_tv=findViewById(R.id.time_tv);
    }

}

效果圖:
這裏寫圖片描述
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章