Skip to content

Commit

Permalink
1、修改部分核心包名及类名称
Browse files Browse the repository at this point in the history
2、完善部分注释
3、框架增加日志模块,提供扩展开关接口
4、增加全局错误回调接口 AppModule.GlobalErrorHandler,可以通过 AppComponent 获取,此接口不限于只处理 HTTP 异常,其他模块也可以回调此接口来处理统一异常管理
5、完善 Demo
  • Loading branch information
RockyQu committed May 15, 2018
1 parent 524a713 commit 23d346b
Show file tree
Hide file tree
Showing 20 changed files with 285 additions and 335 deletions.
150 changes: 14 additions & 136 deletions App/src/main/java/me/mvp/demo/app/AppConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,47 +7,36 @@
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;

import io.rx_cache2.internal.RxCache;
import me.mvp.demo.BuildConfig;
import me.mvp.demo.app.api.Api;
import me.mvp.demo.app.utils.gson.GsonResponseDeserializer;
import me.mvp.demo.app.config.GlobalErrorConfig;
import me.mvp.demo.app.config.GsonConfig;
import me.mvp.demo.app.config.NetworkInterceptorConfig;
import me.mvp.demo.app.config.OkHttpConfig;
import me.mvp.demo.app.config.ParameterInterceptorConfig;
import me.mvp.demo.app.config.RetrofitConfig;
import me.mvp.demo.app.config.RxCacheConfig;
import me.mvp.demo.entity.User;
import me.mvp.demo.mvp.login.LoginActivity;

import com.google.gson.GsonBuilder;
import com.squareup.leakcanary.LeakCanary;
import com.squareup.leakcanary.RefWatcher;

import me.mvp.frame.base.App;
import me.mvp.frame.base.delegate.ApplicationLifecycles;
import me.mvp.frame.di.module.AppConfigModule;
import me.mvp.frame.di.module.AppModule;
import me.mvp.frame.di.module.HttpModule;
import me.mvp.frame.http.NetworkInterceptorHandler;
import me.mvp.frame.http.ResponseEntity;
import me.mvp.frame.http.cookie.PersistentCookieJar;
import me.mvp.frame.http.download.Downloader;
import me.mvp.frame.http.download.config.DownloaderConfiguration;
import me.mvp.frame.http.interceptor.NetworkInterceptor;
import me.mvp.frame.http.interceptor.ParameterInterceptor;
import me.mvp.frame.integration.ConfigModule;
import me.mvp.frame.utils.AppUtils;
import me.mvp.frame.utils.GsonUtils;
import me.mvp.frame.utils.PreferencesUtils;
import me.mvp.frame.utils.ProjectUtils;

import java.io.File;
import java.util.HashMap;
import java.util.List;

import okhttp3.Cookie;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import retrofit2.Retrofit;

