架构--探索Architecture Component之TaskExecutor

版权声明:转载请注明出处。 https://blog.csdn.net/rentee/article/details/82630236

万丈架构平地起,带你拆解Google Android Architecture Component(以下简称 Arch)系列之一。


此次解析比较简约且独立的部分,android.arch.core.executor包。让我们来学习下Google的TaskExecutor。


此包从属于android.arch.core:runtime 可以理解为acrh的基础工具集。


包下就三个类:
1.TaskExecutor
抽象类,基类,如下:

public abstract class TaskExecutor {

    public abstract void executeOnDiskIO(@NonNull Runnable runnable);

    public abstract void postToMainThread(@NonNull Runnable runnable);

    public void executeOnMainThread(@NonNull Runnable runnable) {
        if (isMainThread()) {
            runnable.run();
        } else {
            postToMainThread(runnable);
        }
    }

    public abstract boolean isMainThread();

}

提供四个方法,定义TaskExecutor的功能,即在主线程/IO线程执行任务。executeOnMainThread方法判定是否此方法执行是否已在主线程,如果在则直接执行,不在则post只主线程。


2.ArchTaskExecutor
继承自TaskExecutor 如下:

public class ArchTaskExecutor extends TaskExecutor {
    private static volatile ArchTaskExecutor sInstance;

    @NonNull
    private TaskExecutor mDelegate;

    @NonNull
    private TaskExecutor mDefaultTaskExecutor;

    @NonNull
    private static final Executor sMainThreadExecutor = new Executor() {
        @Override
        public void execute(Runnable command) {
            getInstance().postToMainThread(command);
        }
    };

    @NonNull
    private static final Executor sIOThreadExecutor = new Executor() {
        @Override
        public void execute(Runnable command) {
            getInstance().executeOnDiskIO(command);
        }
    };

    private ArchTaskExecutor() {
        mDefaultTaskExecutor = new DefaultTaskExecutor();
        mDelegate = mDefaultTaskExecutor;
    }

    public static ArchTaskExecutor getInstance() {
        if (sInstance != null) {
            return sInstance;
        }
        synchronized (ArchTaskExecutor.class) {
            if (sInstance == null) {
                sInstance = new ArchTaskExecutor();
            }
        }
        return sInstance;
    }

    public void setDelegate(@Nullable TaskExecutor taskExecutor) {
        mDelegate = taskExecutor == null ? mDefaultTaskExecutor : taskExecutor;
    }

    @Override
    public void executeOnDiskIO(Runnable runnable) {
        mDelegate.executeOnDiskIO(runnable);
    }

    @Override
    public void postToMainThread(Runnable runnable) {
        mDelegate.postToMainThread(runnable);
    }

    @NonNull
    public static Executor getMainThreadExecutor() {
        return sMainThreadExecutor;
    }

    @NonNull
    public static Executor getIOThreadExecutor() {
        return sIOThreadExecutor;
    }

    @Override
    public boolean isMainThread() {
        return mDelegate.isMainThread();
    }
}

实现了3个抽象方法,这里使用代理模式,实现后,执行全部转交给mDelegate,而此类也提供setDelegate的方法,允许client从外部提供一个TaskExecutor,这样设计的好处:
1.通过代理,实际的执行模型(如:DefaultTaskExecutor的ExecutorService)交给代理类实现,隐藏了实现细节
2.给client比较高的自由度,客户端可以定义自己的TaskExecutor,从而定义实际的执行模型及队列等,也有利于方法埋点等操作。

另外,通过getMainThreadExecutor与getMainThreadExecutor两个静态方法将sMainThreadExecutor与sIOThreadExecutor暴露给外部,而sMainThreadExecutor与sIOThreadExecutor相当于一个适配器,将ArchTaskExecutor的任务执行转换成标准的Executor,并未暴露mDelegate中的ExecutorService。


3.DefaultTaskExecutor
也继承自TaskExecutor,如下:

public class DefaultTaskExecutor extends TaskExecutor {
    private final Object mLock = new Object();
    private ExecutorService mDiskIO = Executors.newFixedThreadPool(2);

    @Nullable
    private volatile Handler mMainHandler;

    @Override
    public void executeOnDiskIO(Runnable runnable) {
        mDiskIO.execute(runnable);
    }

    @Override
    public void postToMainThread(Runnable runnable) {
        if (mMainHandler == null) {
            synchronized (mLock) {
                if (mMainHandler == null) {
                    mMainHandler = new Handler(Looper.getMainLooper());
                }
            }
        }
        //noinspection ConstantConditions
        mMainHandler.post(runnable);
    }

    @Override
    public boolean isMainThread() {
        return Looper.getMainLooper().getThread() == Thread.currentThread();
    }
}

ArchTaskExecutor的默认代理类,当client没有手动设置delegate时,使用其执行任务。
使用了newFixedThreadPool的线程池模型。 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。源码设定最大并发数是2。
postToMainThread时,mMainHandler初始化使用了双重效验锁。


总结:
1.整个包非常独立,如果你自己想实现一个Task Executor,完全可以仿照实现,并丰富功能。

猜你喜欢

转载自blog.csdn.net/rentee/article/details/82630236