之前做启动优化的时候,把各种任务单独拎出来,做成一个组建,然后根据任务的优先级以及依赖顺序去执行.
源码见:https://github.com/huangbei1990/HDemo
整个模块主要分成以下四个部分.
1.task
task设置了四个优先级,具体如下所示,不同优先级的task会有不同的执行逻辑.
public enum Priority {
Immediately,//放入缓存线程池执行
Normal,//放入线程池执行
Idle,//cpu空闲时执行
Main//主线程执行
}
每个task会有一个pre和next,分别表示任务执行的前置条件和后置任务.
另外可以给每个任务设置执行的钩子,任务执行前会执行beforeTask,任务执行后会执行afterTask.
public interface TaskOrder {
public void beforeTask(Task task);
public void afterTask(Task task);
}
每个Task都必须要复写runTask方法,这个方法是真正执行的任务内容.
此外还可以复写isExecute和getPriority方法,
isExecute表示任务是否要执行,可以控制任务在某些场景下执行,某些场景下不执行.
getPriority表示任务的优先级,默认优先级为Immediately
例子:
Task task1 = new Task("task1") {
@Override
public void runTask() {
Log.i(TAG,"执行task1");
}
@Override
public boolean isExecute() {
if(i == 1){
return true;
}else{
return false;
}
}
@Override
public Priority getPriority() {
return Priority.Normal;
}
};
2.TaskPool
taskPool根据任务的配置,将任务放置在不同的线程池中执行.
TaskPool调用execute方法之后将会返回一个Disposable对象,
Disposable方便业务方在合适的时机取消任务,避免发生内存泄漏.
同时也可以调用其autoDispose方法,传入lifeCycle,这样在onDestroy的时候会自动调用dispose方法.
例子:
TaskPool.execute(task1).autoDispose(this.getLifecycle());
3.TaskLine
任务链可以将多个任务线性执行.
如下例子所示,任务将会按照task1->task3->task2线性执行.
例子:
TaskLine.create().next(task1).next(task3).next(task2).execute()
在执行之前会检查当前的链表是否存在环,如果存在环,则会抛出异常.
主要的逻辑如下
private Set<Task> checked = new HashSet<>();
private Queue<Task> seeds = new ArrayDeque<>();
public boolean checkRound(Task root, TaskOrder order) {
checked.clear();
seeds.clear();
seeds.offer(root);
while (!seeds.isEmpty()) {
Task task = seeds.poll();
if (checked.contains(task)) {
return false;
}
if (order != null) {
task.setTaskOrder(order);
}
checked.add(task);
Set<Task> children = task.next();
if (children != null && children.size() > 0) {
for (Task child : children) {
child.addPre(task);
seeds.offer(child);
}
}
}
checked.clear();
seeds.clear();
return true;
}
4.TaskTree
任务树可以包含多条任务链,和多个任务,同样在执行任务之前会先检查是否有环.
例子:
TaskLine taskLine1 = TaskLine.create().next(task1).next(task3);
TaskLine taskLine2 = TaskLine.create().next(task2).next(task4);
TaskTree.create().addTaskLine(taskLine1).addTaskLine(taskLine2).addTask(task5).execute();