/**
* 全局配置信息在此配置,需要将此实现类声明到 AndroidManifest 中
*/
Expand All @@ -64,124 +53,13 @@ public void applyOptions(final Context context, AppConfigModule.Builder builder)
builder
.httpUrl(Api.APP_DOMAIN)
.cacheFile(new File(ProjectUtils.CACHE))
.networkInterceptorHandler(new NetworkInterceptorHandler() { // Http全局响应结果的处理类

@Override
public Request onHttpRequest(Interceptor.Chain chain, Request request) {
// 请求服务器之前可以拿到Request,做一些操作比如给Request统一添加Token或者Header,不做任务操作则直接返回Request
// return chain.request().newBuilder().header("token", tokenId).build();
return request;
}

@Override
public Response onHttpResponse(String result, Interceptor.Chain chain, Request request, Response response) {
// 这里提前拿到Http请求结果,可以用来检测,如Token是否过期
// if (!TextUtils.isEmpty(result)) {
// ResponseEntity entity = GsonUtils.getEntity(result, ResponseEntity.class);
//
// // 登录超时或授权失效,重新获取授权
// if (entity.getCode() == -253 || entity.getCode() == -254) {
// AppComponent component = ((App) context).getAppComponent();
//
// // 读取当前登录用户信息
// String value = PreferencesUtils.getString(context, LoginActivity.class.getName(), null);
// if (value != null) {
// User user = GsonUtils.getEntity(value, User.class);
//
// Call<ResponseEntity<JsonObject>> apiToken = component.getRepositoryManager().obtainApiService(ApiCommon.class).getToken("CF2QCXW6", DeviceUtils.getIMEI(context), user.getUserId());
// try {
// JsonObject resultToken = apiToken.execute().body().getData();
// apiToken.execute().body();
//// Logg.e(resultToken);
//// Logg.e(resultToken.get("access_token"));
// String token = resultToken.get("access_token").getAsString();
//// Logg.e(token);
//
// HttpUrl.Builder modifiedUrl = request.url().newBuilder()
// .scheme(request.url().scheme())
// .host(request.url().host());
//
// modifiedUrl.addQueryParameter("access_token", token);
//
// Request newRequest = request.newBuilder()
//// .method(request.method(), request.body())
//// .url(modifiedUrl.build())
// .build();
// response.body().close();
// return chain.proceed(newRequest);
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
// }
// }

return response;
}
})
.interceptors(new Interceptor[]
{
new ParameterInterceptor(new ParameterInterceptor.ParameterCallback() {

/**
* 这里为接口添加类型为HashMap的统一参数,例如Token、版本号等。支持Get、Post方法,ParameterInterceptor会自动判断
*/
@Override
public HashMap<String, Object> parameters() {
User user = (User) ((App) context).getAppComponent().extras().get(LoginActivity.class.getName());

HashMap<String, Object> parameters = new HashMap<>();
if (user != null) {
// 为接口统一添加access_token参数
parameters.put("access_token", user.getToken());
}

return parameters;
}
})
})
.retrofitConfiguration(new HttpModule.RetrofitConfiguration() {// 扩展自定义配置Retrofit参数

@Override
public void configRetrofit(Context context, Retrofit.Builder builder) {

}
})
.okHttpConfiguration(new HttpModule.OkHttpConfiguration() {// 扩展自定义配置OkHttp参数
@Override
public void configOkHttp(Context context, OkHttpClient.Builder builder) {
// 配置 HTTPS
// builder.sslSocketFactory(SSL.createSSLSocketFactory(), new TrustAllX509TrustManager());
// builder.hostnameVerifier(new TrustAllHostnameVerifier());
}
})
.rxCacheConfiguration(new HttpModule.RxCacheConfiguration() {
@Override
public RxCache configRxCache(Context context, RxCache.Builder builder) {
// 想自定义 RxCache 的缓存文件夹或者解析方式,如改成 fastjson,请 return rxCacheBuilder.persistence(cacheDirectory, new FastJsonSpeaker());
return null;
}
})
.gsonConfiguration(new AppModule.GsonConfiguration() {// 扩展自定义配置Gson参数
@Override
public void configGson(Context context, GsonBuilder builder) {
builder
.serializeNulls()// 支持序列化null的参数
.registerTypeAdapter(ResponseEntity.class, new GsonResponseDeserializer());
}
})
.cookieLoadForRequest(new PersistentCookieJar.CookieLoadForRequest() {

@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {

}

@Override
public List<Cookie> loadForRequest(List<Cookie> cookies) {
return cookies;
}
})
.networkInterceptorHandler(new NetworkInterceptorConfig())
.interceptors(new ParameterInterceptorConfig(context))
.retrofitConfiguration(new RetrofitConfig())
.okHttpConfiguration(new OkHttpConfig())
.globalErrorHandler(new GlobalErrorConfig())
.rxCacheConfiguration(new RxCacheConfig())
.gsonConfiguration(new GsonConfig())
;
}

Expand Down
57 changes: 57 additions & 0 deletions App/src/main/java/me/mvp/demo/app/config/GlobalErrorConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package me.mvp.demo.app.config;

import android.content.Context;
import android.net.ParseException;

import com.google.gson.JsonParseException;

import org.json.JSONException;

import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;

import me.mvp.frame.di.component.AppComponent;
import me.mvp.frame.di.module.AppModule;
import me.mvp.frame.widget.Toaster;
import retrofit2.HttpException;

/**
* 全局异常回调,可以不限于只处理 HTTP 异常,其他模块也可以回调此接口来处理统一异常管理
* 通过 {@link AppComponent#getGlobalErrorHandler()} 获取此接口
*/
public class GlobalErrorConfig implements AppModule.GlobalErrorHandler {

@Override
public void httpError(Context context, Throwable throwable) {
// 可以根据不同的错误做不同的逻辑处理
String message = "未知错误";
if (throwable instanceof UnknownHostException) {
message = "网络不可用或无法解析该域名";
} else if (throwable instanceof ConnectException || throwable instanceof SocketTimeoutException) {
message = "请求网络超时或网络连接异常";
} else if (throwable instanceof HttpException) {
HttpException httpException = (HttpException) throwable;
if (httpException.code() == 500) {
message = "服务器发生错误";
} else if (httpException.code() == 404) {
message = "请求地址不存在";
} else if (httpException.code() == 403) {
message = "请求被服务器拒绝";
} else if (httpException.code() == 307) {
message = "请求被重定向到其他页面";
} else {
message = httpException.message();
}
} else if (throwable instanceof JsonParseException || throwable instanceof ParseException || throwable instanceof JSONException) {
message = "数据解析错误";
}

Toaster.postMessage(message);
}

@Override
public void handlerError(Context context, Throwable throwable) {

}
}
22 changes: 22 additions & 0 deletions App/src/main/java/me/mvp/demo/app/config/GsonConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package me.mvp.demo.app.config;

