当前位置:网站首页>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();
}
边栏推荐
猜你喜欢

for循环的3个表达式执行顺序

Vivado安装后添加器件库

缓存一致性

leetcode207.课程表(判断有向图是否有环)

展厅全息投影所具备的三大应用特点

Yilian: Activating the Value Potential of Data Elements and Unleashing the Innovation Dividend of SAS SSD

OpenHarmony环境搭建报错: ImportError: cannot import name ‘VERSION‘ from ‘hb.__main__‘

树形dp小总结(换根,基环树,杂七杂八的dp)

监控界的最强王者,没有之一!

Mysql索引结构
随机推荐
How to display an Excel table in the body of an email?
Tutorial on using the one-key upgrade function of the RTSP/Onvif video platform EasyNVR service
【微信小程序】一文带你搞懂小程序的页面配置和网络数据请求
There is no one of the strongest kings in the surveillance world!
How to solve the problem that the page does not display the channel configuration after the EasyNVR is updated to (V5.3.0)?
R语言ggplot2可视化:使用ggpubr包的ggboxplot函数可视化分组箱图、使用ggpar函数改变图形化参数(ylim、修改可视化图像y轴坐标轴数值范围)
第42讲:Scala中泛型类、泛型函数、泛型在Spark中的广泛应用
物理服务器与虚拟机:主要区别和相似之处
[PostgreSQL] - 存储结构及缓存shared_buffers
[PostgreSQL] - explain SQL analysis introduction
缓存一致性
手慢无!阿里亿级流量高并发系统设计核心原理全彩笔记现实开源
浅析TSINGSEE智能视频分析网关的AI识别技术及应用场景
CMake库搜索函数居然不搜索LD_LIBRARY_PATH
SyntaxError: EOL while scanning string literal
matlab画图,仅显示部分图例
每天学一点Scala之 伴生类和伴生对象
句柄与指针的简单理解
手撕读写锁性能测试
R语言使用方差分析ANOVA比较回归模型的差异、anova函数比较两个模型并报告它们是否存在显著差异(两个模型的数据相同,一个模型使用的预测特征包含另外一个模型的特征)