阅读 170

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);     } } 复制代码

  1. 主进程时,先判断isMainProcess,如果不是主进程,走3

  2. 其他进程时,走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


文章分类
代码人生
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