import android.content.Context;

import com.google.gson.GsonBuilder;

import me.mvp.demo.app.utils.gson.GsonResponseDeserializer;
import me.mvp.frame.di.module.AppModule;
import me.mvp.frame.http.ResponseEntity;

/**
* 扩展自定义配置 Gson 参数
*/
public class GsonConfig implements AppModule.GsonConfiguration {

@Override
public void configGson(Context context, GsonBuilder builder) {
builder
.serializeNulls()// 支持序列化null的参数
.registerTypeAdapter(ResponseEntity.class, new GsonResponseDeserializer());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package me.mvp.demo.app.config;

import me.mvp.frame.http.NetworkInterceptorHandler;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;

/**
* Http全局响应结果的处理类
*/
public class NetworkInterceptorConfig implements NetworkInterceptorHandler {

@Override
public Request onHttpRequest(Interceptor.Chain chain, Request request) {
// 请求服务器之前可以拿到Request,做一些操作比如给Request统一添加Token或者Header,不做任务操作则直接返回Request
// return chain.request().newBuilder().header("token", tokenId).build();
return request;
}

@Override
public Response onHttpResponse(String result, Interceptor.Chain chain, Request request, Response response) {
// 这里提前拿到Http请求结果,可以用来检测,如Token是否过期
// if (!TextUtils.isEmpty(result)) {
// ResponseEntity entity = GsonUtils.getEntity(result, ResponseEntity.class);
//
// // 登录超时或授权失效,重新获取授权
// if (entity.getCode() == -253 || entity.getCode() == -254) {
// AppComponent component = ((App) context).getAppComponent();
//
// // 读取当前登录用户信息
// String value = PreferencesUtils.getString(context, LoginActivity.class.getName(), null);
// if (value != null) {
// User user = GsonUtils.getEntity(value, User.class);
//
// Call<ResponseEntity<JsonObject>> apiToken = component.getRepositoryManager().obtainApiService(ApiCommon.class).getToken("CF2QCXW6", DeviceUtils.getIMEI(context), user.getUserId());
// try {
// JsonObject resultToken = apiToken.execute().body().getData();
// apiToken.execute().body();
//// Logg.e(resultToken);
//// Logg.e(resultToken.get("access_token"));
// String token = resultToken.get("access_token").getAsString();
//// Logg.e(token);
//
// HttpUrl.Builder modifiedUrl = request.url().newBuilder()
// .scheme(request.url().scheme())
// .host(request.url().host());
//
// modifiedUrl.addQueryParameter("access_token", token);
//
// Request newRequest = request.newBuilder()
//// .method(request.method(), request.body())
//// .url(modifiedUrl.build())
// .build();
// response.body().close();
// return chain.proceed(newRequest);
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
// }
// }

return response;
}
}
19 changes: 19 additions & 0 deletions App/src/main/java/me/mvp/demo/app/config/OkHttpConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package me.mvp.demo.app.config;

import android.content.Context;

import me.mvp.frame.di.module.HttpModule;
import okhttp3.OkHttpClient;

/**
* 扩展自定义配置 OkHttp 参数
*/
public class OkHttpConfig implements HttpModule.OkHttpConfiguration {

@Override
public void configOkHttp(Context context, OkHttpClient.Builder builder) {
// 配置 HTTPS
// builder.sslSocketFactory(SSL.createSSLSocketFactory(), new TrustAllX509TrustManager());
// builder.hostnameVerifier(new TrustAllHostnameVerifier());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package me.mvp.demo.app.config;

import android.content.Context;

import java.util.HashMap;

import me.mvp.demo.entity.User;
import me.mvp.demo.mvp.login.LoginActivity;
import me.mvp.frame.base.App;
import me.mvp.frame.http.interceptor.ParameterInterceptor;

/**
* 这里为接口添加类型为HashMap的统一参数,例如Token、版本号等。支持Get、Post方法,ParameterInterceptor会自动判断
*/
public class ParameterInterceptorConfig extends ParameterInterceptor {

private Context context;

public ParameterInterceptorConfig(Context context) {
this.context = context;
}

@Override
public HashMap<String, Object> parameters() {
User user = (User) ((App) context).getAppComponent().extras().get(LoginActivity.class.getName());

HashMap<String, Object> parameters = new HashMap<>();
if (user != null) {
// 为接口统一添加access_token参数
parameters.put("access_token", user.getToken());
}
return parameters;
}
}
Loading

0 comments on commit 23d346b

Please sign in to comment.