1. 程式人生 > >Android--利用Handler訊息轉發機制實現倒計時(內含防止記憶體洩露處理)

Android--利用Handler訊息轉發機制實現倒計時(內含防止記憶體洩露處理)

真正學會Handler必須要了解的相關概念

相關概念圖示:

這裡寫圖片描述

Message:儲存資訊的物件,被Handler線上程間轉發,實現執行緒間的通訊。
MessageQueue:以有序的方式排列的,等待處理的事件(Runnable或者Message)。
Handler:本質上是生成了訊息佇列,供Lopper抽取。
Lopper:類似水泵,從MessageQueue抽取Runnable或者Message。
handlerMessage:子執行緒接收訊息必須重寫的方法。

Handler:

android.os 下的一個類:這個類能方便的開啟一個包含looper的執行緒

主要作用:

1.建立定時任務。
2.實現執行緒間的通訊。

Handler原始碼中使用java.lang.ThreadLocal 中的以下兩個方法保證主執行緒中只有一個Looper

1.void set(Object value)設定當前執行緒的執行緒區域性變數的值。
2.public Object get()該方法返回當前執行緒所對應的執行緒區域性變數。

1.Handler常用API

這裡寫圖片描述

Handler例項

子類需要繼承Hendler類,並重寫handleMessage(Message msg) 方法, 用於接收其他執行緒傳送的資料。

在子執行緒中例項化Handler

方法1

Looper.prepare();
Handler handler = new Handler();
Looper.loop();

方法2

Handler handler = new Handler(Looper.getMainLooper());

主執行緒例項化Handler:new Handler()

應用案例- - -

利用Handler訊息轉發機制實現倒計時(內含防止記憶體洩露處理)

涉及到的知識點:

1.Handler常用API

2.WeakReference:主執行緒上下文物件的弱引用

post類方法允許你排列一個Runnable物件到主執行緒佇列中,

sendMessage類方法, 允許你安排一個帶資料的Message物件到佇列中,等待更新。

程式碼實現:

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

import java.lang.ref.WeakReference;

public class MainActivity extends AppCompatActivity {

    /**
     * 倒計時標記handle code
     */
    public  static  final  int COUNTDOWN_TIME_CODE = 100001;
    /**
     * 倒計時間隔
     */
    public  static  final  int  DELAY_MILLIS = 1000;
    /**
     * 倒計時最大值
     */
    public  static  final  int  MAX_COUNT = 10;


    private TextView mCountdownTimeTextView;


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

        //得到控制元件
        mCountdownTimeTextView= (TextView)findViewById(R.id.countdownTimeTextView);

        //建立了一個handler
        CountdownTimeHandler handler = new CountdownTimeHandler(this);

        //新建了一個message
        Message message = Message.obtain();
        message.what = COUNTDOWN_TIME_CODE;
        message.arg1 = MAX_COUNT;

        //第一次傳送這個message
        handler.sendMessageDelayed(message,DELAY_MILLIS);

    }

    /*防止記憶體洩露,弱引用的方式獲取上下文
    * 多用於耗時執行緒中的操作*/
    public  static  class  CountdownTimeHandler extends Handler{
        static  final  int  MIN_COUNT = 0;
        final WeakReference<MainActivity> mWeakReference;

        CountdownTimeHandler(MainActivity activity){
            mWeakReference = new WeakReference (activity );
        }

        // 子類必須重寫此方法,接收資料 
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            //獲取MainActivity
            MainActivity activity =mWeakReference.get();

            switch (msg.what){
                case COUNTDOWN_TIME_CODE:
                    int value = msg.arg1;
                    activity.mCountdownTimeTextView.setText(String.valueOf(value --));

                    //迴圈發的訊息控制
                    if (value >= MIN_COUNT) {
                        /*這時需要新建Message物件*/
                        Message message = Message.obtain();
                        message.what = COUNTDOWN_TIME_CODE;
                        message.arg1 = value;
                        sendMessageDelayed(message, DELAY_MILLIS);
                    }

                    break;
            }
        }
    }
}

官方文件解析