Startup设计与实现(startup简介)
设计
任务的分类
主线程,阻塞
主线程,非阻塞(不常用)
子线程,阻塞(很少见)
子线程,非阻塞
这里阻塞的含义是指在application的onCreate方法里完成。
任务的分类有点多,有必要精简吗
前序任务
不管什么类型的任务,都可以有后序任务
只有一个例外,就是主线程,非阻塞
的任务,不能有阻塞
的后序任务。
任务的优先级
不管是主线程还是子线程,优先级高的先执行
多进程
任意任务可以在任意进程执行
实现
定义接口 Task
public interface Task extends Runnable { /** * @return 前序任务 */ List<Class<? extends Task>> dependencies(); /** * @return 是否主线程 */ boolean isMainThread(); /** * @return 是否阻塞 */ boolean isBlocking(); /** * @return 优先级,数值越大,优先级越高 */ int priority(); /** * @return 是否主进程 */ boolean isMainProcess(); /** * @return 进程列表 */ Set<String> processes(); } 复制代码
RealTask
public class RealTask extends AtomicInteger implements Task, Comparable<RealTask> { static final int START = 0; static final int RUNNING = 1; static final int COMPLETE = 2; final Context mContext; /** * task运行状态 */ AtomicInteger state; /** * 原始任务 */ final Task source; /** * 后序任务 */ final List<RealTask> nextList; public RealTask(Context context, Task task) { mContext = context; this.source = task; nextList = new ArrayList<>(); state = new AtomicInteger(); } @Override public List<Class<? extends Task>> dependencies() { return source.dependencies(); } @Override public boolean isMainThread() { return source.isMainThread(); } @Override public boolean isBlocking() { return source.isBlocking(); } @Override public int priority() { return source.priority(); } @Override public boolean isMainProcess() { return source.isMainProcess(); } @Override public Set<String> processes() { Set<String> processes = source.processes(); if (processes == null) { processes = new HashSet<>(); } return processes; } @Override public int compareTo(RealTask o) { if (isMainThread()) { if (o.isMainThread()) { return o.priority() - priority(); } else { return 1; } } else { if (o.isMainThread()) { return -1; } else { return o.priority() - priority(); } } } @Override public void run() { state.set(RUNNING); long start = System.currentTimeMillis(); boolean shouldRun = shouldRun(); if (shouldRun) { source.run(); } long end = System.currentTimeMillis(); state.set(COMPLETE); System.out.println("task=" + source.getClass().getSimpleName()); System.out.println("start= " + start); System.out.println("end= " + end + " cost= " + (end - start)); if (!shouldRun) { System.out.println("task not run"); } /* * 执行后续任务 * 1. 任务在主线程,并且是非阻塞的,需要运行 * 2. 任务在子线程,需要运行 */ if (!nextList.isEmpty()) { for (RealTask next : nextList) { if (next.decrementAndGet() == 0) { if (next.isMainThread()) { if (!next.isBlocking()) { ThreadUtils.runOnUiThread(next); } } else { ThreadUtils.runOnIoThread(next); } } } } } /** * @return 是否需要运行 */ private boolean shouldRun() { String processName = ProcessUtils.getCurrentProcessName(mContext); if (ProcessUtils.isMainProcess(mContext, processName)) { if (isMainProcess()) { return true; } else { return processes().contains(processName); } } else { return processes().contains(processName); } } /** * 更新前序任务 */ public void increment() { incrementAndGet(); } /** * 添加后序任务 */ public void addNextTask(RealTask task) { nextList.add(task); } /** * @return 当前任务能否开始,即前序任务有没有完成 */ public boolean canStart() { return get() == 0; } /** * @return 当前任务是否完成 */ public boolean isDone() { return state.get() == COMPLETE; } } 复制代码
AtomicInteger
初始值为0
每有一个前序任务加1
每完成一个前序任务减1
Comparable
@Override public int compareTo(RealTask o) { if (isMainThread()) { if (o.isMainThread()) { return o.priority() - priority(); } else { return 1; } } else { if (o.isMainThread()) { return -1; } else { return o.priority() - priority(); } } } 复制代码
线程相同的情况下,优先级高的先运行
线程不同的情况下,子线程先运行
这里的运行,不一定真的运行,要根据前序任务
多进程逻辑
private boolean shouldRun() { String processName = ProcessUtils.getCurrentProcessName(mContext); if (ProcessUtils.isMainProcess(mContext, processName)) { if (isMainProcess()) { return true; } else { return processes().contains(processName); } } else { return processes().contains(processName); } } 复制代码
主进程时,先判断
isMainProcess
,如果不是主进程,走3其他进程时,走3
判断进程列表是否包含该进程,有可能包含主进程
执行逻辑
@Override public void run() { ... if (!nextList.isEmpty()) { for (RealTask next : nextList) { if (next.decrementAndGet() == 0) { if (next.isMainThread()) { if (!next.isBlocking()) { ThreadUtils.runOnUiThread(next); } } else { ThreadUtils.runOnIoThread(next); } } } } } 复制代码
后序任务在主线程,并且是非阻塞的,直接运行
后序任务在子线程,直接运行
Startup
public final class Startup { private static volatile Startup sInstance; final Context mContext; final List<Class<? extends Task>> taskList; final Map<Class<?>, Task> taskMap; final List<RealTask> realTaskList; final Map<Class<?>, RealTask> realTaskMap; /** * 启动队列,包括 * 1. 主线程,阻塞的任务 * 2. 子线程,阻塞的任务 */ final Queue<RealTask> queue; /** * 子线程,非阻塞 */ final Queue<RealTask> ioQueue; /** * 主线程,非阻塞 */ final Queue<RealTask> mainQueue; Startup(Context context) { mContext = context.getApplicationContext(); taskList = new ArrayList<>(); taskMap = new HashMap<>(); realTaskList = new ArrayList<>(); realTaskMap = new HashMap<>(); queue = new LinkedList<>(); ioQueue = new LinkedList<>(); mainQueue = new LinkedList<>(); } public static Startup getInstance(Context context) { if (sInstance == null) { synchronized (Startup.class) { if (sInstance == null) { sInstance = new Startup(context); } } } return sInstance; } public Startup addTask(Class<? extends Task> component) { taskList.add(component); return this; } private void prepare(List<Class<? extends Task>> list) { for (Class<? extends Task> component : list) { prepare0(component); } } private void prepare0(Class<? extends Task> component) { prepare0(component, new HashSet<>()); } private void prepare0(Class<? extends Task> component, Set<Class<?>> initializing) { if (initializing.contains(component)) { String message = String.format("循环依赖 %s.", component.getName()); throw new StartupException(message); } try { if (!taskMap.containsKey(component)) { initializing.add(component); Object instance = component.getDeclaredConstructor().newInstance(); Task initializer = (Task) instance; List<Class<? extends Task>> sublist = initializer.dependencies(); if (sublist != null && !sublist.isEmpty()) { for (int i = 0; i < sublist.size(); i++) { if (!taskMap.containsKey(sublist.get(i))) { prepare0(sublist.get(i), initializing); } } } initializing.remove(component); taskMap.put(component, initializer); } } catch (Throwable t) { throw new StartupException(t); } } private void check() { for (RealTask task : realTaskList) { if (task.isMainThread() && !task.isBlocking()) { check0(task); } } } private void check0(RealTask task) { List<RealTask> list = task.nextList; if (list != null && !list.isEmpty()) { for (RealTask next : list) { if (next.isBlocking()) { String message = String.format("主线程,非阻塞任务不能依赖阻塞任务 %s.", task.getClass().getSimpleName()); throw new StartupException(message); } else { check0(next); } } } } public void start() { // 创建任务对象,检测循环依赖 prepare(taskList); // 创建包装任务 for (Map.Entry<Class<?>, Task> entry : taskMap.entrySet()) { Class<?> clazz = entry.getKey(); Task initializer = entry.getValue(); RealTask task = new RealTask(mContext, initializer); realTaskList.add(task); realTaskMap.put(clazz, task); } // 添加后序任务,统计前序任务数量 for (RealTask task : realTaskList) { List<Class<? extends Task>> sublist = task.dependencies(); if (sublist != null && !sublist.isEmpty()) { for (Class<? extends Task> clazz : sublist) { RealTask subTask = realTaskMap.get(clazz); if (subTask != null) { subTask.addNextTask(task); task.increment(); } } } } // 检测 check(); // 所有任务排序 Collections.sort(realTaskList, RealTask::compareTo); // 后序任务排序 for (RealTask task : realTaskList) { List<RealTask> list = task.nextList; if (list != null && !list.isEmpty()) { Collections.sort(list, RealTask::compareTo); } } // 分组任务 for (RealTask task : realTaskList) { if (task.isMainThread()) { if (task.isBlocking()) { queue.offer(task); } else { mainQueue.offer(task); } } else { if (task.isBlocking()) { queue.offer(task); } else { ioQueue.offer(task); } } } // 先执行子线程的非阻塞任务 while (!ioQueue.isEmpty()) { RealTask task = ioQueue.poll(); if (task != null) { if (task.canStart()) { ThreadUtils.runOnIoThread(task); } } } // 执行阻塞任务 while (!queue.isEmpty()) { RealTask task = queue.poll(); if (task != null) { if (task.isDone()) { continue; } if (!task.canStart()) { queue.offer(task); continue; } if (task.isMainThread()) { if (task.isBlocking()) { task.run(); } } else { ThreadUtils.runOnIoThread(task); } } } // 执行主线程的非阻塞任务 while (!mainQueue.isEmpty()) { RealTask task = mainQueue.poll(); if (task != null) { ThreadUtils.runOnUiThread(task); } } } } 复制代码
单例模式
递归的方式检测循环依赖
建立任务的前后依赖关系
递归的方式检测任务合理性
排序,后序任务也要排序
所有任务进行分组
执行任务
总结
本文主要描述了Application启动任务的优化。
部分代码参考了官方Startup库。
作者:Java技师
链接:https://juejin.cn/post/7031508136301166622