异步任务AysncTask的初步分离

使用AysncTask而不是Thread之前有个博文专门讲了传送门

可是在使用AysncTask还是有诸多不便。
1. 每个任务都写一个AysncTask类,太违背重用代码的理念
2. 需要写一堆传入参数
3. 如果一个java类中需要多种后台任务,不同的AysncTask写出来以后使得java篇幅太长

我还是希望:
1. 重用重复代码
2. 不以任务名字写AysncTask内部类
3. 有个统一的启动任务入口
4. 将任务和处理任务的AysncTask分开来,任务可以用一个 final int 来区分


思考之后我是这么做的,给出思路图并贴出代码,能力有限敬听大家意见。
这里写图片描述
图中左侧是分离出来的任务处理类 右侧是具体任务启动和实现类


/**
 * Created by lzc on 2017/10/10.
 */
public class AsyncTaskExecutor {
    //饥饿 随类加载
    private static AsyncTaskExecutor ourInstance = new AsyncTaskExecutor();
    //一个Activity 或者Service中不会有太多的任务 用稀疏key-value:SparseArray 
    //保存任务号和任务引用
    private SparseArray<SeedTask> ayncTaskMapper = new SparseArray<>();

    public static AsyncTaskExecutor getInstance() {
        return ourInstance;
    }

    private AsyncTaskExecutor() {
    }
    //关注传入实体和任务号
    /**
    *
    *Entity 是web bean的基类
    */
    public void forkTaskAndExecute(Entity entity, int task, UiAsyncTaskCallBack uiAsyncTaskCallBack) {
        if (ayncTaskMapper.get(task) != null) {
            Log.d("lzc", task + "异步任务正在执行");
            return;
        }
        //不去持有Activity的强引用
        SeedTask seedTask = new SeedTask(entity, task, new WeakReference(uiAsyncTaskCallBack));
        ayncTaskMapper.put(task, seedTask);
        seedTask.execute((Void) null);
    }
    //重载方法 只关注后台逻辑
    public void forkTaskAndExecute(UiAsyncTaskCallBack uiAsyncTaskCallBack) {
        forkTaskAndExecute(null,0,uiAsyncTaskCallBack);
    }
    class SeedTask extends AsyncTask<Void, Void, Response> {
        private Entity entity;
        private int task;
        private WeakReference<UiAsyncTaskCallBack> uiAsyncTaskCallBack;

        SeedTask(Entity entity, int task, WeakReference<UiAsyncTaskCallBack> uiAsyncTaskCallBack) {
            this.entity = entity;
            this.task = task;
            this.uiAsyncTaskCallBack = uiAsyncTaskCallBack;
        }

        @Override
        protected Response doInBackground(Void... params) {
            if(uiAsyncTaskCallBack.get() == null){
                return null;
            }
            return uiAsyncTaskCallBack.get().doInBackgroud(task, entity);
        }

        @Override
        protected void onPreExecute() {
            uiAsyncTaskCallBack.get().onPreExecute(task);
        }

        @Override
        protected void onPostExecute(final Response response) {
            if(response != null){
                ayncTaskMapper.remove(task);
                uiAsyncTaskCallBack.get().onPostExecute(task, response);
            }
        }

        @Override
        protected void onCancelled() {
            ayncTaskMapper.remove(task);
        }
    }

}
/**
 * Created  on 2017/10/10.
 * Entity 起初想用泛型 但是具体UiAsyncTaskCallBack实现者的任务类型不确定
 * 所以为web实体加了统一父类  用作具体情况下的强制转型
 * 
 */

public interface UiAsyncTaskCallBack{
    void onPreExecute(int task);
    Response doInBackgroud(int task, Entity entity);
    void onPostExecute(int task, Response asyncResult);
}
//如果任务类型单一 可以用泛型省掉强制转型
public interface UiAsyncTaskCallBack<T>{
    void onPreExecute(int task);
    T doInBackgroud(int task, T entity);
    void onPostExecute(int task, T asyncResult);
}

网络任务种类比较繁杂我建立了一个接口来统一保存

public interface AysncTaskList {
    int LOGIN = 2001;
    int REGISTE = 2002;
    ...
}

我们的Activity既可以这样来发起一个任务:
Activity implements UiAsyncTaskCallBack
//类内任务
AsyncTaskExecutor.getInstance().forkTaskAndExecute(LOAD_DATA,this);
//网络任务
User user = newUser(P,N);
AsyncTaskExecutor.getInstance().forkTaskAndExecute(user ,USER_LOGIN,this);
当然网络任务如何处理user 的login是另外一个流程了,在这不表了。

Response doInBackgroud(int task, Entity entity){
//打开case 来分别处理
switch(task){
}
return response;//统一封装的返回类
}
void onPostExecute(int task, Response asyncResult){
//打开case 来分别处理
switch(task){
}
}

over
刚芭蕾!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值