当前位置:网站首页>TaskDispatcher源码解析
TaskDispatcher源码解析
2022-07-30 12:53:00 【赵健zj】
资料
github地址
[email protected]:AdrianAndroid/TaskDispatcher.git
图论:有向无环图的排序——拓扑排序
用法
TaskDispatcher.init
public static void init(Application context) {
if (context != null) {
sContext = context; // 保存上下文
mApp = context; // 保存Application
sHasInit = true; // 已经初始化
sIsMainProcess = Utils.isMainProcess(sContext); // 是不是主进程
}
}
createInstance
/** * 注意:每次获取的都是新对象 * * @return */
public static TaskDispatcher createInstance() {
if (!sHasInit) {
throw new RuntimeException("must call TaskDispatcher.init first");
}
return new TaskDispatcher();
}
addTask & start & await
void runTask() {
Log.i("MyApp", "step 1");
Debug.startMethodTracing("runTask" + System.currentTimeMillis());
TaskDispatcher dispatcher = TaskDispatcher.createInstance();
dispatcher
.addTask(new InitStethoTask())
.addTask(new InitUmengTask())
.addTask(new GetDeviceIdTask())
.start();
Log.i("MyApp", "step 2");
dispatcher.await();
Log.i("MyApp", "step 3");
DelayInitDispatcher delayInitDispatcher = new DelayInitDispatcher();
delayInitDispatcher.addTask(new DelayInitTaskA())
.addTask(new DelayInitTaskB())
.start();
Log.i("MyApp", "step 4");
LaunchTimer.endRecord();
Debug.stopMethodTracing();
}
addTask(new InitStethoTask())
/** * 异步的Task */
public class InitStethoTask extends Task {
@Override
public boolean needWait() {
return true;
}
@Override
public void run() {
Handler handler = new Handler(Looper.getMainLooper());
Stetho.initializeWithDefaults(mContext);
try {
Thread.sleep(1300);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i("MyApp", "InitStethoTask");
}
}
addTask(new InitUmengTask())
/** * 需要在getDeviceId之后执行 */
public class InitUmengTask extends Task {
@Override
public boolean needWait() {
return super.needWait();
}
@Override
public List<Class<? extends Task>> dependsOn() {
List<Class<? extends Task>> task = new ArrayList<>();
task.add(GetDeviceIdTask.class);
return task;
}
@Override
public void run() {
UMConfigure.init(mContext, "58edcfeb310c93091c000be2", "umeng",
UMConfigure.DEVICE_TYPE_PHONE, "1fe6a20054bcef865eeb0991ee84525b");
Log.i("MyApp", "InitUmengTask");
}
}
addTask(new GetDeviceIdTask())
public class GetDeviceIdTask extends Task {
private String mDeviceId;
@Override
public boolean needWait() {
return true;
}
@SuppressLint("MissingPermission")
@Override
public void run() {
// 真正自己的代码
TelephonyManager tManager = (TelephonyManager) mContext.getSystemService(
Context.TELEPHONY_SERVICE);
// MyApp app = (MyApp) mContext;
// app.setDeviceId(mDeviceId);
Log.i("MyApp", "GetDeviceIdTask");
}
}
DelayInitDispatcher
DelayInitDispatcher delayInitDispatcher = new DelayInitDispatcher();
delayInitDispatcher.addTask(new DelayInitTaskA())
.addTask(new DelayInitTaskB())
.start();
/** * 延迟初始化分发器 */
public class DelayInitDispatcher {
private Queue<Task> mDelayTasks = new LinkedList<>();
private MessageQueue.IdleHandler mIdleHandler = new MessageQueue.IdleHandler() {
@Override
public boolean queueIdle() {
if(mDelayTasks.size()>0){
Task task = mDelayTasks.poll();
new DispatchRunnable(task).run();
}
return !mDelayTasks.isEmpty();
}
};
public DelayInitDispatcher addTask(Task task){
mDelayTasks.add(task);
return this;
}
public void start(){
Looper.myQueue().addIdleHandler(mIdleHandler);
}
}
DelayInitTaskA
public class DelayInitTaskA extends MainTask {
@Override
public void run() {
Log.i("MyApp", "DelayInitTaskA");
// 模拟一些操作
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i("DelayInitTaskA finished", "");
}
}
MainTask
public abstract class MainTask extends Task {
@Override
public boolean runOnMainThread() {
return true;
}
}
源码解析
addTask
addTask
public TaskDispatcher addTask(Task task) {
if (task != null) {
collectDepends(task);
mAllTasks.add(task);
mClsAllTasks.add(task.getClass());
// 非主线程且需要wait的,主线程不需要CountDownLatch也是同步的
if (ifNeedWait(task)) {
mNeedWaitTasks.add(task);
mNeedWaitCount.getAndIncrement();
}
}
return this;
}
collectDepends(task);
private void collectDepends(Task task) {
if (task.dependsOn() != null && task.dependsOn().size() > 0) {
for (Class<? extends Task> cls : task.dependsOn()) {
if (mDependedHashMap.get(cls) == null) {
mDependedHashMap.put(cls, new ArrayList<Task>());
}
mDependedHashMap.get(cls).add(task);
if (mFinishedTasks.contains(cls)) {
task.satisfy();
}
}
}
}
start
@UiThread
public void start() {
mStartTime = System.currentTimeMillis();
if (Looper.getMainLooper() != Looper.myLooper()) {
throw new RuntimeException("must be called from UiThread");
}
if (mAllTasks.size() > 0) {
mAnalyseCount.getAndIncrement();
printDependedMsg();
mAllTasks = TaskSortUtil.getSortResult(mAllTasks, mClsAllTasks);
mCountDownLatch = new CountDownLatch(mNeedWaitCount.get());
sendAndExecuteAsyncTasks();
DispatcherLog.i("task analyse cost " + (System.currentTimeMillis() - mStartTime) + " begin main ");
executeTaskMain();
}
DispatcherLog.i("task analyse cost startTime cost " + (System.currentTimeMillis() - mStartTime));
}
getSortResult
public static synchronized List<Task> getSortResult(List<Task> originTasks,
List<Class<? extends Task>> clsLaunchTasks) {
long makeTime = System.currentTimeMillis();
Set<Integer> dependSet = new ArraySet<>();
Graph graph = new Graph(originTasks.size());
for (int i = 0; i < originTasks.size(); i++) {
Task task = originTasks.get(i);
if (task.isSend() || task.dependsOn() == null || task.dependsOn().size() == 0) {
continue;
}
for (Class cls : task.dependsOn()) {
int indexOfDepend = getIndexOfTask(originTasks, clsLaunchTasks, cls);
if (indexOfDepend < 0) {
throw new IllegalStateException(task.getClass().getSimpleName() +
" depends on " + cls.getSimpleName() + " can not be found in task list ");
}
dependSet.add(indexOfDepend);
graph.addEdge(indexOfDepend, i);
}
}
List<Integer> indexList = graph.topologicalSort();
List<Task> newTasksAll = getResultTasks(originTasks, dependSet, indexList);
DispatcherLog.i("task analyse cost makeTime " + (System.currentTimeMillis() - makeTime));
printAllTaskName(newTasksAll);
return newTasksAll;
}
拓扑排序

初始化线程堵塞
mCountDownLatch = new CountDownLatch(mNeedWaitCount.get());
开始执行任务
/** * 发送去并且执行异步任务 */
private void sendAndExecuteAsyncTasks() {
for (Task task : mAllTasks) {
if (task.onlyInMainProcess() && !sIsMainProcess) {
markTaskDone(task);
} else {
sendTaskReal(task);
}
task.setSend(true);
}
}
markTaskDone
public void markTaskDone(Task task) {
if (ifNeedWait(task)) {
mFinishedTasks.add(task.getClass());
mNeedWaitTasks.remove(task);
mCountDownLatch.countDown();
mNeedWaitCount.getAndDecrement();
}
}
sendTaskReal
/** * 发送任务 */
private void sendTaskReal(final Task task) {
if (task.runOnMainThread()) {
mMainThreadTasks.add(task);
if (task.needCall()) {
task.setTaskCallBack(new TaskCallBack() {
@Override
public void call() {
TaskStat.markTaskDone();
task.setFinished(true);
satisfyChildren(task);
markTaskDone(task);
DispatcherLog.i(task.getClass().getSimpleName() + " finish");
Log.i("testLog", "call");
}
});
}
} else {
// 直接发,是否执行取决于具体线程池
Future future = task.runOn().submit(new DispatchRunnable(task, this));
mFutures.add(future);
}
}
executeTaskMain
private void executeTaskMain() {
mStartTime = System.currentTimeMillis();
for (Task task : mMainThreadTasks) {
long time = System.currentTimeMillis();
new DispatchRunnable(task, this).run();
DispatcherLog.i("real main " + task.getClass().getSimpleName() + " cost " +
(System.currentTimeMillis() - time));
}
DispatcherLog.i("maintask cost " + (System.currentTimeMillis() - mStartTime));
}
@Override
public void run() {
TraceCompat.beginSection(mTask.getClass().getSimpleName());
DispatcherLog.i(mTask.getClass().getSimpleName()
+ " begin run" + " Situation " + TaskStat.getCurrentSituation());
Process.setThreadPriority(mTask.priority());
long startTime = System.currentTimeMillis();
mTask.setWaiting(true);
mTask.waitToSatisfy();
long waitTime = System.currentTimeMillis() - startTime;
startTime = System.currentTimeMillis();
// 执行Task
mTask.setRunning(true);
mTask.run();
// 执行Task的尾部任务
Runnable tailRunnable = mTask.getTailRunnable();
if (tailRunnable != null) {
tailRunnable.run();
}
if (!mTask.needCall() || !mTask.runOnMainThread()) {
printTaskLog(startTime, waitTime);
TaskStat.markTaskDone();
mTask.setFinished(true);
if (mTaskDispatcher != null) {
mTaskDispatcher.satisfyChildren(mTask);
mTaskDispatcher.markTaskDone(mTask);
}
DispatcherLog.i(mTask.getClass().getSimpleName() + " finish");
}
TraceCompat.endSection();
}
边栏推荐
- 湖仓一体电商项目(二):项目使用技术及版本和基础环境准备
- 当下,产业园区发展面临的十大问题
- 腾讯称电竞人才缺口200万;华为鸿蒙3.0正式发布;乐视推行每周工作4天半?...丨黑马头条...
- 私有化部署的即时通讯平台,为企业移动业务安全保驾护航
- Using Baidu EasyDL to realize the recognition of the chef's hat of the bright kitchen
- datax enables hana support and dolphinscheduler enables datax tasks
- 434. 字符串中的单词数
- 【Kaggle:UW-Madison GI Tract Image Segmentation】肠胃分割比赛:赛后复盘+数据再理解
- [PostgreSQL] - explain SQL分析介绍
- dolphinscheduler单机化改造
猜你喜欢

There is no one of the strongest kings in the surveillance world!

手慢无!阿里亿级流量高并发系统设计核心原理全彩笔记现实开源

力扣——15. 三数之和

腾讯称电竞人才缺口200万;华为鸿蒙3.0正式发布;乐视推行每周工作4天半?...丨黑马头条...

一本通循环结构的程序设计第一章题解(1)

私有化部署的即时通讯平台,为企业移动业务安全保驾护航

DeFi 巨头进军 NFT 领域 用户怎么看?

Markdown 1 - 图文音视频等

Beijing, Shanghai and Guangzhou offline events丨The most unmissable technology gatherings at the end of the year are all gathered

一文读懂Elephant Swap,为何为ePLATO带来如此高的溢价?
随机推荐
【Kaggle:UW-Madison GI Tract Image Segmentation】肠胃分割比赛:赛后复盘+数据再理解
一文读懂Elephant Swap,为何为ePLATO带来如此高的溢价?
[BJDCTF2020]Cookie is so stable-1|SSTI注入
Raja Koduri澄清Arc GPU跳票传闻 AXG年底前新推四条产品线
[ASP.NET Core] Dependency Injection for Option Classes
一本通循环结构的程序设计第一章题解(1)
DeFi 巨头进军 NFT 领域 用户怎么看?
【Kaggle比赛常用trick】K折交叉验证、TTA
R语言ggplot2可视化:使用ggpubr包的ggboxplot函数可视化分组箱图、使用ggpar函数改变图形化参数(xlab、ylab、改变可视化图像的坐标轴标签内容)
关于香港高防IP需要关注的几个问题
dolphinscheduler添加hana支持
int a=8,a=a++,a? int b=8,b=b+1,b?
Jackson 的JAR包冲突问题
数字化时代,寻求企业财务转型路径的最优解
展厅全息投影所具备的三大应用特点
js 构造函数 return 非空对象,其实例化的对象在原型上的差异
Markdown 1 - 图文音视频等
域名抢注“卷”到了表情包?ENS逆势上涨的新推力
dolphinscheduler adds hana support
R语言时间序列数据算术运算:使用log函数将时间序列数据的数值对数化(平方、开平方、指数化等函数类似使用)