Android - 任务封装

package com.lzh.baselib;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;


/**
 * 构造时如果传入了任务返回结果的类型,则运行会自动尝试构造不带参数的结果实例,并保存
 * 界面解析任务
 * 支持外部逻辑注入
 * 支持id标记
 * task处理结果保存在DataPackage中,键值为taskId
 * task 生命周期结束后需要统一销毁
 * 闲散的task id标号从1000开始
 */
public abstract class BaseTask implements ITask, IBaseIdItem {

    private static final IdAllocator mIdAllocator = new IdAllocator(IdAllocator.AllocateType.TYPE_SCATTERED_TASK, 100);

    private static final String TAG = "BaseTask";

    private int mTaskId = -1;
    private String mTaskDesc = "";

    protected List<BaseTask> preTasks = new ArrayList<>();

    protected List<BaseTask> postTasks = new ArrayList<>();

    private Object mLock = new Object();

    private BaseTask mOwner = null;

    private LLMResult mTempResult = null;

    private boolean mIsVisibleToSameOwner = false;

    /**
     * 创建分散的Task,****注意及时手动释放****
     *
     * @param preTask
     * @param postTask
     */
    public BaseTask(BaseTask preTask, BaseTask postTask) {
        preTasks.add(preTask);
        postTasks.add(postTask);
    }

    /**
     * 构造BaseTask实例,给每个Task分配一个Id
     */
    public BaseTask() {
        try {
            mTaskId = mIdAllocator.allocate();
        } catch (Exception e) {
            CVLog.e(TAG, "id exceeds max num:" + mIdAllocator.getMaxID());
            mIdAllocator.reset();
            try {
                mTaskId = mIdAllocator.allocate();
            } catch (Exception ex) {
                CVLog.e(TAG, "id exceeds max num:" + mIdAllocator.getMaxID());
            }
        }
        CVLog.d(TAG, "create Task id =" + mTaskId + " Task class:" + getTaskDesc());
    }

    public void readTaskParams(Package paramsPackage) throws NoSuchFieldException, IllegalAccessException {
        ParamKey[] annotations = this.getClass().getAnnotationsByType(ParamKey.class);
        for (ParamKey annotation : annotations) {
            Field field = this.getClass().getDeclaredField(annotation.name());
            field.set(this, paramsPackage.get(annotation.name(), field.getType()));
        }

    }

    public BaseTask setOwner(BaseTask owner) {
        mOwner = owner;
        return this;
    }

    public BaseTask getOwner() {
        return mOwner;
    }

    @Override
    public Object run(Package params) {
        CVLog.i(TAG, getTaskDesc() + " task start run. task id=" + mTaskId + " pre.size =" + preTasks.size() + " post.size =" + postTasks.size());
        try {
            readTaskParams(params);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }catch (NoSuchFieldException e) {
            CVLog.e(TAG, "readTaskParams error!", e);
        }
        return null;
    }

    public void setTaskDesc(String taskDesc) {
        mTaskDesc = taskDesc;
    }

    @Override
    public String getTaskDesc() {
        if (mTaskDesc.isEmpty()) {
            if (getOwner() != null) {
                return getOwner().getClass().getSimpleName() + "/" + getId() + "_" + getClass().getSimpleName();
            }
            return getId() + "_" + getClass().getName();
        }
        return mTaskDesc;
    }

    public void setPreProcess(List<BaseTask> tasks) {
        preTasks = tasks;
        for(BaseTask task : tasks){
            task.setOwner(this);
        }
    }

    public BaseTask addPre(BaseTask task) {
        preTasks.add(task);
        task.setOwner(this);
        return this;
    }

    /**
     * 向前处理列表中插入任务,原任务后移
     * @param index  负数表示倒数第index位,如-2表示插入倒数第2位
     * @param task
     * @return
     */
    public BaseTask insertPre(int index, BaseTask task) {
        if(index < 0){
            index = preTasks.size() + index + 1;
        }
        if(index < 0){
            index = 0;
            CVLog.i(TAG, "index < 0, will add at 0 ");
        }
        if(index > postTasks.size()){
            index = postTasks.size();
            CVLog.i(TAG, "index < 0, will add at " + postTasks.size());
        }
        preTasks.add(index, task);
        task.setOwner(this);
        return this;
    }

    public BaseTask setPostProcess(List<BaseTask> tasks) {
        postTasks = tasks;
        for(BaseTask task : tasks){
            task.setOwner(this);
        }
        return this;
    }

    public BaseTask addPost(BaseTask task) {
        postTasks.add(task);
        task.setOwner(this);
        return this;
    }

    /**
     * 向前处理列表中插入任务,原任务后移
     * @param index  负数表示倒数第index位,如-2表示插入倒数第2位
     * @param task
     * @return
     */
    public BaseTask insertPost(int index, BaseTask task) {
        if(index < 0){
            index = postTasks.size() + index + 1;
            CVLog.i(TAG, "after transform, index = " + index);
        }
        if(index < 0){
            index = 0;
            CVLog.i(TAG, "index < 0, will add at 0 ");
        }
        if(index > postTasks.size()){
            index = postTasks.size();
            CVLog.i(TAG, "index < 0, will add at " + postTasks.size());
        }
        postTasks.add(index, task);
        task.setOwner(this);
        return this;
    }


