Skip to content

pudao2010/MVP

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 

Repository files navigation

MVP

项目中的MVP架子 网络请求结合Rxjava + Retrofit + OKHttp(基于此仿一个WeChat?) 整体思路: 一、抽取顶层的接口Presenter接口,使用泛型进行简化,包含两个主要的方法与生命周期进行绑定

	public interface Presenter<T extends MvpView> {

	    // 在Activity或者Fragment的生命周期onCreate时进行绑定
	    void attachView(T mvpView);

	    // 在Activity或者Fragment的生命周期onDestroy时进行解绑
	    void detachView();

	}
二、View层的顶层接口MvpView
	public interface MvpView {
		// 这里对错误可以进行统一提示
    	void showErrorInfo(String msg);

	}
三、Presenter的基类实现
	public class BasePresenter<T extends MvpView> implements Presenter<T> {
		// 用于网络请求	
	    protected Api mApi = new ApiImpl();

	    protected String TAG = getClass().getSimpleName();
	    // Presenter持有View的引用,在attachView时获得实例,在detachView时置为null
	    private T mMvpView;
	    // 在attach时获得实例
	    @Override
	    public void attachView(T mvpView) {
	        mMvpView = mvpView;
	    }
	    // 在detach时置为null
	    @Override
	    public void detachView() {
	        mMvpView = null;
	    }

	    public T getMvpView() {
	        return mMvpView;
	    }
	    // 通过java的反射机制获取泛型的实例,简化代码的书写
	    public Class<T> getMvpViewClass() {
	        return ReflexUtil.getClassGeneric(this, 0);
	    }

	}
四、Api接口,主要是一些基于Rxjava观察者模式的一些网络请求方法
	public interface Api {

	    Subscription getQRcodeInfo(String action, String params, ResultSubscriber<LinkedTreeMap> subscriber);

	    Subscription getNews(int page, int rows, String mid, ResultSubscriber<List<NewEntity>> subscriber);

	    Subscription getCompic(ResultSubscriber<List<CompicEntity>> subscriber);

	    Subscription login(String usercode, String password, ResultSubscriber<Void> subscriber);

	    Subscription getCurruser(ResultSubscriber<UserInfo> subscriber);

	}
五、Api接口的实现类

	public class ApiImpl implements Api {
		// ApiService的实例,在构造实例时进行初始化,并获取到Retrofit的对象
	    private ApiService mApiService;

	    public ApiImpl() {
	        this.mApiService = RetrofitManage.getApiInstance(ApiService.class);
	    }

	    @Override
	    public Subscription getNews(int page, int rows, String mid, ResultSubscriber<List<NewEntity>> subscriber) {
	        return HttpMethod.execute(mApiService.news(page, rows, mid), subscriber);
	    }

	    @Override
	    public Subscription login(String usercode, String password, ResultSubscriber<Void> subscriber) {
	        return HttpMethod.execute(mApiService.login(usercode, password), subscriber);
	    }
	}
六、ApiService接口,实现具体网络访问,主要是Retrofit的使用注解的get或者post请求

	public interface ApiService {

	    @FormUrlEncoded
	    @POST("{action}")
	    Observable<Response<ResultModle<LinkedTreeMap>>> qrcodeinf(@Path(value = "action", encoded = true) String url, @FieldMap Map<String, String> fields);

	    @GET("index/news!jsonlist.action")
	    Observable<Response<ResultModle<List<NewEntity>>>> news(@Query("page") int page, @Query("rows") int rows, @Query("mid") String mid);

	    @GET("index/news!getByidinfo.action")
	    Observable<Response<ResultModle<NewEntity>>> newsinfo(@Query("id") String id);

	    @GET("common/compic!jsonlist.action")
	    Observable<Response<ResultModle<List<CompicEntity>>>> compic();
	    
	}
七、请求结果返回模型的统一封装,网络请求返回的json主要字段进行统一管理
	public class ResultModle<T> {

	    private int code = 0;
	    private String msg;
	    private T data;

	    public int getCode() {
	        return code;
	    }

	    public void setCode(int code) {
	        this.code = code;
	    }

	    public String getMsg() {
	        return msg;
	    }

	    public void setMsg(String msg) {
	        this.msg = msg;
	    }

	    public T getData() {
	        return data;
	    }

	    public void setData(T data) {
	        this.data = data;
	    }

	}

八、Retrofit的网络管理类
	public class RetrofitManage {

	    private static RetrofitManage mRetrofitManage;

	    public static void init(OkHttpClient okHttpClient) {
	        mRetrofitManage = new RetrofitManage(okHttpClient);
	    }

	    private Retrofit mRetrofit;

	    private Map<Class<?>, Object> mApis;
	    // 私有构造方法,标准的单例设计模式
	    private RetrofitManage(OkHttpClient okHttpClient) {

	        mApis = new HashMap<Class<?>, Object>();

	        mRetrofit = new Retrofit.Builder()
	                .client(okHttpClient)
	                .baseUrl(ServiceConfig.BASE_URL)
	                .addConverterFactory(GsonConverterFactory.create())
	                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
	                .build();
	    }

	    /**
	     * 单例模式的Api实例获取
	     * @param clazz 需要获取实例的类
	     * @param <T>   泛型
	     * @return 实例
	     */
	    public static <T> T getApiInstance(Class<T> clazz) {
	        T object = (T) mRetrofitManage.mApis.get(clazz);
	        if (object == null) {
	            object = mRetrofitManage.mRetrofit.create(clazz);
	            mRetrofitManage.mApis.put(clazz, object);
	        }
	        return object;
	    }
	}
