流程图:
mvp终极.jpg首先创建model 层 并且对他的请求参数,网络请求,数据参数,进行封装,这样可以减小相似代码。更简洁。
分包:
创建ApiService:
public interface ApiService {
@POST
@FormUrlEncoded
Observable<String> doPost(@Url String url, @HeaderMap HashMap<String ,Object> headers, @FieldMap HashMap<String,Object> params);
@GET
Observable<String> doGet(@Url String url, @HeaderMap HashMap<String ,Object> headers, @QueryMap HashMap<String,Object> params);
}
创建DataService:
//网络 请求封装
//日志拦截器,Retrofit 的 公有部分抽取出来 使用了双检索单列模式
public class DataService {
public static volatile ApiService mApiService;
private static HttpLoggingInterceptor httpLoggingInterceptor;
public static final int WAIT_TIME=20000;
public static ApiService getApiService(){
if (mApiService==null){
//在多线程 防止线程抢占 类只有一个
synchronized (DataService.class){
if (mApiService==null){
httpLoggingInterceptor = new HttpLoggingInterceptor();
if (BuildConfig.DEBUG){
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
}else {
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.NONE);
}
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(httpLoggingInterceptor)
.connectTimeout(WAIT_TIME, TimeUnit.SECONDS)
.writeTimeout(WAIT_TIME, TimeUnit.SECONDS)
.readTimeout(WAIT_TIME, TimeUnit.SECONDS)
.build();
Retrofit retrofit = new Retrofit.Builder().addConverterFactory(MvpGsonConverterFactory.create())
.addCallAdapterFactory(RxJava3CallAdapterFactory.create())
.client(okHttpClient)
.baseUrl(Contrast.BASE_URL)
.build();
mApiService=retrofit.create(ApiService.class);
}
}
}
return mApiService;
}
}
MvpGsonConverterFactory, MvpGsonRequestBodyConverter
//Gson转换器工厂
public final class MvpGsonConverterFactory extends Converter.Factory {
/**
* Create an instance using a default {@link Gson} instance for conversion. Encoding to JSON and
* decoding from JSON (when no charset is specified by a header) will use UTF-8.
*/
public static MvpGsonConverterFactory create() {
return create(new Gson());
}
/**
* Create an instance using {@code gson} for conversion. Encoding to JSON and
* decoding from JSON (when no charset is specified by a header) will use UTF-8.
*/
@SuppressWarnings("ConstantConditions") // Guarding public API nullability.
public static MvpGsonConverterFactory create(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
return new MvpGsonConverterFactory(gson);
}
private final Gson gson;
private MvpGsonConverterFactory(Gson gson) {
this.gson = gson;
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new MvpGsonResponseBodyConverter<>(gson, adapter,type);
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
return new MvpGsonRequestBodyConverter<>(gson, adapter);
}
}
//请求体转换器
final class MvpGsonRequestBodyConverter<T> implements Converter<T, RequestBody> {
private static final MediaType MEDIA_TYPE = MediaType.get("application/json; charset=UTF-8");
private static final Charset UTF_8 = Charset.forName("UTF-8");
private final Gson gson;
private final TypeAdapter<T> adapter;
MvpGsonRequestBodyConverter(Gson gson, TypeAdapter<T> adapter) {
this.gson = gson;
this.adapter = adapter;
}
@Override public RequestBody convert(T value) throws IOException {
Buffer buffer = new Buffer();
Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8);
JsonWriter jsonWriter = gson.newJsonWriter(writer);
adapter.write(jsonWriter, value);
jsonWriter.close();
return RequestBody.create(MEDIA_TYPE, buffer.readByteString());
}
}
//响应体转换器
final class MvpGsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
private final Gson gson;
private final TypeAdapter<T> adapter;
private final Type type;
MvpGsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter,Type type) {
this.gson = gson;
this.adapter = adapter;
this.type=type;
}
@Override public T convert(ResponseBody value) throws IOException {
if (type==String.class){
try {
MediaType mediaType = value.contentType();
//字符集
Charset charset=null;
if (mediaType!=null){
charset=mediaType.charset();
}
String json = new String(value.bytes(), charset == null ? StandardCharsets.UTF_8 : charset);
return (T) handJson(json);
}finally {
value.close();
}
}else {
JsonReader jsonReader = gson.newJsonReader(value.charStream());
try {
T result = adapter.read(jsonReader);
if (jsonReader.peek() != JsonToken.END_DOCUMENT) {
throw new JsonIOException("JSON document was not fully consumed.");
}
return result;
} finally {
value.close();
}
}
}
public String handJson(String json){
try {
JSONObject jsonObject = new JSONObject(json);
if (!jsonObject.isNull("code")){
int code = jsonObject.getInt("code");
if (code!=1){
if (!jsonObject.isNull("data")){
String data = jsonObject.getString("data");
if (TextUtils.isEmpty(data)){//如果data 是一个空字符串
jsonObject.remove("data");
return jsonObject.toString();
}
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return json;
}
}
创建MvpRequest:
//数据请求参数的封装
//使用面向对象的思想 : 通过bean 类 的形式将请求的数据封装到一个类中
public class MvpRequest <T>{
protected String url;
protected RequestType requestType=RequestType.FIRST;//第一次请求,刷新 ,加载更多
protected RequestMethod requestMethod=RequestMethod.POST;//post get
protected HashMap<String ,Object> mParams;
protected HashMap<String ,Object> mHeaders;
protected Class<T> type;
protected boolean isEnableCancel;
public MvpRequest() {
}
public Class<T> getType() {
return type;
}
public void setType(Class<T> type) {
this.type = type;
}
public MvpRequest(String url) {
this.url = url;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public RequestType getRequestType() {
return requestType;
}
public void setRequestType(RequestType requestType) {
this.requestType = requestType;
}
public RequestMethod getRequestMethod() {
return requestMethod;
}
public void setRequestMethod(RequestMethod requestMethod) {
this.requestMethod = requestMethod;
}
public HashMap<String, Object> getParams() {
return mParams;
}
public void setParams(HashMap<String, Object> mParams) {
this.mParams = mParams;
}
public HashMap<String, Object> getHeaders() {
//三目用算符 如果header ==null 就创建HashMap<> 否则传入headers
return mHeaders == null ? new HashMap<>() : mHeaders;
}
public void setHeaders(HashMap<String, Object> mHeaders) {
this.mHeaders = mHeaders;
}
public boolean isEnableCancel() {
return isEnableCancel;
}
public void setEnableCancel(boolean enableCancel) {
isEnableCancel = enableCancel;
}
//枚举形式的RequestType 固定几个参数
}
创建GetRequest:
public class GetRequest extends MvpRequest {
public GetRequest(String url) {
super(url);
}
@Override
public RequestMethod getRequestMethod() {
return RequestMethod.GET;
}
}
创建PostRequest:
public class PostRequest extends MvpRequest {
public PostRequest(String url) {
super(url);
}
@Override
public RequestMethod getRequestMethod() {
return RequestMethod.POST;
}
}
创建枚举RequestMethod
//对get post 进行选择
public enum RequestMethod {
POST,GET
}
创建枚举RequestType :
//进行第一次 ,加载 ,刷新
public enum RequestType {
FIRST,REFRESH,LOAD_MORE
}
创建MvpResponse:
//数据结果参数的封装
public class MvpResponse<D> {
private ResponseType type = ResponseType.SERVER;// 数据从哪儿回来的? 服务器,sdcard, 内存
private RequestType requestType = RequestType.FIRST; // 是第一次请求回来?刷新回来?加载更多回来?
private String msg; // 服务器给的消息提示
private int code; // 服务器返回的状态码
private D data; // 我们真正要的数据
public boolean isOk(){
return data != null;
}
public ResponseType getType() {
return type;
}
public MvpResponse<D> type(ResponseType type) {
this.type = type;
return this;
}
public RequestType getRequestType() {
return requestType;
}
public MvpResponse<D> requestType(RequestType requestType) {
this.requestType = requestType;
return this;
}
public String getMsg() {
return msg;
}
public MvpResponse<D> setMsg(String msg) {
this.msg = msg;
return this;
}
public int getCode() {
return code;
}
public MvpResponse<D> setCode(int code) {
this.code = code;
return this;
}
public D getData() {
return data;
}
public MvpResponse<D> setData(D data) {
this.data = data;
return this;
}
}
创建枚举ResponseType :
//对 服务,sd卡,缓存
public enum ResponseType {
SERVER,MEMORY,SDCARD
}
创建IBaseCallBack:
//接口放实现类
public interface IBaseCallBack <T>{
void onResult(MvpResponse<T> response);
default void onStart(Disposable disposable){
}
}
创建IBaseModel:
public interface IBaseModel {
//做请求:两个参数: MvpRequest CallBack
<T> void doRequest(MvpRequest<T> request, IBaseCallBack<T> callBack);
}
创建BaseModel 进行model 的抽取:
public class BaseRepository implements IBaseModel {
@SuppressWarnings("ALL")
public Consumer empty= o ->{};//定义一个空的Consumer 有点时候调用三参方法
public <T> void doRequest(MvpRequest<T> request,IBaseCallBack<T> callBack){
doRequest(request,empty,callBack);
}
public <T> void doRequest(MvpRequest<T> request, Consumer<MvpResponse<T>> doBackground, IBaseCallBack<T> callBack) {
//判断
switch (request.getRequestMethod()) {
case GET: {
//创建观察者处理数据
doObserver(request, DataService.getApiService().doGet(request.getUrl(), request.getHeaders(), request.getParams()), doBackground, callBack);
break;
}
case POST: {
doObserver(request, DataService.getApiService().doPost(request.getUrl(), request.getHeaders(), request.getParams()), doBackground, callBack);
break;
}
}
}
protected <T> void doObserver(MvpRequest<T> request, Observable<String> observable, Consumer<MvpResponse<T>> consumer, IBaseCallBack<T> callBack) {
observable//对数据进行加工
.map(json2Data(request))
//对数据做异常处理
.doOnNext(consumer)
//切换线程
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<MvpResponse<T>>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
if (request.isEnableCancel()) {
callBack.onStart(d);
}
}
@Override
public void onNext(@NonNull MvpResponse<T> data) {
callBack.onResult(data);
}
@Override
public void onError(@NonNull Throwable e) {
callBack.onResult(new MvpResponse<T>().setMsg(e.getMessage()));
}
@Override
public void onComplete() {
}
});
}
public <T> Function<String, MvpResponse<T>> json2Data(MvpRequest<T> request) {
return new Function<String, MvpResponse<T>> () {
@Override
public MvpResponse<T> apply(String s) throws Throwable {
// IBaseCallBack<ColumnData>
/*Type[] types = callBack.getClass().getGenericInterfaces();
ParameterizedType parameterizedType = (ParameterizedType) types[0];
Type realType = parameterizedType.getActualTypeArguments()[0];
*/
//HttpResult<ColumnData>
ParameterizedTypeImpl parameterizedType = new ParameterizedTypeImpl(HttpResult.class, new Type[]{request.getType()});
HttpResult<T> data = new Gson().fromJson(s, parameterizedType);
if (data.getCode() == 1) {
if (data.getData() != null) {
return new MvpResponse<T>().setCode(data.getCode()).setData(data.getData());
} else {
return new MvpResponse<T>().setCode(data.getCode()).setMsg("服务器异常");
}
} else {
return new MvpResponse<T>().setCode(data.getCode()).setMsg(data.getMessage());
}
}
};
}
}
网友评论