    public void updatePre(Class<?> oldTaskType, BaseTask newTask) {
        for (int i = 0; i < preTasks.size(); i++) {
            if (preTasks.get(i).getClass().equals(oldTaskType)) {
                CVLog.d(TAG, "update pre task:" + preTasks.get(i).getTaskDesc() + "to" + newTask.getTaskDesc());
                preTasks.get(i).release();
                preTasks.set(i, newTask);
                newTask.setOwner(this);
            }
        }
    }

    public void updatePost(Class<?> oldTaskType, BaseTask newTask) {
        for (int i = 0; i < postTasks.size(); i++) {
            if (postTasks.get(i).getClass().equals(oldTaskType)) {
                postTasks.get(i).release();
                CVLog.d(TAG, "update post task:" + newTask.getTaskDesc());
                postTasks.set(i, newTask);
                newTask.setOwner(this);
            }
        }
    }

    @Override
    public int getTaskState() {
        return 0;
    }

    @Override
    public void release() {
        CVLog.i(TAG, "release task:" + mTaskId + " taskClass: " + this.getClass().getName());
        synchronized (mLock) {
            for (BaseTask task : preTasks) {
                task.release();
            }
            for (BaseTask task : postTasks) {
                task.release();
            }
            Environment.getInstance().remove(getId());
        }

    }

    public void sendTo(BaseTask taskOwner, Package<String> messages) {
        CVLog.d(TAG, "send to :" + taskOwner.getTaskDesc());
        taskOwner.run(messages);
    }

    public void receiveFrom(BaseTask taskOwner, Package<String> messages) {
        CVLog.d(TAG, "receive from :" + taskOwner.getTaskDesc());
    }

    @Override
    public void setId(int id) {
        mTaskId = id;
    }

    @Override
    public int getId() {
        return mTaskId;
    }

    @Override
    public void destroy() {
        CVLog.i(TAG, "destroy task:" + mTaskId + " taskClass: " + this.getClass().getName());
        release();
        preTasks.clear();
        postTasks.clear();
    }

    public  <T> T extractFromEnv(Class<T> resultClazz) {
        return  Environment.extract(getId(), resultClazz);
    }

    public  <T> ArrayList<T> extractListFromEnv(Class<T> resultClazz) {
        return  Environment.extractList(getId(), resultClazz);
    }


    public void syncToEnv(Object result){
        Environment.append(getId(), result);
    }

    /**
     * 递归添加子任务结果暂存到父任务中,保持子任务缓存结果对父级任务可见
     * @param key  子任务结果保存key值
     * @param result 子任务结果
     */
    public void addSubResult(String key, Object result){
        if(mTempResult == null ){
            mTempResult = new LLMResult();
        }
        mTempResult.put(key, result);
        if(mOwner != null){
            mOwner.addSubResult(key, result);
        }
    }

    public Object retrieveCache(String key){
        if(mTempResult != null ){
            Object res = mTempResult.get(key);
            if(res!=null){
                return  res;
            }else if(isVisibleToSameOwner() && mOwner != null){
                return mOwner.retrieveCache(key);
            }
        }
        return null;
    }

    public <T> T retrieveCache(String key, Class<T> targetClazz){
        if(mTempResult != null ){
            T res = mTempResult.get(key, targetClazz);
            if(res!=null){
                return  res;
            }else if(isVisibleToSameOwner() && mOwner != null){
                return mOwner.retrieveCache(key, targetClazz);
            }
        }
        return null;
    }

    /**
     * (慎用)默认key值位result的类名,仅适用于添加自定义
     * @param result
     */
    public void appendCache(Object result){
        if(mTempResult == null ){
            mTempResult = new LLMResult();
        }
        CVLog.i("lzhDebug", "appendCache :" + result.getClass().getSimpleName());
        mTempResult.put(result.getClass().getSimpleName(), result);
        if(mOwner != null){
            mOwner.addSubResult(result.getClass().getSimpleName(), result);
        }
    }

    /**
     * 从任务结果中获取子任务结果, 默认key值为结果类名
     * @param targetClazz
     */
    public <T> T retrieveCache(Class<T> targetClazz){
        if(mTempResult != null ){
            T res = mTempResult.get(targetClazz.getSimpleName(), targetClazz);
            if(res!=null){
                return  res;
            }else if(isVisibleToSameOwner() && mOwner!=null){
                CVLog.i("lzhDebug", "retrieveCache in current task null:" + targetClazz.getSimpleName());
                return mOwner.retrieveCache(targetClazz);
            }
        }
        CVLog.i(TAG, "retrieveCache null:" + targetClazz.getSimpleName());
        return null;
    }

    public <T> ArrayList<T> retrieveCacheAsList(Class<T> targetClazz){
        if(mTempResult != null ){
            ArrayList<T> res = mTempResult.getArrayList(targetClazz.getSimpleName(), targetClazz);
            if(res!=null){
                return  res;
            }else if(isVisibleToSameOwner() && mOwner != null){
                return mOwner.retrieveCacheAsList(targetClazz);
            }
        }
        return null;
    }

    public <T> T[] retrieveCacheAsArray(Class<T> targetClazz){
        if(mTempResult != null ){
            T[] res = mTempResult.getArrays(targetClazz.getSimpleName(), targetClazz);
            if(res!=null){
                return  res;
            }else if(isVisibleToSameOwner() && mOwner != null){
                return mOwner.retrieveCacheAsArray(targetClazz);
            }
        }
        return null;
    }

    public boolean isVisibleToSameOwner() {
        return mIsVisibleToSameOwner;
    }

    public void setVisibleToSameOwner(boolean visibleToSameOwner) {
        mIsVisibleToSameOwner = visibleToSameOwner;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值