设计
任务的分类
- 主线程,阻塞
- 主线程,非阻塞(不常用)
- 子线程,阻塞(很少见)
- 子线程,非阻塞
这里阻塞的含义是指在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库。