idisfkj / android-startup

🔥The Android Startup library provides a straightforward, performant way to initialize components at the application startup. Both library developers and app developers can use Android Startup to streamline startup sequences and explicitly set the order of initialization.
https://rousetime.com
Apache License 2.0
1.6k stars 158 forks source link

关于主线程上有相互依赖的任务的执行问题 #37

Closed Jorah1012 closed 8 months ago

Jorah1012 commented 11 months ago

有这样的业务场景 模块A需要在application的attachBaseContext中执行,并且需要在主线程执行 模块B需要在application的onCreate中执行,且依赖A,并需在主线程中执行

由于当前的库是在for循环中对所有库进行了线程分配,如果是在主线程执行时,则顺序run所有在主线程执行的模块,这时候,如果模块A执行超时(模块A使用手动触发dispatch,以期望在onCreate时初始化其它模块),则主线程冻结

建议: 在dispatch过程中,所有的模块默认都在线程池中等待竞争条件,wait到竞争条件后真正执行时,如果模块需要在主线程中执行,则通过handler来执行。这样可以解决这个问题

idisfkj commented 11 months ago
  1. 手动配置与自动配置推荐只选一种,除非实在有必要(因为attachBaseContext 是在onCreate之前执行,导致间接强依赖)
  2. 针对主线程冻结的问题,建议看下文档(尤其是这两个方法的使用:callCreateOnMainThreadwaitOnMainThread
  3. dispatch过程中,异步的任务本身就是在线程池中,同步的任务一定是符合条件的才会进入执行或者等待。
  4. 另外,如果你的任务并不存在等待,其实本质就是异步任务了。这就类似于你所说的所有的模块默认都在线程池中等待竞争条件,wait到竞争条件后真正执行时,如果是这样的就已经跳过了启动链路,它本身就与启动无强制关系。
Jorah1012 commented 11 months ago

目前来说在主线程同步调用所有在主线程执行的模块是有道理的。毕竟是初始化。我目前的项目必须是要现在attachBaseConext执行初始化一两个模块,其它需要在onCreate执行,我当前的解决办法是分两份初始化,一份是在attachBaseContext中,另外一份在onCreate中,在onCreate中初始化的不在模块中写那些在attachBaseContext中初始化的模块——我们就假定它们已经初始化过了