异步任务AysncTask的初步分离

来源:互联网 发布:加微信群软件 编辑:程序博客网 时间:2024/05/22 00:49

使用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
刚芭蕾!

原创粉丝点击