package com.banking.xc.utils;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.zip.GZIPInputStream;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import skytv_com.banking.enjoymovie.MyApplication;
import skytv_com.banking.enjoymovie.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import com.banking.xc.config.CacheTimeConfig;
import com.banking.xc.config.Configuration;
import com.banking.xc.utils.FileService.Directory;
import com.banking.xc.utils.MyActivity.DestroyListener;
import com.banking.xc.utils.thread.PooledThread;
import com.banking.xc.utils.ui.DialogController;
import com.banking.xc.utils.webService.request.XCRequest;
import com.banking.xc.utils.webService.util.WebServiceConnect;
public abstract class HttpGroup implements DestroyListener {
private static int httpIdCounter = 0;
private static final int connectTimeout = Integer.parseInt(Configuration
.getProperty(Configuration.CONNECT_TIMEOUT));// 连接超时
private static final int connectTimeoutForWIFI = Integer
.parseInt(Configuration
.getProperty(Configuration.CONNECT_TIMEOUT_FOR_WIFI));// 连接超时
private static final int readTimeout = Integer.parseInt(Configuration
.getProperty(Configuration.READ_TIMEOUT));// 读取超时
private static final int readTimeoutForWIFI = Integer
.parseInt(Configuration
.getProperty(Configuration.READ_TIMEOUT_FOR_WIFI));// 读取超时
private static String charset = "GBK";// 编码 UTF-8
private static final int attempts = Integer.parseInt(Configuration
.getProperty(Configuration.ATTEMPTS));// 尝试次数
private static final int attemptsTime = Integer.parseInt(Configuration
.getProperty(Configuration.ATTEMPTS_TIME));// 尝试的间隔时间
protected int httpCount = 0;// 组的任务数量
protected HttpGroupSetting httpGroupSetting;
protected int priority = 1;
protected int type = 1;
AlertDialog alertDialog;
// 设置是否带上client的访问信息
private static final HashMap<MyActivity, ArrayList<HttpRequest>> alertDialogStateMap = new HashMap<MyActivity, ArrayList<HttpRequest>>();
public HttpGroup(HttpGroupSetting setting) {
Log.d("HttpGroup", "HttpGroup cons");
this.httpGroupSetting = setting;
this.priority = setting.getPriority();
this.type = setting.getType();
}
abstract protected void execute(HttpRequest httpRequest);
/**
* 每次提供的httpSetting都应该是新的,不要同一个httpSetting多次提供给网络层
*/
public HttpRequest add(final HttpSetting httpSetting) {
// 给每个网络请求派发一个运行时标识符
httpIdCounter = httpIdCounter + 1;
httpSetting.setId(httpIdCounter);
tryEffect(httpSetting);
final HttpRequest httpRequest = new HttpRequest(httpSetting);
final OnReadyListener onReadyListener = httpSetting
.getOnReadyListener();
if (null != onReadyListener) {
new Thread() {
@Override
public void run() {
onReadyListener.onReady(httpSetting);
if (httpSetting.isReady()) {
executeAddedRequest(httpRequest);// 准备好参数才继续
} else {// 否则没有准备好,抛出一个error,给调用者
final HttpError httpError = new HttpError(
new Exception(
HttpError.EXCEPTION_MESSAGE_NO_READY));
httpSetting.onError(httpError);
}
}
}.start();
} else {
executeAddedRequest(httpRequest);// 直接继续
}
return httpRequest;
}
public void executeAddedRequest(HttpRequest httpRequest) {
HttpSetting httpSetting = httpRequest.getHttpSetting();
if (Log.I && null != httpSetting.getFunctionId()) {
Log.i("HttpGroup", "id:" + httpSetting.getId()
+ "- functionId -->> " + httpSetting.getFunctionId());
}
// 数据类型(因为优先级提前,因此数据类型也要提前)
if (httpSetting.getType() == 0) {
httpSetting.setType(type);
}
// 优先级(一定要提前到这里处理,因为要赶在加入线程池之前)
if (httpSetting.getPriority() == 0) {
httpSetting.setPriority(priority);
}
// 默认优先级
if (httpSetting.getPriority() == 0) {// 可继承
switch (httpSetting.getType()) {
case HttpGroupSetting.TYPE_JSON:// 如果是 JSON
httpSetting.setPriority(HttpGroupSetting.PRIORITY_JSON);
break;
case HttpGroupSetting.TYPE_IMAGE:// 如果是图片
httpSetting.setPriority(HttpGroupSetting.PRIORITY_IMAGE);
break;
case HttpGroupSetting.TYPE_FILE:// 如果是文件
httpSetting.setPriority(HttpGroupSetting.PRIORITY_FILE);
break;
}
}
execute(httpRequest);// 马上交给线程处理。在此之前还是UI线程。
}
/**
* 如果要求默认效果,而且效果状态为未处理,并且所关联 activity 非空,才加上效果。
*/
private void tryEffect(HttpSetting httpSetting) {
MyActivity myActivity = httpSetting.getMyActivity();// httpGroupSetting.getMyActivity();
Activity activity = httpSetting.getActivity();// httpGroupSetting.getMyActivity();
if (Log.D) {
Log.d("", "myActivity==null" + (myActivity == null));
}
if (HttpSetting.EFFECT_DEFAULT == httpSetting.getEffect() && // 需要默认效果
HttpSetting.EFFECT_STATE_NO == httpSetting.getEffectState()// 而且效果状态为未处理
) {// 并且所关联 activity 非空
if (null != myActivity) {
if (Log.D) {
Log.d("", "doeffect");
}
DefaultEffectHttpListener effectListener = new DefaultEffectHttpListener(
httpSetting, myActivity);
httpSetting.setListener(effectListener);
} else {
if (activity != null) {
if (Log.D) {
Log.d("", "doeffect 2");
}
DefaultEffectHttpListener effectListener = new DefaultEffectHttpListener(
httpSetting, activity);
httpSetting.setListener(effectListener);
}
}
}
}
@Override
public void onDestroy() {
}
/**
* 异步池组
*/
public static class HttpGroupaAsynPool extends HttpGroup {
//
public HttpGroupaAsynPool(HttpGroupSetting setting) {
super(setting);
}
/*
* public HttpGroupaAsynPool(int type,int j) { super(type); }
*/
@Override
public void execute(final HttpRequest httpRequest) {
// 先放到第一线程池中,避免同时处理多个任务引起手机速度降低,这个池里也区分线
Runnable runnable = new Runnable() {
@Override
public void run() {
httpCount++;
// onReady
if (httpCount < 1) {// 通知组开始
HttpGroupaAsynPool.this.onStart();
}
httpRequest.noNeedConnectionHandler();// 先执行不需要连网的任务
if (httpRequest.isNeedConnection) {// 需要连网取数据
final Runnable taskRunnable = new Runnable() {
@Override
public void run() {
httpRequest.needConnectionHandler();
}
};
if (httpRequest.getHttpSetting().isTopPriority()) {
new Thread(taskRunnable).start();
} else {
if (httpRequest.getHttpSetting().getPriority() == HttpGroupSetting.PRIORITY_JSON) {// json放到第二个线程池里
PooledThread.getSecondThreadPool().offerTask(
taskRunnable,
httpRequest.getHttpSetting()
.getPriority());
} else {// 图片和file放第三线程池里
PooledThread.getThirdThreadPool().offerTask(
taskRunnable,
httpRequest.getHttpSetting()
.getPriority());
}
}
}
}
};
if (httpRequest.getHttpSetting().isTopPriority()) {
new Thread(runnable).start();
} else {
PooledThread.getFirstThreadPool().offerTask(runnable,
httpRequest.getHttpSetting().getPriority());
}
}
}
interface Handler {
void run();
}
/**
* 停止控制器
*/
public interface StopController {
void stop();
boolean isStop();
}
public interface CompleteListener {
void onComplete(Bundle bundle);
}
/**
* 请求
*/
public class HttpRequest implements StopController {
// 停止控制器
private boolean stopFlag;
public boolean isStop() {
return stopFlag;
}
public void stop() {
stopFlag = true;
}
// 停止控制器
protected HttpSetting httpSetting;
protected HttpURLConnection conn;
protected InputStream inputStream;
protected HttpResponse httpResponse = new HttpResponse();
// 对象实例化,较大改动
protected ArrayList<HttpError> errorList;
protected boolean manualRetry;
/**
* 代表着本次连接是失败的,不可用。
*/
protected boolean connectionRetry;
private int currentHandlerIndex = 0;
private String thirdHost;
private ArrayList<HttpError> getErrorList() {
if (null == errorList) {
errorList = new ArrayList<HttpError>();
}
return errorList;
}
private HttpError getLastError() {
ArrayList<HttpError> errorList = getErrorList();
int size = errorList.size();
if (size > 0) {
return errorList.get(size - 1);
}
return null;
}
private void clearErrorList() {
getErrorList().clear();
}
public boolean isLastError() {// 判断是否多次尝试失败
boolean result = null != errorList
&& !(errorList.size() < httpSetting.getAttempts());// 需要与httpSetting的重试资料来判断
if (!result) {
HttpError lastError = getLastError();
if (null != lastError && lastError.isNoRetry()) {
result = true;
}
}
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- isLastError() -->> " + result);
}
return result;
}
public void throwError(HttpError error) {
ArrayList<HttpError> errorList = getErrorList();
errorList.add(error);
error.setTimes(errorList.size());
if (Log.I) {
Log.i("HttpGroup", "id:" + httpSetting.getId()
+ "- HttpError -->> " + error);
}
// 检查用户交互
checkErrorInteraction();
}
/**
* 检查用户交互
*/
public void checkErrorInteraction() {
/*
* 存在2种需要与用户交互的异常
*/
HttpError lastError = getLastError();
if (null != lastError && // 认证WIFI
HttpError.EXCEPTION == lastError.getErrorCode() && //
HttpError.EXCEPTION_MESSAGE_ATTESTATION_WIFI
.equals(lastError.getException().getMessage())) {
alertAttestationWIFIDialog();
} else if (isLastError()) {// 如果已经达到自动尝试次数就弹出通知窗口
alertErrorDialog();
}
}
/**
* 非线程安全
*/
class HttpDialogController extends DialogController {
protected ArrayList<HttpRequest> httpRequestList;
protected MyActivity myActivity;
private boolean isSynchronizHTTP = true;// 弹框时,是否阻塞网络请求
/**
* 初始化
*/
public void init(ArrayList<HttpRequest> httpRequestList,
MyActivity myActivity) {
this.myActivity = myActivity;
this.httpRequestList = httpRequestList;
init(myActivity);
}
/**
* 重试
*/
protected void actionRetry() {
actionCommon(true);
}
/**
* 取消
*/
protected void actionCancel() {
actionCommon(false);
}
/**
* 是否阻塞网络请求
*
* @param isSynchronizHTTP
*/
public void setSynchronizHTTP(boolean isSynchronizHTTP) {
this.isSynchronizHTTP = isSynchronizHTTP;
}
/**
* 是否阻塞网络请求
*
* @return
*/
public boolean isSynchronizHTTP() {
return isSynchronizHTTP;
}
protected void actionCommon(boolean isRetry) {
if (null != alertDialog) {
alertDialog.dismiss();
}
if (Log.D) {
Log.d("HttpGroup",
"id:"
+ httpSetting.getId()
+ "- notifyUser() retry -->> httpRequestList.size() = "
+ httpRequestList.size());
}
synchronized (alertDialogStateMap) {
for (int i = 0; i < httpRequestList.size(); i++) {
HttpRequest httpRequest = httpRequestList.get(i);
if (isRetry) {
httpRequest.manualRetry = true;
}
synchronized (httpRequest) {
httpRequest.notify();
}
}
alertDialogStateMap.remove(myActivity);
}
}
}
/**
* 弹出对话窗
*/
private void notifyUser(final HttpDialogController httpDialogController) {
final MyActivity myActivity = null;// httpGroupSetting.getMyActivity();
if (null == myActivity) {// 跟界面无关的连接不弹窗
return;
}
boolean result = false;// 用于控制不要同一界面连续弹窗
ArrayList<HttpRequest> httpRequestList = null;
synchronized (alertDialogStateMap) {
httpRequestList = alertDialogStateMap.get(myActivity);// 该页面所关联的需弹窗网络异常通知
if (null == httpRequestList) {// 如果没有任何需弹窗网络异常通知
httpRequestList = new ArrayList<HttpRequest>();
alertDialogStateMap.put(myActivity, httpRequestList);
result = true;
}
httpRequestList.add(this);
}
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- notifyUser() -->> result = " + result);
}
if (result) {
// 弹出对话框
// 初始化
httpDialogController.init(httpRequestList, myActivity);
myActivity.post(new Runnable() {
@Override
public void run() {
httpDialogController.show();
}
});
}
if (httpDialogController.isSynchronizHTTP) {
// 本线程工作暂停,等待UI线程接受用户选择。
synchronized (HttpRequest.this) {
try {
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- dialog wait start -->> ");
}
HttpRequest.this.wait();
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- dialog wait end -->> ");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* s
*/
private void alertResettingDialog() {
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- alertErrorDialog() -->> ");
}
// 是否禁止通知用户处理
if (!httpSetting.isNotifyUser()) {
return;
}
if (Log.D) {
Log.d("HttpGroup", "ResettingDialog() -->> ");
}
final MyActivity myActivity = MyApplication.getInstance()
.getCurrentMyActivity();
if (myActivity == null) {
return;
}
myActivity.post(new Runnable() {
@Override
public void run() {
alertDialog = new Builder(myActivity).create();
alertDialog.setTitle("检查网络");
alertDialog.setMessage("您当前网络状况不佳,请检查下您的网络吧!");
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "设置网络",
new AlertDialog.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
Intent intent = null;
if (android.os.Build.VERSION.SDK_INT > 10) {
// 3.0以上打开设置界面,也可以直接用ACTION_WIRELESS_SETTINGS打开到wifi界面
intent = new Intent(
android.provider.Settings.ACTION_SETTINGS);
} else {
intent = new Intent(
android.provider.Settings.ACTION_WIRELESS_SETTINGS);
}
alertDialog.dismiss();
myActivity.startActivity(intent);
}
});
alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "取消",
new AlertDialog.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
myActivity.finish();
alertDialog.dismiss();
}
});
alertDialog.show();
}
});
}
/**
* 一般异常对话框
*/
private void alertErrorDialog() {
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- alertErrorDialog() -->> ");
}
// 是否禁止通知用户处理
if (!httpSetting.isNotifyUser()) {
return;
}
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- alertErrorDialog() -->> true");
}
// 弹窗通知用户
HttpDialogController httpDialogController = new HttpDialogController() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case AlertDialog.BUTTON_POSITIVE:// (左边的按钮)重试
if (httpSetting.getAlertErrorDialogType() == HttpSetting.ERROR_DIALOG_TYPE_SETUP_CANCEL) {
actionCancel();
final MyActivity myActivity = MyApplication
.getInstance().getCurrentMyActivity();
if (null != myActivity) {
Intent intent = null;
if (android.os.Build.VERSION.SDK_INT > 10) {
// 3.0以上打开设置界面,也可以直接用ACTION_WIRELESS_SETTINGS打开到wifi界面
intent = new Intent(
android.provider.Settings.ACTION_SETTINGS);
} else {
intent = new Intent(
android.provider.Settings.ACTION_WIRELESS_SETTINGS);
}
// myActivity.startActivityNoException(intent);
}
} else {
actionRetry();
}
break;
case AlertDialog.BUTTON_NEGATIVE:// (右边的按钮)取消或退出
if (httpSetting.getAlertErrorDialogType() == HttpSetting.ERROR_DIALOG_TYPE_BACK_RETRY) {
final MyActivity myActivity = MyApplication
.getInstance().getCurrentMyActivity();
if (null != myActivity) {
myActivity.finish();
}
} else {
actionCancel();
}
break;
}
}
};
httpDialogController.setCanceledOnTouchOutside(false);
httpDialogController.setMessage("网络不佳");
if (httpSetting.getAlertErrorDialogType() == HttpSetting.ERROR_DIALOG_TYPE_DEFAULT) {
// 重试按钮
httpDialogController.setPositiveButton(MyApplication
.getInstance().getText(R.string.retry));
// 退出或取消按钮
httpDialogController
.setNegativeButton(MyApplication
.getInstance()
.getText(
httpSetting.isNotifyUserWithExit() ? R.string.exit
: R.string.cancel));
} else if (httpSetting.getAlertErrorDialogType() == HttpSetting.ERROR_DIALOG_TYPE_ONLY_CANCEL) {
// 确定:取消
httpDialogController.setNegativeButton(MyApplication
.getInstance().getText(R.string.ok));
} else if (httpSetting.getAlertErrorDialogType() == HttpSetting.ERROR_DIALOG_TYPE_BACK_RETRY) {
// 重试
httpDialogController.setPositiveButton(MyApplication
.getInstance().getText(R.string.retry));
// 返回上一页
httpDialogController.setNegativeButton(MyApplication
.getInstance().getText(R.string.back_page));
} else if (httpSetting.getAlertErrorDialogType() == HttpSetting.ERROR_DIALOG_TYPE_SETUP_CANCEL) {
httpDialogController.setSynchronizHTTP(false);// 网络线程可直接结束掉
// 设置网络
httpDialogController.setPositiveButton(MyApplication
.getInstance().getText(R.string.go_setup));
// 取消
httpDialogController.setNegativeButton(MyApplication
.getInstance().getText(R.string.cancel));
}
notifyUser(httpDialogController);
}
/**
* 认证 WIFI 对话框
*/
private void alertAttestationWIFIDialog() {
// 弹出窗口
HttpDialogController httpDialogController = new HttpDialogController() {
private int state;
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case AlertDialog.BUTTON_POSITIVE:// (左边的按钮)确定
switch (state) {
case 0:// 第一次
if (Log.D) {
Log.d("HttpGroup",
"http dialog BUTTON_POSITIVE -->> " + 1);
}
// 改变界面和功能
state = 1;
myActivity.post(new Runnable() {// 让窗口关闭后重新显示
public void run() {
if (Log.D) {
Log.d("HttpGroup",
"http dialog change -->> ");
}
setMessage("现在是否重试?");
setPositiveButton("重试");
if (!alertDialog.isShowing()) {
alertDialog.show();
}
// 打开浏览器(这里要确保在所有UI操作之后执行)
Intent intent = new Intent(
Intent.ACTION_VIEW,
Uri.parse("http://app.360buy.com/"));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// myActivity.startActivityNoException(intent);
}
});
break;
case 1:// 第二次
if (Log.D) {
Log.d("HttpGroup",
"http dialog BUTTON_POSITIVE -->> " + 2);
}
actionRetry();
break;
}
break;
case AlertDialog.BUTTON_NEGATIVE:// (右边的按钮)取消
if (Log.D) {
Log.d("HttpGroup",
"http dialog BUTTON_NEGATIVE -->> " + 1);
}
actionCancel();
break;
}
}
};
httpDialogController.setTitle("WIFI认证");
httpDialogController.setMessage("您所连接的网络可能需要验证,现在打开浏览器进行验证?");
// (左边的按钮)重试
httpDialogController.setPositiveButton("确定");
// (右边的按钮)取消或退出
httpDialogController.setNegativeButton("取消");
notifyUser(httpDialogController);
}
private ArrayList<Handler> handlers = new ArrayList<Handler>();
public HttpRequest(HttpSetting httpSetting) {
this.httpSetting = httpSetting;
}
public boolean isNeedConnection = false;// 该请求是否要网络,并进入到线程池中
/**
* 不需要连网可执行的责任链
*/
public void noNeedConnectionHandler() {
handlers.add(firstHandler);
handlers.add(testHandler);
handlers.add(cacheHandler);
nextHandler();
}
/**
* 需要连网操作执行的责任链,需要被放入到线程池中。
*/
public void needConnectionHandler() {
if (isNeedConnection) {
handlers.clear();
handlers.add(connectionThreadPoolsHandler);
handlers.add(connectionHandler);
handlers.add(contentHandler);
nextHandler();
}
}
public HttpSetting getHttpSetting() {
return httpSetting;
}
private void nextHandler() {
int i = currentHandlerIndex;
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- nextHandler() i -->> " + currentHandlerIndex);
}
currentHandlerIndex++;
if (i < handlers.size()) {
handlers.get(i).run();
currentHandlerIndex = i;// 恢复层次指针到本层
}
}
private File findCachesFileByMd5() {
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- findCachesFileByMd5() -->> ");
}
Directory directory = null;
String fileName = httpSetting.getMd5();
// 1. 确定类型
switch (httpSetting.getType()) {
case HttpGroupSetting.TYPE_JSON: {// JSON
directory = FileService.getDirectory(FileService.JSON_DIR);
fileName += FileService.CACHE_EXT_NAME_JSON;
break;
}
case HttpGroupSetting.TYPE_IMAGE: {// IMAGE
directory = FileService.getDirectory(FileService.IMAGE_DIR);
fileName += FileService.CACHE_EXT_NAME_IMAGE;
break;
}
}
// 2. 查找文件
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- findCachesFileByMd5() directory -->> " + directory);
}
if (null == directory) {
return null;
}
File dir = directory.getDir();
if (Log.D) {
Log.d("HttpGroup",
"id:" + httpSetting.getId()
+ "- findCachesFileByMd5() dir.exists() -->> "
+ dir.exists());
}
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- findCachesFileByMd5() dir.isDirectory() -->> "
+ dir.isDirectory());
}
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- findCachesFileByMd5() dir -->> " + dir);
}
if (null != directory.getPath()) {
final String filePath = directory.getPath()
+ File.separatorChar + fileName;
final File file = new File(filePath);
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- findCachesFileByMd5() filePath -->> "
+ filePath);
}
if (file.exists()) {
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- can find caches file by md5 -->> ");
}
return file;
}
}
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- canot find caches file by md5 -->> ");
}
return null;
}
/**
* 设置纠正
*/
private Handler firstHandler = new Handler() {
@Override
public void run() {
// System.out.println("XC--> firstHandler");
// 继承组设置:
// 重试次数
if (httpSetting.getAttempts() == 0) {
httpSetting.setAttempts(attempts);
}
// 连接等待时间
if (httpSetting.getConnectTimeout() == 0) {
if (NetUtils.isWifi()) {
httpSetting.setConnectTimeout(connectTimeoutForWIFI);
} else {
httpSetting.setConnectTimeout(connectTimeout);
}
}
// 读取等待时间
if (httpSetting.getReadTimeout() == 0) {
if (NetUtils.isWifi()) {
httpSetting.setReadTimeout(readTimeoutForWIFI);
} else {
httpSetting.setReadTimeout(readTimeout);
}
}
// 默认缓存
if (httpSetting.getType() == HttpGroupSetting.TYPE_IMAGE) {// 如果是图片
httpSetting.setLocalFileCache(true);
httpSetting.setLocalFileCacheTime(CacheTimeConfig.IMAGE);// 图片默认缓存一天
}
// 全局初始化
if (httpSetting.getType() == HttpGroupSetting.TYPE_IMAGE) {// 如果是图片
httpSetting.setNeedGlobalInitialization(false);
}
// 组里面的连接累计量
addMaxStep(1);
// System.out.println("httpSetting.getPayUrl()"+httpSetting.getPayUrl());
// 这里是图片处理
if ((TextUtils.isEmpty(httpSetting.getWholeUrl())
&& TextUtils.isEmpty(httpSetting.getImageUrl()) && TextUtils
.isEmpty(httpSetting.getFinalUrl()))) {
// System.out.println("XC--> Error because empty Url");
HttpError error = new HttpError();
error.setErrorCode(HttpError.RESPONSE_CODE);
error.setResponseCode(404);// 目前就当做404处理
throwError(error);
httpSetting.onError(getLastError());// 通知失败
return;// 根本没执行后来的?
} else {
nextHandler();
callBack();
}
}
};
// 回调
private void callBack() {
if (isNeedConnection) {// 本请求没有完成,还需要进入到线程池中连接网络,不执行以下回调
return;
}
addCompletesCount();
if (isLastError()) {
if (Log.I) {
Log.i("HttpGroup", "id:" + httpSetting.getId()
+ "- onError -->> ");
}
httpSetting.onError(getLastError());// 通知失败
} else {
if (Log.I) {
Log.i("HttpGroup", "id:" + httpSetting.getId()
+ "- onEnd -->> ");
}
addStep(1);
httpSetting.onEnd(httpResponse);// 通知成功
}
};
// interface HttpTestMappers {
//
// boolean
//
// }
/**
* 测试
*/
private Handler testHandler = new Handler() {
@Override
public void run() {
nextHandler();
}
};
/**
* 缓存
*/
private Handler cacheHandler = new Handler() {
@Override
public void run() {
// System.out.println("XC--> cachehandler");
File cachesFile = null;
if (httpSetting.getCacheMode() != HttpSetting.CACHE_MODE_ONLY_NET
&& httpSetting.isLocalFileCache()
&& null != (cachesFile = findCachesFileByMd5())) {// 如果有缓存文件就走缓存
long localFileCacheTime = httpSetting
.getLocalFileCacheTime();
if (localFileCacheTime != 0) {// 超出有效期
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- local file cache time out -->> ");
}
doNetAndCache();
return;
}
httpResponse = new HttpResponse();
switch (httpSetting.getType()) {
case HttpGroupSetting.TYPE_JSON: {
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- read json file -->> ");
}
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(cachesFile);
httpResponse.setString(IOUtil.readAsString(
inputStream, charset));
} catch (Exception e) {
e.printStackTrace();
cachesFile.delete();
httpResponse = null;
doNetAndCache();
} finally {
if (null != inputStream) {
try {
inputStream.close();
} catch (Exception e) {
}
}
}
break;
}
case HttpGroupSetting.TYPE_IMAGE: {// IMAGE
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- read image file -->> ");
}
try {
httpResponse.setLength(cachesFile.length());
httpResponse.setSaveFile(cachesFile);// 图片需要保存File对象,用于取图片存储目录
if (httpSetting.isNeedShareImage()) {// 需要将缓存图片存成共享
final String shareImagePath = FileService
.saveShareImage(cachesFile);
httpResponse.setShareImagePath(shareImagePath);
}
} catch (Throwable e) {
cachesFile.delete();
httpResponse = null;
doNetAndCache();
}
break;
}
}
} else {
doNetAndCache();
}
}
};
/**
* 通知需要访问网络
*/
private void doNetAndCache() {
// System.out.println("XC--> doNetAndCache()");
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- doNetAndCache() -->> ");
}
// 如果要求只依靠缓存,那么直接走onError。
if (HttpSetting.CACHE_MODE_ONLY_CACHE == httpSetting.getCacheMode()) {
HttpError httpError = new HttpError(new Exception(
HttpError.EXCEPTION_MESSAGE_NO_CACHE));
httpError.setNoRetry(true);
throwError(httpError);
return;
}
isNeedConnection = true;// 需要进入到线程池中网络取数据
if (Log.I) {
Log.i("HttpGroup", "id:" + httpSetting.getId()
+ "- onStart -->> ");
}
// 开始访问网络了,真正开始了,才打开遮罩
httpSetting.onStart();// 通知开始(遮罩要在)
}
/**
* 保存
*/
private void saveCache() {
if (isLastError()) {
return;
}
// 存储
if (httpSetting.isLocalFileCache()) {
switch (httpSetting.getType()) {
case HttpGroupSetting.TYPE_JSON: {// JSON
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- save json file start -->> ");
}
Directory directory = FileService
.getDirectory(FileService.JSON_DIR);
if (null != directory) {
String fileName = httpSetting.getMd5()
+ FileService.CACHE_EXT_NAME_JSON;
if (null == httpResponse) {
return;
}
String fileContent = httpResponse.getString();
boolean result = FileService.saveToSDCardWithType(
directory, fileName, fileContent,
FileService.JSON_DIR);
if (result) {
}
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- save json file -->> " + result);
}
}
break;
}
case HttpGroupSetting.TYPE_IMAGE: {// IMAGE
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- save image file start -->> ");
}
Directory directory = FileService
.getDirectory(FileService.IMAGE_DIR);
if (null != directory) {
String fileName = httpSetting.getMd5()
+ FileService.CACHE_EXT_NAME_IMAGE;
if (null == httpResponse) {
return;
}
byte[] fileContent = httpResponse.getInputData();
boolean result = FileService.saveToSDCardWithType(
directory, fileName, fileContent,
FileService.IMAGE_DIR);
if (result) {
httpResponse.setSaveFile(null);// 图片需要保存File对象,用于取图片存储目录
if (httpSetting.isNeedShareImage()) {// 需要将缓存图片存成共享
final String shareImagePath = FileService
.saveShareImage(null);
httpResponse.setShareImagePath(shareImagePath);
}
}
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- save image file -->> " + result);
}
}
break;
}
}
}
}
/**
* 进入线程池的第一个handler
*/
private Handler connectionThreadPoolsHandler = new Handler() {
@Override
public void run() {
// System.out.println("XC--> connectionThreadPoolsHandler");
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- connectionThreadPoolsHandler -->> ");
}
isNeedConnection = false;// 已进入到线程池,还原为false
nextHandler();
// saveCache();// 保存缓存文件
callBack();// 回调
}
};
/**
* 这里要加入重试,真正的网络请求开始
*/
private Handler connectionHandler = new Handler() {
@Override
public void run() {
if (Log.D) {
Log.d("HttpGroup", "connectionHandler");
}
try {
if (httpSetting.getType() == HttpGroupSetting.TYPE_JSON) {
if (Log.D) {
Log.d("HttpGroup",
"httpSetting.getType()==HttpGroupSetting.TYPE_JSON");
}
handleBookByHttp();
} else {
handleImageByHttp();
}
} catch (Exception e) {
}
}
};
public void handleImageByHttp() {
String urlStr = httpSetting.getImageUrl();
try {
URL url = new URL(urlStr);
conn = (HttpURLConnection) url.openConnection();
handleGetOrPost();
} catch (Exception e) {
}
}
public void handleBookByHttp() {
String urlStr = httpSetting.getFinalUrl();
Log.d("HttpGroup", "handleBookByHttp url:"+urlStr);
try {
URL url = new URL(urlStr);
conn = (HttpURLConnection) url.openConnection();
handleGetOrPost();
} catch (Exception e) {
}
}
private void handleGetOrPost() throws Exception {
get();
conn.setConnectTimeout(httpSetting.getConnectTimeout());
conn.setReadTimeout(httpSetting.getReadTimeout());
conn.setRequestProperty("Charset", charset);
conn.setRequestProperty("Accept-Encoding", "gzip,deflate");// 客户端支持gzip
connectionHandler2();
}
/**
* GET 请求
*/
private void get() throws Exception {
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- get() -->> ");
}
httpResponse = new HttpResponse(conn);
conn.setRequestMethod("GET");
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- get() -->> ok");
}
}
/**
* POST 请求
*/
private void post() throws Exception {
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- post() -->> ");
}
httpResponse = new HttpResponse(conn);
conn.setRequestMethod("POST");
conn.setDoOutput(true);
byte[] data = null;
if (this.httpSetting.getMapParams() == null) {
data = ((String) "body=").getBytes();
} else {
StringBuilder sb = new StringBuilder();
// sb.append("<soap:Body><Request xmlns=\"http://ctrip.com/\"><requestXML>");
// sb.append("<Request><Header AllianceID=\"5208\" SID=\"123887\" TimeStamp=\"1363920604\" RequestType=\"GroupProductList\" Signature=\"52CC356E6308F116AC4D4CBCD3EFAC3E\" />");
sb.append("<PaymentEntryRequest>");
Map<String, String> mapParams = this.httpSetting.getMapParams();
Set<String> keySet = mapParams.keySet();
for (Iterator<String> iterator = keySet.iterator(); iterator
.hasNext();) {
String key = (String) iterator.next();
/*
* if ("functionId".equals(key)) { continue; }
*/
String value = mapParams.get(key);
if (Log.I) {
Log.i("HttpGroup", "id:" + httpSetting.getId()
+ "- param key and value -->> " + key + ":"
+ value);
}
/*
* sb.append(key).append("=").append(value); if
* (iterator.hasNext()) { sb.append("&"); }
*/
sb.append("<" + key + ">");
sb.append(value);
sb.append("</" + key + ">");
}
sb.append("</PaymentEntryRequest>");
// sb.append("</Request>");
// sb.append("</requestXML></Request></soap:Body>");
if (Log.D) {
Log.d("httpGroup", "id:" + httpSetting.getId()
+ "sb.toString()" + sb.toString());
}
data = sb.toString().getBytes();
}
conn.setRequestProperty("Content-Length",
String.valueOf(data.length));
conn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- post() -->> 1");
}
DataOutputStream outStream = new DataOutputStream(
conn.getOutputStream());
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- post() -->> 2");
}
outStream.write(data);
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- post() -->> ready");
}
outStream.flush();
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- post() -->> ok");
}
}
/**
*
*/
protected void connectionHandler2() {
try {
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- connectionHandler2() -->> ");
}
conn.connect();
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- ResponseCode() -->> ");
}
// 保存头字段
//httpResponse.setHeaderFields(conn.getHeaderFields());
// 打印所有头字段
/*if (Log.D) {
try {
Map<String, List<String>> headerFields = conn
.getHeaderFields();// TODO:headerFields有可能为null
Set<Entry<String, List<String>>> entrySet = headerFields
.entrySet();
JSONObject jsonObject = new JSONObject();
for (Entry<String, List<String>> entry : entrySet) {
String name = (null == entry.getKey() ? "<null>"
: entry.getKey());
String value = new JSONArray(entry.getValue())
.toString();
jsonObject.put(name, value);
}
Log.d("HttpGroup",
"id:" + httpSetting.getId()
+ "- headerFields -->> "
+ jsonObject.toString());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}*/
httpResponse.setCode(conn.getResponseCode());
/*String inputStreamString = "null";
try {
inputStreamString = IOUtil.readAsString(conn.getInputStream(),
charset, ioProgressListener);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.d("HttpGroup","inputString init...->"+inputStreamString);*/
// 长度
httpResponse.setLength(conn.getContentLength());
HttpGroup.this.addMaxProgress(Long.valueOf(
httpResponse.getLength()).intValue());// 更新组进度上限
// 类型
httpResponse.setType(conn.getContentType());
if (httpResponse.getCode() != HttpURLConnection.HTTP_OK) {
HttpError error = new HttpError();
error.setErrorCode(HttpError.RESPONSE_CODE);
error.setResponseCode(httpResponse.getCode());
throwError(error);
connectionRetry = true;// 重试
return;
}
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- ResponseCode() -->> ok");
}
// 输入流
InputStream is = null;
// 支持gzip
String encoding = conn.getHeaderField("Content-Encoding");
if ("gzip".equals(encoding)) {
is = new GZIPInputStream(conn.getInputStream());
} else {
is = conn.getInputStream();
}
if (is != null) {
// System.out.println("XC is is not null");
} else {
// System.out.println("XC is is null");
}
httpResponse.setInputStream(is);
// try 为了保证释放 InputStream
try {
// 下一步
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- ResponseCode() -->> ok nextHandler()");
}
nextHandler();
} finally {
try {
if (null != httpResponse.getInputStream()) {
httpResponse.getInputStream().close();
httpResponse.setInputStream(null);// 去掉这个唯一的
// InputStream
// 持有
}
if (null != conn) {
conn.disconnect();
conn = null;
// HttpResponse 里的 conn 暂时留着,用于方便事后排错或查询里面设定的属性 TODO
}
} catch (Exception e) {
}
}
} catch (Exception e) {
e.printStackTrace();
if (e instanceof SocketTimeoutException) {// 连接超时
HttpError error = new HttpError();
error.setErrorCode(HttpError.TIME_OUT);
throwError(error);
} else {// 其它
HttpError httpError = new HttpError(e);
throwError(httpError);
}
connectionRetry = true;// 重试
return;
}
}
/**
* 派发内容处理
*/
private Handler contentHandler = new Handler() {
@Override
public void run() {
// if()
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- contentHandler -->>");
Log.d("HttpGroup",
"httpSetting.getType()==:" + httpSetting.getType());
}
try {
if (httpSetting.getType() == HttpGroupSetting.TYPE_JSON) {
InputStream is = httpResponse.getInputStream();
String inputStreamString = "null";
try {
inputStreamString = IOUtil.readAsString(is,
charset, ioProgressListener);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "-httpGroup inputStreamString my -->> "
+ inputStreamString);
}
httpResponse.setString(inputStreamString);
/*try {
JSONObjectProxy jsProxy = new JSONObjectProxy(
new JSONObject(httpResponse.getString()));
httpResponse.setJsonObject(jsProxy);
} catch (JSONException e) {// 根本不是 json 格式
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- Can not format json -->> ", e);
}
HttpError httpError = new HttpError(e);
throwError(httpError);
connectionRetry = true;// 重试
return;
}*/
return;
} else if (httpSetting.getType() == HttpGroupSetting.TYPE_IMAGE) {
imageContent();
} else if (httpSetting.getType() == HttpGroupSetting.TYPE_FILE) {
// fileContent();
}
httpResponse.clean();
} catch (Exception e) {
HttpError httpError = new HttpError(e);
throwError(httpError);
connectionRetry = true;// 重试
return;
}
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- contentHandler -->> ok");
}
}
};
// 读取进度监听器
private IOUtil.ProgressListener ioProgressListener = new IOUtil.ProgressListener() {
@Override
public void notify(int incremental, int cumulant) {
addProgress(incremental);// 组进度
httpSetting.onProgress(Long.valueOf(httpResponse.getLength())
.intValue(), cumulant);// 请求进度
}
};
// 连接完毕继续监听器
private HttpGroup.CompleteListener continueListener = new HttpGroup.CompleteListener() {
@Override
public void onComplete(Bundle bundle) {
synchronized (HttpRequest.this) {
HttpRequest.this.notify();
}
}
};
/**
* image 内容处理
*/
private void imageContent() throws Exception {
// 头字段所示类型与期望不符时作以下处理:
if (null == httpResponse.getType()
|| !httpResponse.getType().contains("image/")) {
HttpError error = new HttpError();
error.setErrorCode(HttpError.RESPONSE_CODE);
error.setResponseCode(404);
throwError(error);
connectionRetry = true;// 重试
return;
}
// 走网络
try {
if (Log.D) {
Log.d("setInputData", "setInputData");
}
httpResponse.setInputData(IOUtil.readAsBytes(
httpResponse.getInputStream(), ioProgressListener));
} catch (Throwable e) {// 读取过程出错
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- image content connection read error -->> ", e);
}
HttpError httpError = new HttpError(e);
throwError(httpError);
connectionRetry = true;// 重试
return;
}
// 走缓存
}
/**
* file 内容处理
*/
private void fileContent() {
// 所示类型与期望不符时作以下处理:
// 管它是什么东西都尝试写到文件里面去
try {
FileGuider savePath = httpSetting.getSavePath();
if (null != savePath) {
// 确定保存路径
}
// TODO 应该判断如果 savePath 为 null
// TODO 可以而提供绝对路径,也可以提供相对路径,应该有多种方式。
savePath.setAvailableSize(httpResponse.getLength());// 所需空间大小
FileOutputStream fileOutputStream = FileService
.openFileOutput(savePath);
IOUtil.readAsFile(httpResponse.getInputStream(),
fileOutputStream, ioProgressListener, this);
File dir = MyApplication.getInstance().getFilesDir();
File apkFilePath = new File(dir, savePath.getFileName());
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- download() apkFilePath -->> " + apkFilePath);
}
if (isStop()) {
apkFilePath.delete();
}
httpResponse.setSaveFile(apkFilePath);
} catch (Exception e) {// 读取过程出错
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "- file content connection read error -->> ", e);
}
HttpError httpError = new HttpError(e);
throwError(httpError);
connectionRetry = true;// 重试
return;
}
}
/**
* 类型定位
*/
public void typeHandler() {
nextHandler();
}
/**
* @Title: getResponseJson
* @Description: 获取解密后的下发数据
* @param @param inputStreamString
* @param @return
* @return JSONObjectProxy
* @throws
*/
private JSONObjectProxy getResponseJson(String inputStreamString) {
JSONObjectProxy responseJsonObject = null;
try {
responseJsonObject = new JSONObjectProxy(new JSONObject(
inputStreamString));
String codeString = responseJsonObject.getStringOrNull("code");
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "-codeString -->> " + codeString);
}
if (codeString != null && codeString.length() > 0) {
String encContent = "";
if ("6".equals(codeString)) {
String desContent = responseJsonObject
.getStringOrNull("des");
if (Log.D) {
Log.d("HttpGroup", "id:" + httpSetting.getId()
+ "-通讯加密 desContent -->> " + desContent);
}
} else {
if ("8".equals(codeString) || "11".equals(codeString)
|| "7".equals(codeString)) {// 8:缺少sessionKey
// 11:解密请求信息失败
rsaConnectionRetry();
return null;
}
}
}
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return responseJsonObject;
}
private void rsaConnectionRetry() {
HttpError httpError = new HttpError(new Exception(
HttpError.EXCEPTION_MESSAGE_ATTESTATION_RSA));
httpError.setNoRetry(true);
throwError(httpError);
connectionRetry = true;// 重试
}
protected static final int MODULE_STATE_DISABLE = 0;// 禁用
protected static final int MODULE_STATE_ENCRYPT = 3;// 加密
}
/**
* 响应封装类
*/
public class HttpResponse {
private InputStream inputStream;
private byte[] inputData;
private SoftReference<byte[]> softReferenceInputData;
private File saveFile;
private String string;
private JSONObjectProxy jsonObject;
private HttpURLConnection httpURLConnection;
private Map<String, List<String>> headerFields;
private int code;// 响应码
private long length;// 数据量
private String type;// 媒体类型
private String shareImagePath;// 共享图片路径名
// 内存回收
private void gc() {
softReferenceInputData = new SoftReference<byte[]>(inputData);
inputData = null;
}
/**
* 当直接从缓存中取得数据而无需网络连接时,可能会使用此构造函数
*/
public HttpResponse() {
}
public HttpResponse(HttpURLConnection httpConnection) {
this.httpURLConnection = httpConnection;
}
public void clean() {
this.httpURLConnection = null;
}
public void setInputStream(InputStream inputStream) {
this.inputStream = inputStream;
}
public InputStream getInputStream() {
return inputStream;
}
/*public void setJsonObject(JSONObjectProxy jsonObject) {
this.jsonObject = jsonObject;
}
public JSONObjectProxy getJSONObject() {
return jsonObject;
}*/
public String getString() {
return string;
}
public void setString(String string) {
this.string = string;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public long getLength() {
return length;
}
public void setLength(long length) {
this.length = length;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public byte[] getInputData() {
byte[] iData = inputData;
gc();
return iData;
}
public void setInputData(byte[] inputData) {
this.inputData = inputData;
}
public File getSaveFile() {
return saveFile;
}
public void setSaveFile(File saveFile) {
this.saveFile = saveFile;
}
public Map<String, List<String>> getHeaderFields() {
return headerFields;
}
public void setHeaderFields(Map<String, List<String>> headerFields) {
this.headerFields = headerFields;
}
public String getHeaderField(String key) {
if (null == headerFields) {
return null;
}
List<String> listStr = headerFields.get(key);
if (null == listStr || listStr.size() < 1) {
return null;
}
return listStr.get(0);
}
public void setShareImagePath(String shareImagePath) {
this.shareImagePath = shareImagePath;
}
public String getShareImagePath() {
return shareImagePath;
}
}
/* 组的被子调用事件 */
protected void onStart() {
if (null != onGroupStartListener)
onGroupStartListener.onStart();
}
protected void onComplete() {
if (null != onGroupCompleteListener)
onGroupCompleteListener.onComplete();
}
private int completesCount = 0;
/**
* httpSetting的onEnd 和 onError 都调用这一个,通知调用方各请求完成
*/
protected void addCompletesCount() {
this.completesCount += 1;
if (Log.I) {
Log.i("HttpGroup", "addCompletesCount -->> " + this
+ "completesCount:" + completesCount + ", httpCount:"
+ httpCount);
}
if (completesCount == httpCount) {
onComplete();
}
}
// 为了 progress -->>
private void onProgress(int maxProgress, int progress) {
if (null != onGroupProgressListener)
onGroupProgressListener.onProgress(maxProgress, progress);
}
private int maxProgress = 0;
private int progress = 0;
protected void addMaxProgress(int maxProgress) {// TODO 多线程调用这个方法,这里可能会有线程问题
this.maxProgress += maxProgress;
onProgress(this.maxProgress, this.progress);
}
protected void addProgress(int progress) {// TODO 多线程调用这个方法,这里可能会有线程问题
this.progress += progress;
onProgress(this.maxProgress, this.progress);
}
// <<-- 为了 progress
// 为了 step -->>
private void onStep(int maxStep, int step) {
if (null != onGroupStepListener)
onGroupStepListener.onStep(maxStep, step);
}
private int maxStep = 0;
private int step = 0;
protected void addMaxStep(int maxStep) {// TODO 多线程调用这个方法,这里可能会有线程问题
this.maxStep += maxStep;
onStep(this.maxStep, this.step);
}
protected void addStep(int step) {// TODO 多线程调用这个方法,这里可能会有线程问题
this.step += step;
onStep(this.maxStep, this.step);
}
// <<-- 为了 step
/* 组监听器 - 存放 */
private OnGroupStartListener onGroupStartListener;
private OnGroupCompleteListener onGroupCompleteListener;
private OnGroupProgressListener onGroupProgressListener;
private OnGroupStepListener onGroupStepListener;
public void setOnGroupStartListener(
OnGroupStartListener onGroupStartListener) {
this.onGroupStartListener = onGroupStartListener;
}
public void setOnGroupCompleteListener(
OnGroupCompleteListener onGroupCompleteListener) {
this.onGroupCompleteListener = onGroupCompleteListener;
}
public void setOnGroupProgressListener(
OnGroupProgressListener onGroupProgressListener) {
this.onGroupProgressListener = onGroupProgressListener;
}
public void setOnGroupStepListener(OnGroupStepListener onGroupStepListener) {
this.onGroupStepListener = onGroupStepListener;
}
/* 组监听器 - 定义 */
public interface OnGroupStartListener {
void onStart();
}
public interface OnGroupCompleteListener {
void onComplete();
}
public interface OnGroupProgressListener {
void onProgress(int max, int progress);
}
public interface OnGroupStepListener {
void onStep(int max, int step);
}
/* HttpTask监听器 - 定义 */
public interface HttpTaskListener {
}
public interface OnStartListener extends HttpTaskListener {
void onStart();
}
public interface OnEndListener extends HttpTaskListener {
void onEnd(HttpResponse httpResponse);
}
public interface OnErrorListener extends HttpTaskListener {
void onError(HttpError error);
}
public interface OnReadyListener extends HttpTaskListener {
void onReady(HttpSettingParams httpSettingParams);
}
public interface OnProgressListener extends HttpTaskListener {
void onProgress(int max, int progress);
}
public interface OnCommonListener extends OnEndListener, OnErrorListener,
OnReadyListener {
}
public interface OnAllListener extends OnStartListener, OnEndListener,
OnErrorListener, OnProgressListener {
}
public interface CustomOnAllListener extends OnAllListener {
}
/**
* 错误信息封装
*/
public static class HttpError {
public static final int EXCEPTION = 0;
public static final int TIME_OUT = 1;
public static final int RESPONSE_CODE = 2;
public static final int JSON_CODE = 3;
public static final String EXCEPTION_MESSAGE_ATTESTATION_WIFI = "attestation WIFI";
public static final String EXCEPTION_MESSAGE_NO_CACHE = "no cache";
public static final String EXCEPTION_MESSAGE_ATTESTATION_RSA = "attestation RSA";
public static final String EXCEPTION_MESSAGE_NO_READY = "no ready";
/**
* 出错的方向
*/
private int errorCode;
/**
* 被捕获的responseCode
*/
private int responseCode;
/**
* 被捕获的jsonCode
*/
private int jsonCode;
/**
* 备用
*/
private String message;
/**
* 被捕获的异常
*/
private Throwable exception;
/**
* 第几次尝试
*/
private int times;
/**
* 无需重试
*/
private boolean noRetry;
private HttpResponse httpResponse;
public HttpError() {
}
public HttpError(Throwable exception) {
this.errorCode = EXCEPTION;
this.exception = exception;
}
public int getErrorCode() {
return errorCode;
}
public String getErrorCodeStr() {
switch (errorCode) {
case EXCEPTION:
return "EXCEPTION";
case TIME_OUT:
return "TIME_OUT";
case RESPONSE_CODE:
return "RESPONSE_CODE";
case JSON_CODE:
return "JSON_CODE";
default:
return "UNKNOWN";
}
}
public void setErrorCode(int errorCode) {
this.errorCode = errorCode;
}
public int getResponseCode() {
return responseCode;
}
public void setResponseCode(int responseCode) {
this.responseCode = responseCode;
}
public int getJsonCode() {
return jsonCode;
}
public void setJsonCode(int jsonCode) {
this.jsonCode = jsonCode;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Throwable getException() {
return exception;
}
public void setException(Throwable exception) {
this.exception = exception;
}
public int getTimes() {
return times;
}
public void setTimes(int times) {
this.times = times;
}
public HttpResponse getHttpResponse() {
return httpResponse;
}
public void setHttpResponse(HttpResponse httpResponse) {
this.httpResponse = httpResponse;
}
@Override
public String toString() {
if (null != getException()) {
if (Log.D) {
Log.d("HttpGroup", "HttpError Exception -->> ",
getException());
}
}
return "HttpError [errorCode=" + getErrorCodeStr() + ", exception="
+ exception + ", jsonCode=" + jsonCode + ", message="
+ message + ", responseCode=" + responseCode + ", time="
+ times + "]";
}
/**
* 是否无需重试
*/
public boolean isNoRetry() {
return noRetry;
}
/**
* 设置是否无需重试
*/
public void setNoRetry(boolean noRetry) {
this.noRetry = noRetry;
}
}
/**
* Copyright 2011 Jingdong Android Mobile Application
*
* @author lijingzuo
*
* Time: 2011-1-10 下午12:52:06
*
* Name:
*
* Description: 连接组设置封装
*/
public static class HttpGroupSetting {
public static final int PRIORITY_FILE = 500;
public static final int PRIORITY_JSON = 1000;
public static final int PRIORITY_IMAGE = 5000;
public static final int TYPE_FILE = 500;
public static final int TYPE_JSON = 1000;
public static final int TYPE_IMAGE = 5000;
private MyActivity myActivity;
private int priority;
private int type;
public MyActivity getMyActivity() {
return myActivity;
}
public void setMyActivity(MyActivity myActivity) {
this.myActivity = myActivity;
}
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
if (0 == priority) {
switch (type) {
case TYPE_JSON:
setPriority(PRIORITY_JSON);
break;
case TYPE_IMAGE:
setPriority(PRIORITY_IMAGE);
break;
}
}
}
}
public interface HttpSettingParams {
void putJsonParam(String key, Object value);
void putMapParams(String key, String value);
void setReady(boolean isReady);
}
public static class HttpSetting implements HttpSettingParams {
public static final int EFFECT_NO = 0;// 不要效果
public static final int EFFECT_DEFAULT = 1;// 默认效果
public static final int EFFECT_STATE_NO = 0;
public static final int EFFECT_STATE_YES = 1;
public static final int CACHE_MODE_AUTO = 0;
public static final int CACHE_MODE_ONLY_CACHE = 1;
public static final int CACHE_MODE_ONLY_NET = 2;
public static final int CACHE_MODE_ASSETS = 3;
public static final int ERROR_DIALOG_TYPE_DEFAULT = 0;// 默认为0
public static final int ERROR_DIALOG_TYPE_ONLY_CANCEL = 1;// 只有取消按钮
public static final int ERROR_DIALOG_TYPE_BACK_RETRY = 2;// 返回上一页和重试
public static final int ERROR_DIALOG_TYPE_SETUP_CANCEL = 3;// 设置网络和取消
private XCRequest request;
private int id;
private String imageUrl;
private String finalUrl;
private FileGuider savePath;
private JSONObject jsonParams;
private Map<String, String> mapParams;
private OnStartListener onStartListener;
private OnProgressListener onProgressListener;
private OnEndListener onEndListener;
private OnErrorListener onErrorListener;
private OnReadyListener onReadyListener;
private int connectTimeout;
private int readTimeout;
private String md5;
private int type;
private int priority;// 0:继承
private boolean notifyUser = false;
private boolean notifyUserWithExit = false;// 仅仅控制了一下文字,退出的逻辑由监听器处理。
private boolean localMemoryCache = false;
private boolean localFileCache = false;
private long localFileCacheTime = CacheTimeConfig.DEFAULT;// 0:永久保存(不允许出现,因为有无限膨胀的危险)
private boolean needGlobalInitialization = true;
private int effect = EFFECT_DEFAULT;// 0:不要效果,1:默认效果
private int effectState = EFFECT_STATE_NO;// 0:未处理,1:已处理
private int cacheMode = CACHE_MODE_AUTO;// 缓存模式。0:自动模式(有缓存用缓存,没缓存用网络),1:只使用缓存,2:只使用网络,3:打包模式(有缓存用缓存,没缓存用打包数据,没打包数据用网络)
private int attempts;// 重试次数
private String postFunctionId;
private MyActivity myActivity;
private Activity activity;
private boolean needShareImage;// 是否将缓存图片存成共享图片
private boolean isThisFunctionMustBeExcute = false; // 这个请求是否必须被执行,如果没有执行成功(即走了Error),那么将在网络情况重新连接的时候,重新发送这个请求
private boolean isTopPriority = false;// 首要任务,不会放到线程池中执行
private boolean isReady = true;// 是否真的准备好要发网络请求
private int alertErrorDialogType = ERROR_DIALOG_TYPE_DEFAULT;// 错误时的弹出框类型
public HttpSetting(XCRequest request) {
this.request = request;
}
@Deprecated
public HttpSetting() {
}
public MyActivity getMyActivity() {
return myActivity;
}
public void setMyActivity(MyActivity myActivity) {
this.myActivity = myActivity;
}
public Activity getActivity() {
return activity;
}
public void setActivity(Activity activity) {
this.activity = activity;
}
/**
* 仅仅为了保存图片http地址
*/
public void setUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public String getImageUrl() {
return this.imageUrl;
}
public XCRequest getXCRequest() {
return this.request;
}
public void setXCRequest(XCRequest request) {
this.request = request;
}
// public
public int getAlertErrorDialogType() {
return alertErrorDialogType;
}
public void setAlertErrorDialogType(int alertErrorDialogType) {
this.alertErrorDialogType = alertErrorDialogType;
}
public boolean isReady() {
return isReady;
}
@Override
public void setReady(boolean isReady) {
this.isReady = isReady;
}
public boolean isThisFunctionMustBeExcute() {
return isThisFunctionMustBeExcute;
}
public void setThisFunctionMustBeExcute(
boolean isThisFunctionMustBeExcute) {
this.isThisFunctionMustBeExcute = isThisFunctionMustBeExcute;
}
public int getAttempts() {
return attempts;
}
// 重试次数追加1次
public void appendOneAttempts() {
attempts++;
}
public void setAttempts(int attempts) {
this.attempts = attempts;
}
public String getFunctionId() {
if (request == null) {
return "";
}
return request.getRequestType();
}
public void setPostFunctionId(String s) {
postFunctionId = s;
}
public String getPostFunctionId() {
return postFunctionId;
}
public String getFinalUrl() {
return finalUrl;
}
public void setFinalUrl(String finalUrl) {
this.finalUrl = finalUrl;
}
public JSONObject getJsonParams() {
if (null == jsonParams) {
jsonParams = new JSONObject();
}
return jsonParams;
}
public void putJsonParam(String key, Object value) {
if (null == this.jsonParams) {
this.jsonParams = new JSONObject();
}
try {
this.jsonParams.put(key, value);
} catch (JSONException e) {
if (Log.D) {
Log.d("HttpGroup", "JSONException -->> ", e);
}
}
}
public Map<String, String> getMapParams() {
return mapParams;
}
/**
* 批量添加参数
*/
@Deprecated
public void setMapParams(Map<String, String> mapParams) {
if (null == mapParams) {
return;
}
Set<String> keySet = mapParams.keySet();
for (String key : keySet) {
putMapParams(key, mapParams.get(key));
}
}
public void putMapParams(String key, String value) {
if (null == this.mapParams) {
this.mapParams = new URLParamMap(charset);
}
this.mapParams.put(key, value);
}
public int getConnectTimeout() {
return connectTimeout;
}
public void setConnectTimeout(int connectTimeout) {
this.connectTimeout = connectTimeout;
}
public OnStartListener getOnStartListener() {
return onStartListener;
}
public OnProgressListener getOnProgressListener() {
return onProgressListener;
}
public OnEndListener getOnEndListener() {
return onEndListener;
}
public OnErrorListener getOnErrorListener() {
return onErrorListener;
}
public OnReadyListener getOnReadyListener() {
return onReadyListener;
}
public void setListener(HttpTaskListener httpTaskListener) {
if (httpTaskListener instanceof CustomOnAllListener) {
setEffect(0);// 没有效果
}
if (httpTaskListener instanceof DefaultEffectHttpListener) {
setEffectState(1);// 已处理
}
if (httpTaskListener instanceof OnErrorListener) {
this.onErrorListener = (OnErrorListener) httpTaskListener;
}
if (httpTaskListener instanceof OnStartListener) {
this.onStartListener = (OnStartListener) httpTaskListener;
}
if (httpTaskListener instanceof OnProgressListener) {
this.onProgressListener = (OnProgressListener) httpTaskListener;
}
if (httpTaskListener instanceof OnEndListener) {
this.onEndListener = (OnEndListener) httpTaskListener;
}
if (httpTaskListener instanceof OnReadyListener) {
this.onReadyListener = (OnReadyListener) httpTaskListener;
}
}
public void onStart() {
if (null != onStartListener) {
onStartListener.onStart();
}
}
public void onEnd(HttpResponse httpResponse) {
if (null != onEndListener) {
if (httpResponse != null) {
onEndListener.onEnd(httpResponse);
} else {
}
}
}
public void onError(HttpError httpError) {
if (null != onErrorListener) {
onErrorListener.onError(httpError);
}
}
public void onProgress(int max, int progress) {
if (null != onProgressListener) {
onProgressListener.onProgress(max, progress);
}
}
public String getWholeUrl() {
if (request == null) {
return "";
}
return request.getWholeUrl();
}
// 这儿和图片存储和获取有关
public String getMd5() {
if (null == md5) {
String urlTempStr = getWholeUrl();
if (null == urlTempStr) {
return null;
}
int start = 0;
for (int i = 0; i < 3; i++) {
start = urlTempStr.indexOf("/", start + 1);
}
if (start == -1) {
return null;
}
String urlPath = getWholeUrl().substring(start);
// if (isPost()) {
// md5 = Md5Encrypt.md5(urlPath + getJsonParams());
// } else {
md5 = Md5Encrypt.md5(urlPath);
// }
if (Log.D) {
Log.d("HttpGroup", "urlPath -->> " + urlPath + " md5 -->> "
+ md5);
}
}
return md5;
}
public void setMd5(String md5) {
this.md5 = md5;
}
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
public int getReadTimeout() {
return readTimeout;
}
public void setReadTimeout(int readTimeout) {
this.readTimeout = readTimeout;
}
public boolean isNotifyUser() {
return notifyUser;
}
public void setNotifyUser(boolean notifyUser) {
this.notifyUser = notifyUser;
}
public boolean isLocalMemoryCache() {
return localMemoryCache;
}
public void setLocalMemoryCache(boolean localMemoryCache) {
this.localMemoryCache = localMemoryCache;
}
public boolean isLocalFileCache() {
return localFileCache;
}
public void setLocalFileCache(boolean localFileCache) {
this.localFileCache = localFileCache;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public long getLocalFileCacheTime() {
return localFileCacheTime;
}
public void setLocalFileCacheTime(long localFileCacheTime) {
this.localFileCacheTime = localFileCacheTime;
}
public FileGuider getSavePath() {
return savePath;
}
/**
* 注意不要把同一个对象给多个网络连接
*/
public void setSavePath(FileGuider savePath) {
this.savePath = savePath;
}
public boolean isNotifyUserWithExit() {
return notifyUserWithExit;
}
public void setNotifyUserWithExit(boolean notifyUserOrExit) {
this.notifyUserWithExit = notifyUserOrExit;
}
public boolean isNeedGlobalInitialization() {
return needGlobalInitialization;
}
public void setNeedGlobalInitialization(boolean needGlobalInitialization) {
this.needGlobalInitialization = needGlobalInitialization;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getEffect() {
return effect;
}
public void setEffect(int effect) {
this.effect = effect;
}
public int getEffectState() {
return effectState;
}
public void setEffectState(int effectState) {
this.effectState = effectState;
}
public int getCacheMode() {
return cacheMode;
}
/**
* 缓存模式。0:自动模式(有缓存用缓存,没缓存用网络),1:只使用缓存,2:只使用网络
* CACHE_MODE_AUTO、CACHE_MODE_ONLY_CACHE、CACHE_MODE_ONLY_NET
*/
public void setCacheMode(int cacheMode) {
this.cacheMode = cacheMode;
}
public void setNeedShareImage(boolean needShareImage) {
this.needShareImage = needShareImage;
}
public boolean isNeedShareImage() {
return needShareImage;
}
public boolean isTopPriority() {
return isTopPriority;
}
public void setTopPriority(boolean isTopPriority) {
this.isTopPriority = isTopPriority;
}
}
public static String mergerUrlAndParams(String urlStr,
Map<String, String> params) {
if (null == params) {
return urlStr;
}
Set<String> keySet = params.keySet();
if (null == keySet || keySet.isEmpty()) {
return urlStr;
}
StringBuilder url = new StringBuilder(urlStr);
int i = urlStr.indexOf("?");
if (i == -1) {
url.append("?");
} else {
String queryString = urlStr.substring(i + 1);
if (!TextUtils.isEmpty(queryString) && !queryString.endsWith("&")) {
url.append("&");
}
}
for (Iterator<String> iterator = keySet.iterator(); iterator.hasNext();) {
String key = (String) iterator.next();
String value = params.get(key);
url.append(key).append("=").append(value);
if (iterator.hasNext()) {
url.append("&");
}
}
return url.toString();
}
}