package com.elphin.framework.util.http; import android.content.Context; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.DefaultHttpRequestRetryHandler; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.params.HttpProtocolParams; import java.util.ArrayList; /** * Http网络调度器 * * @author yuankai * @version 1.0 * @data 2012-7-29 */ public class HttpScheduler { // private final static String TAG = "httpTask"; /** * 网络模块上下文 */ private Context mContext = null; /** * 最大并发线程数 */ private int mMaxConcurrentCount = 2; /** * 等待队列 */ private ArrayList<HttpTask> mWaitingList = new ArrayList<HttpTask>(); /** * 正在运行的任务 */ private ArrayList<AsyncConnectThread> mRunningTasks = new ArrayList<HttpScheduler.AsyncConnectThread>(); /** * 调度器构造方法 * @param context 上下文 * @param maxConcurrentCount 最大并发线程数 */ public HttpScheduler(Context context, int maxConcurrentCount) { mContext = context; mMaxConcurrentCount = maxConcurrentCount; for(int i = 0;i < mMaxConcurrentCount; ++i) { mRunningTasks.add(new AsyncConnectThread()); } } /** * 将任务加入到网络队列中 * @param task 任务 * @return 如果参数不正确,则启动失败 */ public boolean asyncConnect(HttpTask task) { if(task == null || task.getHttpUriRequest() == null)return false; // 将任务加入到队首,后进先出 synchronized(mWaitingList) { mWaitingList.add(0, task); } // 如果当前有空档线程,则启动之 synchronized(mRunningTasks) { final int runningSize = mRunningTasks.size(); for(int i = 0;i < runningSize; ++i) { final AsyncConnectThread runningTask = mRunningTasks.get(i); if(!runningTask.isRunning()) { runningTask.setRunning(true); runningTask.start(); break; } } } return true; } /** * 停止网络任务,停止之后不会回调 * @param task 任务 */ public void cancel(HttpTask task) { if(task == null)return; // 判断waitinglist中是否有此任务 synchronized(mWaitingList) { int waitSize = mWaitingList.size(); for(int i = 0;i < waitSize; ++i) { if(mWaitingList.get(i) == task) { mWaitingList.remove(i); -- i; -- waitSize; } } } // 判断正在运行的任务是否有此任务 synchronized(mRunningTasks) { final int size = mRunningTasks.size(); for(int i = 0;i < size; ++i) { AsyncConnectThread thread = mRunningTasks.get(i); if(thread.getCurrentTask() == task) { thread.abortTask(); } } } } public void release() { // 停止所有线程,停止所有队列 synchronized(mWaitingList) { mWaitingList.clear(); } synchronized(mRunningTasks) { for(int i = 0;i < mRunningTasks.size(); ++i) { mRunningTasks.get(i).cancel(); mRunningTasks.set(i, new AsyncConnectThread()); // replace with new object } } } /** * 下载任务类 * @author yuankai * @version 1.0 * @data 2012-7-10 */ class AsyncConnectThread extends Thread { private HttpTask mHttpTask = null; // 当前正在处理的任务 private volatile boolean isRunning = false; private volatile boolean isCancel = false; private volatile boolean isAbort = false; private DefaultHttpClient mHttpClient = new DefaultHttpClient(); private HttpParams mHttpParams = new BasicHttpParams(); public void run() { while(!isCancel) { synchronized(mWaitingList) { if(mWaitingList.size() > 0) { mHttpTask = mWaitingList.remove(0); } else { break; } } HttpCallBack callBack = mHttpTask.getCallBack(); try { HttpResponse httpResponse = doConnect(mHttpTask); if(callBack != null && !isCancel && !isAbort) { callBack.onCallBack(mHttpTask, HttpCallBack.SUCCESS, httpResponse); } } catch(Exception e) { if(callBack != null && !isCancel && !isAbort) { callBack.onCallBack(mHttpTask, HttpCallBack.EXCEPTION, e); } } isAbort = false; mHttpTask = null; } synchronized(mRunningTasks) { mRunningTasks.remove(this); mRunningTasks.add(new AsyncConnectThread()); } isRunning = false; isCancel = false; } public void abortTask() { isAbort = true; if(mHttpTask != null) { mHttpTask.getHttpUriRequest().abort(); } if(mHttpParams != null) { HttpConnectionParams.setConnectionTimeout(mHttpParams, 1); HttpConnectionParams.setSoTimeout(mHttpParams, 1); } } protected HttpResponse doConnect(HttpTask task) throws Exception { mHttpParams = new BasicHttpParams(); HttpProtocolParams.setVersion(mHttpParams, HttpVersion.HTTP_1_1); HttpProtocolParams.setContentCharset(mHttpParams, "utf-8"); HttpConnectionParams.setConnectionTimeout(mHttpParams, task.getConnectTimeout()); HttpConnectionParams.setSoTimeout(mHttpParams, task.getSocketTimeout()); // 加入代理 HttpUtils.fillProxy(mContext, mHttpParams); mHttpClient = new DefaultHttpClient(mHttpParams); // 重试一次 mHttpClient.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler(2, true)); HttpResponse httpResponse = mHttpClient.execute(task.getHttpUriRequest()); return httpResponse; } public void setRunning(boolean running) { isRunning = running; } /** * 获取当前任务 * @return 任务 */ public HttpTask getCurrentTask() { return mHttpTask; } /** * 停止任务 */ public void cancel() { isCancel = true; } /** * 线程是否在运行中 * @return */ public boolean isRunning() { return isRunning; } }; }