Android:Handler

2019-02-10  本文已影响60人  春暖花已开

术语

Looper

每一个线程只有一个Looper,每个线程在初始化Looper之后,然后Looper会维护好该线程的消息队列,用来存放Handler发送的Message,并处理消息队列出队的Message。它的特点是它跟它的线程是绑定的,处理消息也是在Looper所在的线程去处理,所以当我们在主线程创建Handler时,它就会跟主线程唯一的Looper绑定,从而我们使用Handler在子线程发消息时,最终也是在主线程处理,达到了异步的效果。

在主线程中,ActivityThread默认会把Looper初始化好,prepare以后,当前线程就会变成一个Looper线程。

MessageQueue

MessageQueue是一个消息队列,用来存放Handler发送的消息。每个线程最多只有一个MessageQueue。MessageQueue通常都是由Looper来管理,而主线程创建时,会创建一个默认的Looper对象,而Looper对象的创建,将自动创建一个MessageQueue。其他非主线程,不会自动创建Looper。

Message

消息对象,就是MessageQueue里面存放的对象,一个MessageQueu可以包括多个Message。当我们需要发送一个Message时,我们一般不建议使用new Message()的形式来创建,更推荐使用Message.obtain()来获取Message实例,因为在Message类里面定义了一个消息池,当消息池里存在未使用的消息时,便返回,如果没有未使用的消息,则通过new的方式创建返回,所以使用Message.obtain()的方式来获取实例可以大大减少当有大量Message对象而产生的垃圾回收问题。


示例:

HandlerActivity

import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
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;

import com.tencent.testand.R;

import java.lang.ref.WeakReference;

public class HandlerActivity extends AppCompatActivity implements View.OnClickListener {

    private Button mSendMsgButton;
    private TextView mShowMsgTextView;
    private MessageHandler mMessageHandler = new MessageHandler(this);

    private static final int MESSAGE_CODE = 999999;

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

        mSendMsgButton = findViewById(R.id.send_message_btn);
        mSendMsgButton.setOnClickListener(this);

        mShowMsgTextView = findViewById(R.id.show_msg_tv);

        // 获取包信息
        getAppInfo();

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 销毁handler
        mMessageHandler.removeCallbacksAndMessages(null);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.send_message_btn: {

                startCountdown();
                break;
            }
        }
    }

    /**
     * 获取App信息
     */
    private void getAppInfo() {

        try {
            PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
            mShowMsgTextView.setText(packageInfo.packageName + packageInfo.versionName);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }

    }

    /**
     * 倒计时
     */
    private void startCountdown() {
        Message msg = mMessageHandler.obtainMessage();
        msg.obj = 20000;
        msg.what = MESSAGE_CODE;

        mMessageHandler.sendMessageDelayed(msg, 1000);
    }


    // Getter
    public TextView getShowMsgTextView() {
        return mShowMsgTextView;
    }

    /**
     * 内部类
     */
    public static class MessageHandler extends Handler {

        public final WeakReference<HandlerActivity> mActivityWeakReference;

        public MessageHandler(HandlerActivity activity) {
            mActivityWeakReference = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            HandlerActivity handlerActivity = mActivityWeakReference.get();

            switch (msg.what) {
                case MESSAGE_CODE: {
                    int value = (int) msg.obj;
                    handlerActivity.getShowMsgTextView().setText(String.valueOf(value/1000));

                    msg = Message.obtain();
                    msg.what = MESSAGE_CODE;
                    msg.obj = value - 1000;

                    if (value > 0) {
                        sendMessageDelayed(msg, 1000);
                    }
                }
            }
        }
    }
}

注:由于布局只是一个简单的TextView,这里不再给出代码。

术语部分参考在CSDN

上一篇下一篇

猜你喜欢

热点阅读