一个异步网络请求模型的实现方法

在android开发中我们常常会使用要异步队列来提升用户体验,如微信中的评论、赞都是采用异步队列来实现的,最近的项目产品也要这样的实现,本方法是采用HandlerThread+阻塞队列实现。

/**
* 异步网络请求模型 有队列系统,严格按照请求序列进行
 */


public class AsynTaskManager {


private static final int NEW_REQUEST = 1;
private static final int INIT_REQUEST = 2;


/**
* 重试次数
*/
public static final int MAX_RETRY_TIME = 3;


/**

* 出现错误后的延迟时间
*/
public static final long BASE_DELAY_MILLIS = 20000;


private BlockingQueue<AsyncProviderTask> taskQueue = new LinkedBlockingQueue<AsyncProviderTask>();
private EntityManager<AsyncProviderTask> dbManager;
private HandlerThread handlerThread;
private Handler networkHandler;
private NetworkHelper.NetworkInductor networdDector = new NetworkHelper.NetworkInductor() {
@Override
public void onNetworkChanged(NetworkHelper.NetworkStatus networkStatus) {
networkHandler.sendEmptyMessageDelayed(NEW_REQUEST, BASE_DELAY_MILLIS);
}
};


private AsynTaskManager() {
dbManager = EntityManagerFactory.getInstance(ACContext.getInstance().getApplicationContext(), 1, "useraccount", null, null).getEntityManager(AsyncProviderTask.class, null);
handlerThread = new HandlerThread("AsynTaskThread");
handlerThread.start();
networkHandler = new NetworkHandler(handlerThread.getLooper());
NetworkHelper.sharedHelper().addNetworkInductor(networdDector);
networkHandler.sendEmptyMessage(INIT_REQUEST);
}


public void submitTask(NewPostEntityProvider<?> protocol) {


AsyncProviderTask task = new AsyncProviderTask(protocol);
task.store();
saveTask(task);
taskQueue.add(task);
networkHandler.sendEmptyMessage(NEW_REQUEST);
}


private void saveTask(AsyncProviderTask task) {
dbManager.saveOrUpdate(task);
}


private void deleteTask(AsyncProviderTask task) {
WhereBuilder wherebuilder = WhereBuilder.create("taskId", "=", task.taskId);
dbManager.delete(wherebuilder);
}


public void destory() {
handlerThread.quit();
taskQueue.clear();
NetworkHelper.sharedHelper().removeNetworkInductor(networdDector);
dbManager.close();


}


private class NetworkHandler extends Handler {


/**
* 错误3次以上就开始延时重试
*/
private int errorCount = 0;


private NetworkHandler(Looper looper) {
super(looper);
}


@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case INIT_REQUEST:
loadAllTask();
sendEmptyMessage(NEW_REQUEST);
break;
case NEW_REQUEST:
AsyncProviderTask task = (AsyncProviderTask) msg.obj;
if (task == null) {
try {
task = taskQueue.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (task == null)
break;
// 真实发起网络请求


task.send();
if (task.isConnectToSever()) {
// 连通网络的
deleteTask(task);
task = null;
// 重置错误计数
errorCount = 0;
} else {
errorCount++;
}
removeMessages(NEW_REQUEST);
Message oldTask = obtainMessage(NEW_REQUEST, task);
if (errorCount > MAX_RETRY_TIME) {
sendMessageDelayed(oldTask, BASE_DELAY_MILLIS * errorCount);
} else {
sendMessage(oldTask);
}
break;
default:
break;
}

}
}


private void loadAllTask() {


taskQueue.clear();
Selector selector = Selector.create();
selector.orderBy("dbId", false);
List<AsyncProviderTask> tasks = dbManager.findAll(selector);


if (tasks != null) {
taskQueue.addAll(tasks);
}


}


private static class InstanceHolder {
public static AsynTaskManager manager = new AsynTaskManager();
}


public static AsynTaskManager getInstance() {
return InstanceHolder.manager;
}

}


/**
 * @Description:对通用协议的包装,支持序列化把原来的协议转化成json格式存放,注意,对于每个协议中需要保存的字段(请求参数),要加上@Expose注解
 */


@Table(version = 1)
public class AsyncProviderTask extends NewPostEntityProvider {


    @Id( strategy = GenerationType.AUTO_INCREMENT)
    public int dbId;


    @Column
    public String taskId;
    /**
     * 用于存放协议的请求数据,暂时只支持基本数据类型
     */
    @Column
    public String paramJson;


    @Column
    public String className;




    public boolean isConnectToSever() {
        return reachServer;
    }


    public boolean reachServer;


    @Column
    public NewPostEntityProvider<?> innerProvider;




    public AsyncProviderTask(NewPostEntityProvider<?>  innerProvider)
    {
        super(innerProvider.getCallback());
        taskId = UUID.randomUUID().toString();
        this.innerProvider = innerProvider;
    }


    public AsyncProviderTask() {
    }






    public void store() {
        if( innerProvider != null) {
//            Map<String, String> ret = innerProvider.getParams();
            Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
            paramJson = gson.toJson(innerProvider);
            className = innerProvider.getClass().getCanonicalName();
        }
    }


    public void load() {
        if( paramJson == null || className == null) {
            return;
        }
        Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
        try {
            Class<?> protocolClass = Class.forName(className);
            innerProvider = (NewPostEntityProvider<?>) gson.fromJson(paramJson, protocolClass);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }


    }


    @Override
public boolean supportPost() {
return innerProvider.supportPost();
}


    
@Override
public boolean supportDesencrypt() {
return innerProvider.supportDesencrypt();
}


@Override
    public String getURL() {
        return innerProvider.getURL();
    }


    @Override
    public void onResponse(String resp) {
        innerProvider.onResponse(resp);
    }


    @Override
    final public Map<String, String> getParams() {
        Map<String, String> ret;
        if( innerProvider == null) {
            load();
        }
        if( innerProvider != null) {
            ret = innerProvider.getParams();
            return ret;
        }
       return super.getParams();
    }


    @Override
    public void send() {
        if( innerProvider == null) {
            load();
        }
       send(true);
    }


    @Override
    public void onSuccess() {
        super.onSuccess();
        NLog.d("TTT", "success %s",innerProvider.getClass().getCanonicalName());
        innerProvider.onSuccess();
        }
        //这儿成功是指与服务取得了联系,至于业务上的不成功,不算重试
        reachServer = true;
    }


    @Override
    public void onCancel() {
        super.onCancel();
        innerProvider.onCancel();
        reachServer = true;
    }


    @Override
    public void onError(int err, int statusCode) {
        super.onError(err, statusCode);
        if( statusCode > 200) {
        reachServer = true;   //这儿成功是指与服务取得了联系,至于业务上的不成功,不算重试
        }
        innerProvider.onError(err, statusCode);
    }
}


你可能感兴趣的:(一个异步网络请求模型的实现方法)