《android系统源代码情景分析》学习-第15章 Android应用线程的消息循环模型

1 三种消息循环模型

1.1 主线程消息循环

第12章最后,AMS请求Zygote创建应用程序进程后,会自动进入主线程的消息循环,也就是ActivityThread。

    //创建一个主线程消息循环
    Looper.prepareMainLooper();
    //创建一个ActivityThread实例 
    ActivityThread thread = new ActivityThread();
    thread.attach(false);
    //当前主线程进入到消息循环
    Looper.loop();

Looper.prepareMainLooper()方法只能在主线程中调用,而且只能被调用一次。所以我们写代码时不能调用这个方法,否则会出异常。这个方法会生成一个Looper对象mMainLoopeer,在其他的子线程中就可以通过 Looper.getMainLooper()获取mMainLopper,完成与主线程的界面更新。

1.2 与UI无关的子线程消息循环模型

子线程有两类,一种是不具有消息循环的子线程,这种是我们经常见到的Thread,一般不直接使用new Thread的方式来创建一个子线程,而是自定义一个Thread实现类,然后用这个实现类创建子线程,在重写的run()中实现业务逻辑。
这种子线程没有消息循环,run方法执行完毕线程就会结束。

另一种是具有消息循环的子线程,也就是与UI无关的子线程消息循环模型。
我们使用HandlerThread创建一个具有消息循环的子线程。HandlerThread继承自Thread.

1.2.2 消息循环的创建
public class HandlerThread extends Thread{
    private Looper mLooper;
    public HandlerThread(String name){
        super(name);
    }
    public void run(){
        Looper.prepare();
        synchronized(this){
            mLooper = Looper.myLooper();
        }
        Looper.loop();
    }
    public Looper getLopper(){
        return mLooper;
    }

    public boolean quit(){
        Looper looper = getLooper();
        if(looper!=null){
            looper.quit();
            return true;
        }
        return false;
    }
}

可以看到, run方法里面首先调用Looper.prepare()创建了一个消息循环,然后Looper.loop()使得当前线程进入消息循环。所以HandlerThread就有了消息循环。

1.2.2 HandlerThread的使用

首先创建一个HandlerThread

    HandlerThread handlerThread = new HandlerThread("handler thread");
    handlerThread.start();

定义一个实现了Runnable的类ThreadTask

public class ThreadTask implements Runnable{
    public ThreadTask(){
    }
    public void run(){
    }
}

新建一个ThreadTask实例
ThreadTask threadTask = new ThreadTask();

将threadTask封装成一个消息发送到消息队列

Handler handler = new Handler(handlerThread.getLooper());
handler.post(threadTask);

消息被处理时就会调用threadTask的run方法,执行自定义任务。
如果一直不往子线程消息队列发送消息,那么子线程就会进入睡眠等待状态。

退出子线程时,只需要

handlerThread.quit();

调用了looper.quit();

Message msg =Message.obtain();
mQueue.enqueueMessage(msg,0);

通过向线程的消息队列发送一个target为null的Message对象,线程就会退出消息循环,停止线程 。

1.3 与UI有关的子线程消息循环模型 AsyncTask

AysncTask的三个主要方法:doInBackground(),onProgressUpdate(),onPostExecute();
其中doInBackground()执行耗时操作,是在子线程运行,onProgressUpdate(),onPostExecute()都可以操作界面,是在主线程运行。

frameworks/base/core/java/android/os/AsyncTask.java

public abstract class AsyncTask<Params,Progress,Result>{}

未完,待续

猜你喜欢

转载自blog.csdn.net/u013034413/article/details/79286951
今日推荐