更快!更高效!异步启动框架Alpha完全解析,值得一读

//Project.java
private void init() {

mProject = new Project();
mFinishTask = new AnchorTask(false, “AlphaDefaultFinishTask”);
mFinishTask.setProjectLifecycleCallbacks(mProject);
mStartTask = new AnchorTask(true, “AlphaDefaultStartTask”);
mStartTask.setProjectLifecycleCallbacks(mProject);
mProject.setStartTask(mStartTask);
mProject.setFinishTask(mFinishTask);

}

private static class AnchorTask extends Task {
private boolean mIsStartTask = true;
private OnProjectExecuteListener mExecuteListener;

public AnchorTask(boolean isStartTask, String name) {
super(name);
mIsStartTask = isStartTask;
}

public void setProjectLifecycleCallbacks(OnProjectExecuteListener callbacks) {
mExecuteListener = callbacks;
}

@Override
public void run() {
if (mExecuteListener != null) {

if (mIsStartTask) {
mExecuteListener.onProjectStart();
} else {
mExecuteListener.onProjectFinish();
}
}
}

}

复制代码

可以看到,在Project类的初始化方法中,定义了一个开始任务和一个结束任务。这是因为从执行角度看,一个任务序列必须有一个开始节点和一个结束节点。但是实际情况中,可能会有多个任务可以同时开始,而且有多个任务可以同时作为结束点。所以就设置了这两个节点方便控制整个流程,标记流程的开始和结束,也方便了任务的监听

说回上面,开始任务的start方法走到哪里去了呢?自然是AnchorTask的父类Task,看看源码:

public synchronized void start() {

switchState(STATE_WAIT);

if (mInternalRunnable == null) {
mInternalRunnable = new Runnable() {
@Override
public void run() {
android.os.Process.setThreadPriority(mThreadPriority);
long startTime = System.currentTimeMillis();

switchState(STATE_RUNNING);
Task.this.run();
switchState(STATE_FINISHED);

long finishTime = System.currentTimeMillis();
recordTime((finishTime - startTime));

notifyFinished();
recycle();
}
};
}

if (mIsInUiThread) {
sHandler.post(mInternalRunnable);
} else {
sExecutor.execute(mInternalRunnable);
}
}
复制代码

源码还是挺简单的哈,定义了一个Runnable,然后判断是否主线程,并执行这个Runnable。其中还穿插了一些状态的改变,在Runnable内部主要是执行了Task.this.run(),也就是执行了任务本身。其中setThreadPriority方法主要是设置了线程的优先级,比如THREAD_PRIORITY_DEFAULT等,这里的优先级是较线程而言的,主要是针对CPU资源的竞争,跟我们需要的Task之间的优先级关系不大。 如果是需要在主线程执行的任务,就会通过Handler(sHandler)将事件传递给主线程执行。 如果是需要在非主线程执行的任务,就会通过线程池(sExecutor)去执行线程任务。

诶,好像没了?开始任务执行了就没了吗?再回头看看,还有一个notifyFinished方法。 按这个名字应该就是通知任务结束的一个方法,看看源码:

void notifyFinished() {
if (!mSuccessorList.isEmpty()) {
AlphaUtils.sort(mSuccessorList);

for (Task task : mSuccessorList) {
task.onPredecessorFinished(this);
}
}

if (!mTaskFinishListeners.isEmpty()) {
for (OnTaskFinishListener listener : mTaskFinishListeners) {
listener.onTaskFinish(mName);
}

mTaskFinishListeners.clear();
}
}
复制代码

这个方法主要做了三件事:

  • mSuccessorList 排序
  • 遍历mSuccessorList列表,执行onPredecessorFinished方法
  • 监听回调onTaskFinish方法

mSuccessorList是什么呢?我们叫它**「紧后任务列表」**,也就是接下来要执行的任务列表。所以流程就是先把当前任务之后的任务列表进行一个排序,根据优先级排序。然后按顺序执行onPredecessorFinished方法。

如果紧后任务列表为空,也就代表没有后续任务了,那么就会走onTaskFinish回调方法,告知当前Project已经执行完毕。

接下来就看看紧后任务是怎么加进来的呢?又该怎么排序?onPredecessorFinished方法又执行了些什么东西?

//1、紧后任务添加
public Builder after(Task task) {
task.addSuccessor(mCacheTask);
mFinishTask.removePredecessor(task);
mIsSetPosition = true;
return Builder.this;
}

void addSuccessor(Task task) {
task.addPredecessor(this);
mSuccessorList.add(task);
}

//2、紧后任务列表排序
public static void sort(List tasks) {
if (tasks.size() <= 1) {
return;
}
Collections.sort(tasks, sTaskComparator);
}

private static Comparator sTaskComparator = new Comparator() {
@Override
public int compare(Task lhs, Task rhs) {
return lhs.getExecutePriority() - rhs.getExecutePriority();
}
};

//3、紧后任务执行
synchronized void onPredecessorFinished(Task beforeTask) {

if (mPredecessorSet.isEmpty()) {
return;
}

mPredecessorSet.remove(beforeTask);
if (mPredecessorSet.isEmpty()) {
start();
}

}

复制代码

ok,源码写的很清楚了,这里逐步分析下:

由源码得知,紧后任务列表主要是通过after方法,还记得之前配置任务的时候吗? builder.add(Task2).after(Task1),所以这个after就代表Task2要在Task1后面执行,也就是Task2成了Task1的紧后任务。同理,Task1也就成了Task2的紧前任务。也就是代码中的addPredecessor方法,在添加紧后任务的同时也添加了紧前任务。

可能有人会问了,紧前任务添加了有什么用呢?难不成还倒退回去执行? 试想一下,如果有多个任务的紧后任务都是一个呢?比如这种情况:builder.add(Task4).after(Task2,Task3)。Task4是Task2和Task3的紧后任务,所以在Task2执行完之后,还要判断Task3是否执行成功,然后才能执行Task4,这就是紧前任务列表的作用。这也就对应到上述代码中onPredecessorFinished方法的逻辑了。

然后这个紧后任务列表的排序是怎么排的呢?其实就是通过getExecutePriority方法获取task的执行优先级数字,按照正序排列,越小的任务执行时机越早。还记得之前配置的时候我设置了setExecutePriority方法吗,就是这里设置了优先级的。

至此主要逻辑就差不多了。好像还挺简单的是不是。还有一些细节我也简单的提下:

  • 各种回调:包括一些task的回调,project的回调。
  • 日志记录:比如耗时时间的记录,刚才执行任务时候的recordTime方法,就是记录了每个task的耗时。
  • 多种Task配置方法:除了上面用Java代码配置,还可以通过xml文件来配置Project和里面的Task,这个就主要是XmlPullParser类来解析xml数据,然后生成Prject。
  • 各种设计模式:比如构建Project的建造者模式,还有通过传入task名称就可以创建Task的工厂模式。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

学习路线+知识梳理

花了很长时间,就为了整理这张详细的知识路线脑图。当然由于时间有限、能力也都有限,毕竟嵌入式全体系实在太庞大了,包括我那做嵌入式的同学,也不可能什么都懂,有些东西可能没覆盖到,不足之处,还希望小伙伴们一起交流补充,一起完善进步。

这次就分享到这里吧,下篇见

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img
,有些东西可能没覆盖到,不足之处,还希望小伙伴们一起交流补充,一起完善进步。

这次就分享到这里吧,下篇见

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-V2GfLdpm-1712739602553)]

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值