天天看点

【第一行代码】AndroidThreadTest

简介

创建子线程,使用 handler 和 message 更新 UI 界面

Android 定义并启动线程的方法

继承 Thread 类

class MyThread extends Thread {
    @Override
    public void run() {
        //处理逻辑
    }
}

//启动
new MyThread().start();
           

实现 Runnable 接口

class MyThread implements Runnable {
    @Override
    public void run() {
        //处理逻辑
    }
}

//启动
MyThread myThread = new MyThread();
new Thread(myThread).start();
           

使用匿名类实现 Runnable 接口

new Thread(new Runnable() {
    @Override
    public void run() {
        //处理逻辑
    }
}).start();
           

在子线程中更新 UI

使用 runOnUiThread

是一个异步消息处理机制的接口封装。

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        text.setText("Nice to meet you 111");
    }
});
           

利用异步消息处理

public static final int UPDATE_TEXT = 1;
private Handler handler = new Handler(new Handler.Callback() {
    @Override
    public boolean handleMessage(@NonNull Message message) {
        if(message.what == UPDATE_TEXT) {
            text.setText("Nice to meet you");
        }
        return false;
    }
});
new Thread(new Runnable() {
    @Override
    public void run() {
        Message message = new Message();
        message.what = UPDATE_TEXT;
        handler.sendMessage(message);
    }
}).start();
           

异步处理机制解析

Android 异步消息处理由四个部分组成:Message、Handler、MessageQueue 和 Looper。

Message

线程之间传递的信息,可携带少量的信息,用于在不同线程之间交换数据;

message 可以携带 what 的 int 数据,除此之外 arg1 和 arg2 也可以携带 int 数据,obj 携带一个 Object 对象。

Handler

用于发送和处理消息。发送消息使用 handler 的 sendMessage 方法;处理消息在 handleMessage 方法中。

MessageQueue

主要存放所有通过 Handler 发送的消息,这部分消息一直存在于消息队列中,等待被处理。

每个线程只有一个 MessageQueue 对象。

Looper

是 MessageQueue 的管家;

调用 Looper 的 loop 方法后,就会进入到一个无限循环当中,每当发现 MessageQueue 存在一条消息,就会将它取出来传递到 Handler 的 handleMessage 方法中。

每个线程中也只有一个 Looper 对象。

AsyncTask

Android 封装的异步消息处理从子线程切换到主线程。

class UpdateTextTask extends AsyncTask<Void, Integer, Boolean> {
    //在后台任务开始执行之前调用,做界面上的初始化操作
    @Override
    protected void onPreExecute() {
        text.setText("start");
    }

    //在子线程中运行,通过 return 返回结果,调用 publishProgress 方法更新 UI
    @Override
    protected Boolean doInBackground(Void... voids) {
        int count = 0;
        while(count != 20) {
            publishProgress(++count);
            Log.d(TAG, "doInBackground: " + count);
            try {
                Thread.sleep(1000);
            }catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
        return true;
    }

    //publishProgress 调用最终会到这个函数里,在这里对 UI 进行操作。
    @Override
    protected void onProgressUpdate(Integer... values) {
        Log.d(TAG, "onProgressUpdate() called with: values = [" + values[0] + "]");
        text.setText(""+values[0]);
    }

    //当后台任务执行完毕并 return 返回是会被调用,可以进行 UI 操作。
    @Override
    protected void onPostExecute(Boolean aBoolean) {
        text.setText("end");
    }
}
           

项目源码下载

Github