技术选型

封装思路

封装okhttp
请求参数的封装:
public class RequestParams {
public ConcurrentHashMap<String, String> urlParams = new ConcurrentHashMap<String, String>();
public ConcurrentHashMap<String, Object> fileParams = new ConcurrentHashMap<String, Object>();
public RequestParams() {
this((Map<String, String>) null);
}
public RequestParams(Map<String, String> source) {
if (source != null) {
for (Map.Entry<String, String> entry : source.entrySet()) {
put(entry.getKey(), entry.getValue());
}
}
}
public RequestParams(final String key, final String value) {
this(new HashMap<String, String>() {
{
put(key, value);
}
});
}
public void put(String key, String value) {
if (key != null && value != null) {
urlParams.put(key, value);
}
}
public void put(String key, Object object) throws FileNotFoundException {
if (key != null) {
fileParams.put(key, object);
}
}
public boolean hasParams() {
if(urlParams.size() > 0 || fileParams.size() > 0){
return true;
}
return false;
}
}
对okhttp的request的封装:
public class CommonRequest {
public static Request createPostRequest(String url, RequestParams params) {
return createPostRequest(url, params, null);
}
public static Request createPostRequest(String url, RequestParams params, RequestParams headers) {
FormBody.Builder mFormBodyBuild = new FormBody.Builder();
if (params != null) {
for (Map.Entry<String, String> entry : params.urlParams.entrySet()) {
mFormBodyBuild.add(entry.getKey(), entry.getValue());
}
}
Headers.Builder mHeaderBuild = new Headers.Builder();
if (headers != null) {
for (Map.Entry<String, String> entry : headers.urlParams.entrySet()) {
mHeaderBuild.add(entry.getKey(), entry.getValue());
}
}
FormBody mFormBody = mFormBodyBuild.build();
Headers mHeader = mHeaderBuild.build();
Request request = new Request.Builder().url(url).
post(mFormBody).
headers(mHeader)
.build();
return request;
}
public static Request createGetRequest(String url, RequestParams params) {
return createGetRequest(url, params, null);
}
public static Request createGetRequest(String url, RequestParams params, RequestParams headers) {
StringBuilder urlBuilder = new StringBuilder(url).append("?");
if (params != null) {
for (Map.Entry<String, String> entry : params.urlParams.entrySet()) {
urlBuilder.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
}
}
Headers.Builder mHeaderBuild = new Headers.Builder();
if (headers != null) {
for (Map.Entry<String, String> entry : headers.urlParams.entrySet()) {
mHeaderBuild.add(entry.getKey(), entry.getValue());
}
}
Headers mHeader = mHeaderBuild.build();
return new Request.Builder().
url(urlBuilder.substring(0, urlBuilder.length() - 1))
.get()
.headers(mHeader)
.build();
}
private static final MediaType FILE_TYPE = MediaType.parse("application/octet-stream");
public static Request createMultiPostRequest(String url, RequestParams params) {
MultipartBody.Builder requestBody = new MultipartBody.Builder();
requestBody.setType(MultipartBody.FORM);
if (params != null) {
for (Map.Entry<String, Object> entry : params.fileParams.entrySet()) {
if (entry.getValue() instanceof File) {
requestBody.addPart(Headers.of("Content-Disposition", "form-data; name=\"" + entry.getKey() + "\""),
RequestBody.create(FILE_TYPE, (File) entry.getValue()));
} else if (entry.getValue() instanceof String) {
requestBody.addPart(Headers.of("Content-Disposition", "form-data; name=\"" + entry.getKey() + "\""),
RequestBody.create(null, (String) entry.getValue()));
}
}
}
return new Request.Builder().url(url).post(requestBody.build()).build();
}
}
对JsonCallback 的封装:
* @function 专门处理JSON的回调
*/
public class CommonJsonCallback implements Callback {
protected final String RESULT_CODE = "ecode";
protected final int RESULT_CODE_VALUE = 0;
protected final String ERROR_MSG = "emsg";
protected final String EMPTY_MSG = "";
protected final int NETWORK_ERROR = -1;
protected final int JSON_ERROR = -2;
protected final int OTHER_ERROR = -3;
private Handler mDeliveryHandler;
private DisposeDataListener mListener;
private Class<?> mClass;
public CommonJsonCallback(DisposeDataHandle handle) {
this.mListener = handle.mListener;
this.mClass = handle.mClass;
this.mDeliveryHandler = new Handler(Looper.getMainLooper());
}
@Override
public void onFailure(final Call call, final IOException ioexception) {
mDeliveryHandler.post(new Runnable() {
@Override
public void run() {
mListener.onFailure(new OkHttpException(NETWORK_ERROR, ioexception));
}
});
}
@Override
public void onResponse(final Call call, final Response response) throws IOException {
final String result = response.body().string();
mDeliveryHandler.post(new Runnable() {
@Override
public void run() {
handleResponse(result);
}
});
}
private void handleResponse(Object responseObj) {
if (responseObj == null || responseObj.toString().trim().equals("")) {
mListener.onFailure(new OkHttpException(NETWORK_ERROR, EMPTY_MSG));
return;
}
try {
JSONObject result = new JSONObject(responseObj.toString());
if (mClass == null) {
mListener.onSuccess(result);
} else {
Object obj = new Gson().fromJson(responseObj.toString(), mClass);
if (obj != null) {
mListener.onSuccess(obj);
} else {
mListener.onFailure(new OkHttpException(JSON_ERROR, EMPTY_MSG));
}
}
} catch (Exception e) {
mListener.onFailure(new OkHttpException(OTHER_ERROR, e.getMessage()));
e.printStackTrace();
}
}
}
业务逻辑层真正处理的地方,包括java层异常和业务层异常:
public interface DisposeDataListener {
void onSuccess(Object responseObj);
void onFailure(Object reasonObj);
}
public class DisposeDataHandle
{
public DisposeDataListener mListener = null;
public Class<?> mClass = null;
public String mSource = null;
public DisposeDataHandle(DisposeDataListener listener)
{
this.mListener = listener;
}
public DisposeDataHandle(DisposeDataListener listener, Class<?> clazz)
{
this.mListener = listener;
this.mClass = clazz;
}
public DisposeDataHandle(DisposeDataListener listener, String source)
{
this.mListener = listener;
this.mSource = source;
}
}
自定义异常类,返回ecode,emsg到业务层:
public class OkHttpException extends Exception {
private static final long serialVersionUID = 1L;
private int ecode;
private Object emsg;
public OkHttpException(int ecode, Object emsg) {
this.ecode = ecode;
this.emsg = emsg;
}
public int getEcode() {
return ecode;
}
public Object getEmsg() {
return emsg;
}
}
专门处理文件下载回调:
public class CommonFileCallback implements Callback {
protected final int NETWORK_ERROR = -1;
protected final int IO_ERROR = -2;
protected final String EMPTY_MSG = "";
private static final int PROGRESS_MESSAGE = 0x01;
private Handler mDeliveryHandler;
private DisposeDownloadListener mListener;
private String mFilePath;
private int mProgress;
public CommonFileCallback(DisposeDataHandle handle) {
this.mListener = (DisposeDownloadListener) handle.mListener;
this.mFilePath = handle.mSource;
this.mDeliveryHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case PROGRESS_MESSAGE:
mListener.onProgress((int) msg.obj);
break;
}
}
};
}
@Override
public void onFailure(final Call call, final IOException ioexception) {
mDeliveryHandler.post(new Runnable() {
@Override
public void run() {
mListener.onFailure(new OkHttpException(NETWORK_ERROR, ioexception));
}
});
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final File file = handleResponse(response);
mDeliveryHandler.post(new Runnable() {
@Override
public void run() {
if (file != null) {
mListener.onSuccess(file);
} else {
mListener.onFailure(new OkHttpException(IO_ERROR, EMPTY_MSG));
}
}
});
}
private File handleResponse(Response response) {
if (response == null) {
return null;
}
InputStream inputStream = null;
File file = null;
FileOutputStream fos = null;
byte[] buffer = new byte[2048];
int length;
int currentLength = 0;
double sumLength;
try {
checkLocalFilePath(mFilePath);
file = new File(mFilePath);
fos = new FileOutputStream(file);
inputStream = response.body().byteStream();
sumLength = (double) response.body().contentLength();
while ((length = inputStream.read(buffer)) != -1) {
fos.write(buffer, 0, length);
currentLength += length;
mProgress = (int) (currentLength / sumLength * 100);
mDeliveryHandler.obtainMessage(PROGRESS_MESSAGE, mProgress).sendToTarget();
}
fos.flush();
} catch (Exception e) {
file = null;
} finally {
try {
if (fos != null) {
fos.close();
}
if (inputStream != null) {
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return file;
}
private void checkLocalFilePath(String localFilePath) {
File path = new File(localFilePath.substring(0,
localFilePath.lastIndexOf("/") + 1));
File file = new File(localFilePath);
if (!path.exists()) {
path.mkdirs();
}
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
封装OkHttpClient,用来发送get, post请求的工具类,包括设置一些请求的共用参数
public class CommonOkHttpClient {
private static final int TIME_OUT = 30;
private static OkHttpClient mOkHttpClient;
static {
OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
okHttpClientBuilder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
okHttpClientBuilder.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request =
chain.request().newBuilder().addHeader("User-Agent", "Imooc-Mobile")
.build();
return chain.proceed(request);
}
});
okHttpClientBuilder.cookieJar(new SimpleCookieJar());
okHttpClientBuilder.connectTimeout(TIME_OUT, TimeUnit.SECONDS);
okHttpClientBuilder.readTimeout(TIME_OUT, TimeUnit.SECONDS);
okHttpClientBuilder.writeTimeout(TIME_OUT, TimeUnit.SECONDS);
okHttpClientBuilder.followRedirects(true);
okHttpClientBuilder.sslSocketFactory(HttpsUtils.initSSLSocketFactory(),
HttpsUtils.initTrustManager());
mOkHttpClient = okHttpClientBuilder.build();
}
public static OkHttpClient getOkHttpClient() {
return mOkHttpClient;
}
public static Call get(Request request, DisposeDataHandle handle) {
Call call = mOkHttpClient.newCall(request);
call.enqueue(new CommonJsonCallback(handle));
return call;
}
public static Call post(Request request, DisposeDataHandle handle) {
Call call = mOkHttpClient.newCall(request);
call.enqueue(new CommonJsonCallback(handle));
return call;
}
public static Call downloadFile(Request request, DisposeDataHandle handle) {
Call call = mOkHttpClient.newCall(request);
call.enqueue(new CommonFileCallback(handle));
return call;
}
}
请求中心
public class RequestCenter {
static class HttpConstants {
private static final String ROOT_URL = "http://imooc.com/api";
private static String HOME_RECOMMAND = ROOT_URL + "/module_voice/home_recommand";
private static String HOME_RECOMMAND_MORE = ROOT_URL + "/module_voice/home_recommand_more";
private static String HOME_FRIEND = ROOT_URL + "/module_voice/home_friend";
public static String LOGIN = ROOT_URL + "/module_voice/login_phone";
}
public static void getRequest(String url, RequestParams params, DisposeDataListener listener,
Class<?> clazz) {
CommonOkHttpClient.get(CommonRequest.
createGetRequest(url, params), new DisposeDataHandle(listener, clazz));
}
public static void requestRecommandData(DisposeDataListener listener) {
RequestCenter.getRequest(HttpConstants.HOME_RECOMMAND, null, listener,
BaseRecommandModel.class);
}
public static void requestRecommandMore(DisposeDataListener listener) {
RequestCenter.getRequest(HttpConstants.HOME_RECOMMAND_MORE, null, listener,
BaseRecommandMoreModel.class);
}
public static void requestFriendData(DisposeDataListener listener) {
RequestCenter.getRequest(HttpConstants.HOME_FRIEND, null, listener, BaseFriendModel.class);
}
public static void login(DisposeDataListener listener) {
RequestParams params = new RequestParams();
params.put("mb", "18734924592");
params.put("pwd", "999999q");
RequestCenter.getRequest(HttpConstants.LOGIN, params, listener, User.class);
}
}