Android MVP+RXJava+Retrofit框架的初步构建
来源:互联网 发布:开淘宝商城要多少钱 编辑:程序博客网 时间:2024/04/29 16:20
之前看了关于MVP、RXJava、Retrofit的开发资料就尝试把它们都整合在一起,这里介绍的内容和搭建的框架是基于我的理解去做的,而且也是初步去构建自己的开发框架,所以难免会有理解不到的地方,不敢保证一点bug都没有,也不建议大家用到真实的项目中去,只是拿来学习。
一、MVP模式的简介
view则用来展示数据,显示界面,业务的的处理就交给Presenter 来处理,数据的访问存储就交给Model 来处理,这样分工比较明确,逻辑也清晰,修改起来也比较方便。
(1)其中View可以对应着Activity、Fragment;
(2)Presenter就是一个中介,响应View发出的请求,同时去调用Model来处理,最后也会把请求的结果返回到view中去;
(3)model响应Presenter的请求,并把请求结果返回给presenter,比如请求网络的工作就可以交给它来做;
(4)它们通过接口来实现相互之间的调用。
二、基础框架的搭建
1、Retrofit的构建
(1) 添加依赖库
我这里把它做成依赖库,这样就可以给其它app公用了,就是netlib,
然后在它的build.gradle添加依赖库。
compile 'com.squareup.okhttp3:okhttp:3.2.0' compile 'com.squareup.okhttp3:logging-interceptor:3.1.2' compile 'com.squareup.retrofit2:converter-gson:2.0.0' compile 'com.squareup.retrofit2:converter-scalars:2.0.0' compile 'com.squareup.retrofit2:retrofit:2.0.0' compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0' compile 'io.reactivex:rxjava:1.0.10' compile 'io.reactivex:rxjava:1.1.0' compile 'io.reactivex:rxandroid:1.1.0'
(2)设置OkHttp
a.可以设置日志信息
b.获取头部信息,比如sessionid,我这里就有获取到登录返回的session
c.设置超时的时间
public class OkhttpManage { //超时时间,60s private final static long timeOut=60; private static OkHttpClient okHttpClient; public static OkHttpClient getOkHttp(Context applicationContext){ if(okHttpClient==null){ //日志 HttpLoggingInterceptor logging = new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY); okHttpClient = new OkHttpClient().newBuilder() .connectTimeout(timeOut, TimeUnit.SECONDS) .addInterceptor(new GetCookiesInterceptor(applicationContext)) .addInterceptor(logging) .build(); } return okHttpClient; } /** * 获取请求头信息,保存cookie */ static class GetCookiesInterceptor implements Interceptor { Context context; SharedPreferences sp; SharedPreferences.Editor editor; public GetCookiesInterceptor(Context context){ this.context = context; sp = context.getSharedPreferences("Cookie",Context.MODE_PRIVATE); editor = sp.edit(); } @Override public Response intercept(Chain chain) throws IOException { Response originnalResponse=null; try { originnalResponse = chain.proceed(chain.request()); if (!originnalResponse.headers("Set-Cookie").isEmpty()) { List<String> header = originnalResponse.headers("Set-Cookie"); for (String s : header) { if (s.contains("JSESSIONID")) { editor.putString("cookie",s.split(";")[0]); editor.commit(); } } } }catch (Exception e){ if(e instanceof java.net.SocketTimeoutException){ new LThread(context,1).start(); System.out.println("GetCookiesInterceptor 超时:"); }else if(e instanceof java.net.ConnectException){ new LThread(context,0).start(); System.out.println("网络不通"); } e.printStackTrace(); } return originnalResponse; } } static class LThread extends Thread{ Context context; int flag; public LThread(Context context,int flag){ this.context = context; this.flag=flag; } @Override public void run() { Looper.prepare(); Handler h = new Handler(){ @Override public void dispatchMessage(Message msg) { if(msg!=null&&msg.what==0){ Toast.makeText(context,"网络不通,请检查网络",Toast.LENGTH_SHORT).show(); }else if(msg!=null&&msg.what==1){ Toast.makeText(context,"请求超时",Toast.LENGTH_SHORT).show(); } } }; h.sendEmptyMessage(flag); Looper.loop(); } }}
(3)创建retrofit的管理类
其中泛型就是下文提到的Model定义的接口,用gson处理返回的数据,用Rxjava做处理数据的适配器。
public class RetrofitManage { /** * @param tClass 自定义的请求接口 * @param baseUrl 请求基本路径 * @param context 请求上下文 * @param <T> * @return */ public static <T> T getNetWorkApi(Class<T> tClass,String baseUrl,Context context){ Converter.Factory gsonConverterFactory = GsonConverterFactory.create(); Converter.Factory scalarsConverterFactory = ScalarsConverterFactory.create(); CallAdapter.Factory rxJavaCallAdapterFactory = RxJavaCallAdapterFactory.create(); Retrofit retrofit = new Retrofit.Builder() .client(OkhttpManage.getOkHttp(context)) .baseUrl(baseUrl) .addConverterFactory(scalarsConverterFactory) .addConverterFactory(gsonConverterFactory) .addCallAdapterFactory(rxJavaCallAdapterFactory) .build(); return retrofit.create(tClass); }}
2、MVP的构建
(1)定义view的接口
这是用在activity或fragment上显示数据的,根据自己实际的需要定义即可。
public interface GetDataInterface { //登录成功的回调 void loginSuccess(UserInfoResult userInfoResult); //错误信息的显示 void onError(Throwable e); //查询数据成功的回调 void getBusSuccess(AllBusinessResult allBusinessResult);}
(2)定义presenter 的接口
public interface Loginpresenter { public void getAllBus(@NonNull String session); public void login(String userName, String pwd, String did);}
(3)定义model接口
这是retrofit的,其中@post代表post请求
a.参数@Header(“Cookie”) String session ,就是要添加到叫“Cookie”头部的内容,根据实际需求修改即可。
b.参数@Query(“username”) String userName,就是请求的参数有username=””
c.像上面一个一个写比较多的时候就不友好了,可以用
@QueryMap Map
public interface LoginAndOther { @POST("pda/queryGlobalQuantityByDay.action") Observable<AllBusinessResult> getAllBus(@Header("Cookie") String session); @POST("pda/mobileLogin.action") Observable<UserInfoResult> login(@Query("username") String userName, @Query("password") String pwd, @Query("devId") String did); @POST("pda/mobileLogin.action") Observable<UserInfoResult> login2(@QueryMap Map<String,String> opts);}
(4)实现presenter定义的接口
a、baseUrl就是基本的路径,最好以“/”结尾,这里涉及到公司内容,我就不显示它的路径了
b、GetDataInterface gt; 就是上面定义的view 的接口
c、CompositeSubscription ss;//是RXJava 的内容,用来管理subscription
d、通过RetrofitManage.getNetWorkApi来进行网络请求,这在上面的Retrofit构建里设置的,同时也调用到model的接口了,这是Retrofit的使用
e、subscribeOn(Schedulers.io())可以让请求运行在其它的线程中,
observeOn(AndroidSchedulers.mainThread())可以让显示数据操作运行在主线程中去,
subscribe(oblogin) 用来处理数据、显示数据等操作,并在这个参数的对象里面调用View的接口,即GetDataInterface gt,这样MVP就相互关联起来了,请求数据不会再主线程中,显示数据又回到主线程中去。
Subscription s = RetrofitManage.getNetWorkApi(LoginAndOther.class,baseUrl,context.getApplicationContext()) .login2(opts) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(oblogin); ss.add(s);
public class LoginImpl implements Loginpresenter{ Context context ; CompositeSubscription ss; String baseUrl = ""; GetDataInterface gt; public LoginImpl(Context context, GetDataInterface gt,CompositeSubscription ss){ this.context = context; this.ss = ss; this.gt = gt; } Observer<UserInfoResult> oblogin = new Observer<UserInfoResult>() { @Override public void onCompleted() { Log.d("omCompleted","请求完成"); System.out.println("请求完成"); } @Override public void onError(Throwable e) { gt.onError(e); Log.d("onError",e.getMessage()); e.printStackTrace(); } @Override public void onNext(UserInfoResult userInfoResult) { gt.loginSuccess(userInfoResult); System.out.println(userInfoResult.toString()); Log.d("userInfoResult ",userInfoResult.success); } }; @Override public void login(String userName, String pwd, String did) { Map<String,String> opts = new HashMap<String, String>() ; opts.put("username",userName); opts.put("password",pwd); opts.put("devId",did); Subscription s = RetrofitManage.getNetWorkApi(LoginAndOther.class,baseUrl,context.getApplicationContext()) .login2(opts) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(oblogin); ss.add(s); } @Override public void getAllBus(String session) { Subscription s = RetrofitManage.getNetWorkApi(LoginAndOther.class,baseUrl,context) .getAllBus(session) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<AllBusinessResult>() { @Override public void onCompleted() { Log.d("omCompleted","请求完成"); System.out.println("请求完成"); } @Override public void onError(Throwable e) { if(e==null)return; Log.d("onError",e.getMessage()); e.printStackTrace(); } @Override public void onNext(AllBusinessResult allBusinessResult) { gt.getBusSuccess(allBusinessResult); } }); ss.add(s); } public void destroySubscription(){ System.out.println("unsubscribe"); ss.unsubscribe(); }}
(5) 在activity或fragment中实现已经定义view的接口
a、就是上面定义的GetDataInterface
b、定义presenter
Loginpresenter lp;
lp = new LoginImpl(this,this,subscriptions);
c、这样就可以通过lp来调用它里面的方法了,比如请求数据
public class DemoActivity extends BaseActivity implements View.OnClickListener,GetDataInterface
三、总结
这是自己动手搭建的框架,其中也遇到不少问题,也参考了RxJavaSamples-master的代码,也是一种尝试。
有需要的也可以下载源码,但是我把url去掉了,不能够直接看效果。
源码
- Android MVP+RXJava+Retrofit框架的初步构建
- Mvp-Retrofit-Rxjava-Rxbus的初步使用
- RxJava+Retrofit+MVP框架
- Rxjava + retrofit + dagger2 + mvp搭建Android框架
- 优雅的使用MVP+RxJava+Retrofit框架
- Retrofit+RXJava+MVP的框架搭建
- Android MVP +Retrofit+RxJava
- Android Mvp快速搭建框架MVP+Dagger2+Retrofit+Rxjava
- Android中的RxJava,Retrofit,MVP的使用
- Android--MVP+Retrofit+Rxjava的实现
- Android MVP+RxJava+Retrofit 的简单模型
- RxJava+Retrofit+OkHttp3+Dagger2+MVP构建Android项目简单例子
- MVP+Retrofit+RxJava+Dagger框架
- RxJava+Retrofit+MVP构建的App——聚合资讯
- 【android进阶篇】MVP+Retrofit+RxJava框架结合
- Android 一步步搭建MVP+Retrofit+RxJava网络请求框架
- Android 搭建MVP+Retrofit+RxJava网络请求框架
- Android Mvp+Rxjava+Retrofit实战
- Android开发环境搭建
- Eclipse / MyEclipse 常用快捷键使用总结
- Luogu P1981 表达式求值
- ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第六章:管理产品图片——多对多关系(上篇)
- cin.get()与cin.peek()的使用
- Android MVP+RXJava+Retrofit框架的初步构建
- org.hibernate.LazyInitializationException: failed to lazily initialize异常记录
- tensorflow+入门笔记︱基本张量tensor理解与tensorflow运行结构
- Java中有关正则表达式的学习笔记
- windbg下看系统非分页内存
- Spring Security(01)——初体验
- 【Unity】3D物体透明化方法
- DVWA-1.9系列操作之CSRF
- Long和long的区别