九、ResultSubscriber类,继承自Subscriber,接口数据统一返回类,观察者,持有Presenter层引用
	public abstract class ResultSubscriber<T> extends Subscriber<T> {

	    private BasePresenter mPresenter;

	    public ResultSubscriber(BasePresenter presenter) {
	        mPresenter = presenter;
	    }

	    @Override
	    public void onStart() {
	        super.onStart();
	    }

	    @Override
	    public void onCompleted() {
	    }

	    @Override
	    public void onError(Throwable e) {
	        e.printStackTrace();
	        if (mPresenter != null) {
	            if (mPresenter.getMvpView() != null) {
	                onError(e.getMessage());
	            }
	        } else {
	            onError(e.getMessage());
	        }
	    }

	    /**
	     * 如果有特别错误处理需求.可以重写改方法
	     * @param error
	     */
	    protected void onError(String error) {
	        if (mPresenter != null) {
	            mPresenter.getMvpView().showErrorInfo(error);
	        }
	    }

	    @Override
	    public void onNext(T t) {
	        if (mPresenter != null) {
	            if (mPresenter.getMvpView() != null) {
	                onSuccess(t);
	            }
	        } else {
	            onSuccess(t);
	        }
	        onCompleted();
	    }

	    public abstract void onSuccess(T t);

	}

十、HttpMethod类,RxJava 对网络请求的统一处理,对结果进行转换

public class HttpMethod {

    /**
     * 使用通用的处理方式去处理网络请求
     *
     * @param observable RxJava Adapter 生成的请求
     * @param subscriber 用于返回数据的观察者
     * @param <T>        接口返回的数据类型
     * @return
     */
    public static <T> Subscription execute(Observable<Response<ResultModle<T>>> observable, Subscriber<T> subscriber) {
        return observable.subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io()) //取消订阅
                .observeOn(AndroidSchedulers.mainThread())
                .map(new HttpResultErrorFunc<T>())
                .map(new HttpResultStatusCodeFunc<T>())
                .subscribe(subscriber);
    }

    /**
     * 接口返回的数据与返回到P层数据不一样需要转换的处理方式
     *
     * @param observable RxJava Adapter 生成的请求
     * @param subscriber 用于返回数据的观察者
     * @param conversion 转换数据的Func1
     * @param <T>        接口返回的数据类型
     * @param <R>        需要的最终类型
     * @return
     */
    public static <T, R> Subscription execute(Observable<Response<ResultModle<T>>> observable, Subscriber<R> subscriber, HttpResultConversionFunc<T, R> conversion) {
        return observable.subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .map(new HttpResultErrorFunc<T>())
                .map(new HttpResultStatusCodeFunc<T>())
                .map(conversion)
                .subscribe(subscriber);
    }

}

/**
 * 转换类的包装,RxJava将 T类型 转换为 R类型
 */
public abstract class HttpResultConversionFunc<T, R> implements Func1<T, R> {

    @Override
    public R call(T t) {
        R r = conversion(t);
        if (r == null) {
            throw new ApiException(ApiException.CONVERSION_RESULT_NULL);
        }
        return r;
    }
    // 将T类型转换为R类型的抽象方法,子类必须实现
    public abstract R conversion(T t);

}


/**
 * Created by Thisdk on 2016/4/11.
 * 全部请求的错误从这里开始产生
 */
public class HttpResultErrorFunc<T> implements Func1<Response<ResultModle<T>>, ResultModle<T>> {

    @Override
    public ResultModle<T> call(Response<ResultModle<T>> response) {
        //正常返回的处理方式
        if (response.isSuccessful()) {
            return response.body();
        }
        //其他错误码的处理方式
        int code = response.code();
        String errorJson = "";
        ResultModle<T> errorBody = null;
        try {
            errorJson = response.errorBody().string();
        } catch (IOException e) {
            //抛出状态码 , 告知I/O错误
            throw new ApiException("HTTP " + code + " I/O steam error");
        }
        try {
            errorBody = new Gson().fromJson(errorJson, new TypeToken<ResultModle<T>>() {
            }.getType());
        } catch (JsonSyntaxException | JsonIOException e) {
            //抛出状态码 , 和无法序列化的内容
            throw new ApiException("HTTP " + code + " " + errorJson);
        }
        if (errorBody == null) {
            //抛出状态码 , 告知没有内容
            throw new ApiException("HTTP " + code + " error body is null");
        }
        //存在返回内容对象,按统一方式处理
        return errorBody;
    }

}

/**
 * 状态码
 */
public class HttpResultStatusCodeFunc<T> implements Func1<ResultModle<T>, T> {

    @Override
    public T call(ResultModle<T> resultModle) {
        if (resultModle.getCode() != 0) {
            throw new ApiException(resultModle.getCode(), resultModle.getMsg());
        } else {
            if (resultModle.getRows() != null) {
                return resultModle.getRows();
            } else return resultModle.getData();
        }
    }

}

About

项目中的MVP架子

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages