handler

1.是啥?

Handler是一种异步消息分发机制。

因为子线程不能进行UI的更新,只有UI线程(即主线程)才可以进行UI的更新。所以需要Handler来接受子线程发送的数据,并用此线程配合主线程来更新UI。Handler可以完成主线程和子线程、子线程和子线程之间的通信。

2.怎么工作

使用Handler进行异步消息处理主要由以下四部分组成:

(1)Message,线程之间传递的消息,用于不同线程之间的数据交互。Message中的what字段用来标记区分多个消息,arg1、arg2 字段用来传递int类型的数据,obj可以传递任意类型的字段。

(2)Handler,用于发送和处理消息。其中的sendMessage()用来发送消息,handleMessage()用于消息处理,进行相应的UI操作。

(3)MessageQueue,消息队列(先进先出),用于存放Handler发送的消息,一个线程只有一个消息队列。

(4)Looper,可以理解为消息队列的管理者,当发现MessageQueue中存在消息,Looper就会将消息传递到handleMessage()方法中,同样,一个线程只有一个Looper。

 

Message可以携带的数据:

//通常作标志位,作区分
message.what;(int)

//携带简单数据
message.arg1;(int)
message.arg2;(int)

//携带object数据类型
message.obj;(object)

3.代码

package com.example.demolist;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

import static com.example.demolist.R.layout.activity_main;


public class MainActivity extends AppCompatActivity {
    public static final int UPDATE =0x1;
    private TextView textView;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(activity_main);
        textView = findViewById(R.id.tv);
        begin();

    }

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(@NonNull Message msg) {
            switch (msg.what){
                case UPDATE:
                    textView.setText(String.valueOf(msg.arg1));
                    break;
            }
        }
    };

    public void begin(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i=5;i>0;i--){
                    Message msg = new Message();
                    msg.what = UPDATE;
                    msg.arg1 = i;
                    handler.sendMessage(msg);
                    try {
                        Thread.sleep(1000);//休眠1秒
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    //打印log
                    Log.i("tag",MainActivity.this+"-"+ i);
                }
                //计时结束后跳转到其他界面
                startActivity(new Intent(MainActivity.this,Main2Activity.class));
                //添加finish方法在任务栈中销毁倒计时界面,使新开界面在回退时直接退出而不是再次返回该界面
                finish();
            }
        }).start();
    }
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main2"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >
    <TextView
        android:gravity="center"
        android:textSize="30sp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="NO DATA"
        android:id="@+id/tv"/>
</LinearLayout>

3.主线程向子线程发送消息

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";
    private static final int SEND_MESSAGE = 10;

    private Handler mHandler;

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

        new Thread(new MyRunnable()).start();

        findViewById(R.id.send_btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Message msg = Message.obtain();
                msg.what = SEND_MESSAGE;
                msg.obj = "主线程向子线程发送新的消息啦";
                mHandler.sendMessage(msg);
            }
        });
    }

    private class MyRunnable implements Runnable {
        @Override
        public void run() {
            //建立消息循环的步骤
            Looper.prepare();//1、初始化Looper
            mHandler = new Handler() {//2、绑定handler到CustomThread实例的Looper对象
                public void handleMessage(Message msg) {//3、定义处理消息的方法
                    if (msg.what == SEND_MESSAGE) {
                        Log.i(TAG, "handleMessage:---->" + msg.obj);
                    }
                }
            };
            Looper.loop();//4、启动消息循环
        }
    }
}

4.子线程向主线程发送消息

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    public static final int UPDATE_TEXT = 1;
    private TextView textView;
    private Button button;
    private HandlerTest handlerTest;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView=findViewById(R.id.text_view);
        button=findViewById(R.id.button);
        handlerTest=new HandlerTest();
        button.setOnClickListener(this);
    }
    private class HandlerTest extends android.os.Handler {
        @Override
        public void handleMessage(@NonNull Message msg) {
            if(msg.what==UPDATE_TEXT){
                textView.setText(String.valueOf(msg.obj));
            }
        }
    }

    @Override
    public void onClick(View view) {
        switch(view.getId()){
            case R.id.button:
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        Message message=new Message();
                        message.obj="来自子线程的消息";
                        message.what=UPDATE_TEXT;
                        handlerTest.sendMessage(message);
                    }
                }).start();
            default:
                break;
        }
    }
}

5.内存泄漏问题

https://www.jianshu.com/p/ed9e15eff47a 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值