有源码 国庆在家,从0手撸一个依赖任务加载框架( 二 )


public class IDAGTask implements Runnable {
private final boolean mIsSyn;
private final AtomicInteger mAtomicInteger;
boolean getIsAsync() {
return mIsSyn;
}
void addRely() {
mAtomicInteger.incrementAndGet();
}
void deleteRely() {
mAtomicInteger.decrementAndGet();
}
int getRely() {
return mAtomicInteger.get();
}
@Override
public void run() {
}
回到之前为什么不用接口或者抽象类的方式来实现这个基础类,一方面为了后续将任务丢进线程池,IDAGTask实现了Runnable接口,接口的方式显然pass,另一方面抽象类的方式涉及到了另一个问题:
 

  • 抽象run方法,可以将IDAGTask任务的监听封装进去,比如startTask、completeDAGTask,如果我们继承IDATask,只需要将初始化部分单纯写进run方法就好了,非常优雅,但是有一种case,如果这个任务的初始化是用多线程实现的,我们调用完Task.init(),马上执行completeDAGTask的监听其实是不对的
     
  • 基于上面的case,我选择了一种不优雅的实现方式,将startTask的监听写在run方法的开头,completeDAGTask的监听需要调用者自己添加,任务初始化是单线程实现写在run方法的末尾即可,任务初始化采用多线程实现,需要将completeDAGTask监听写进加载成功回调
     
  • 综上,run方法写进了startTask的回调,因此抽象失败,那么IDAGTask没有抽象方法,自然也不需要作为一个抽象类
     
 
经过一些加工,最后IDATask实现如下:
public class IDAGTask implements Runnable {
private final boolean mIsSyn;
private final AtomicInteger mAtomicInteger;
private IDAGCallBack mDAGCallBack;
private final Set mNextTaskSet;
public IDAGTask() {
this("");
}
public IDAGTask(boolean isSyn) {
this("", isSyn);
}
public IDAGTask(String alias) {
this(alias, false);
}
public IDAGTask(String alias, boolean IsSyn) {
mIsSyn = IsSyn;
mAtomicInteger = new AtomicInteger();
mDAGCallBack = new DAGCallBack(alias);
mNextTaskSet = new HashSet<>();
}
boolean getIsAsync() {
return mIsSyn;
}
void addRely() {
mAtomicInteger.incrementAndGet();
}
void deleteRely() {
mAtomicInteger.decrementAndGet();
}
int getRely() {
return mAtomicInteger.get();
}
void addNextDAGTask(IDAGTask DAGTask) {
mNextTaskSet.add(DAGTask);
}
public void setDAGCallBack(IDAGCallBack DAGCallBack) {
this.mDAGCallBack = DAGCallBack;
}
public void completeDAGTask() {
for (IDAGTask DAGTask : mNextTaskSet) {
DAGTask.deleteRely();
}
mDAGCallBack.onCompleteDAGTask();
}
@Override
public void run() {
mDAGCallBack.onStartDAGTask();
}
定义DAGProject类
IDAGTask的模板就被敲定了,接下来我们需要建立任务之间的关系:
 
  • Set储存所有的任务,通过addDAGTask添加任务
     
  • Map储存所有的任务与其前置依赖关系,通过addDAGEdge添加任务依赖关系
     
  • 整体采用建造者模式构建DAGProject类
     
 
于是DAGProject实现如下:
public class DAGProject {
private final Set mTaskSet;
private final Map> mTaskMap;
public DAGProject(Builder builder) {
mTaskSet = builder.mTaskSet;
mTaskMap = builder.mTaskMap;
}
Set getDAGTaskSet() {
return mTaskSet;
}
Map> getDAGTaskMap() {
return mTaskMap;
}
public static class Builder {
private final Set mTaskSet = new HashSet<>();
private final Map> mTaskMap = new HashMap<>();
public Builder addDAGTask(IDAGTask DAGTask) {
if (this.mTaskSet.contains(DAGTask)) {
throw new IllegalArgumentException();
}
this.mTaskSet.add(DAGTask);
return this;
}
public Builder addDAGEdge(IDAGTask DAGTask, IDAGTask preDAGTask) {
if (!this.mTaskSet.contains(DAGTask) || !this.mTaskSet.contains(preDAGTask)) {
throw new IllegalArgumentException();
}
Set preDAGTaskSet = this.mTaskMap.get(DAGTask);
if (preDAGTaskSet == null) {
preDAGTaskSet = new HashSet<>();
this.mTaskMap.put(DAGTask, preDAGTaskSet);
}
if (preDAGTaskSet.contains(preDAGTask)) {
throw new IllegalArgumentException();
}
DAGTask.addRely();
preDAGTaskSet.add(preDAGTask);
preDAGTask.addNextDAGTask(DAGTask);
return this;


推荐阅读