公司的大佬用的是这一套,那我这个菜鸟肯定要学习使用了。
我在网上找了很多文章,写的都很详细,比如
https://www.jianshu.com/u/5fd2523645da
https://www.jianshu.com/p/193d8c37c73c
趁热打铁,写一篇学习笔记,理顺思路。
先把他们都引入
//rxjava compile 'io.reactivex.rxjava2:rxjava:2.2.0' compile 'io.reactivex.rxjava2:rxandroid:2.0.2' compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0' //retrofit compile 'com.squareup.retrofit2:retrofit:2.3.0' //okhttp compile 'com.squareup.okhttp3:okhttp:3.11.0' compile 'com.squareup.okio:okio:1.14.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.9.0'
//gson
implementation 'com.google.code.gson:gson:2.8.4' implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
一、RxJava学习
简单的说,核心是观察者模式。那么这个就很有意思了,举个栗子
我订阅了公众号之后就可以去干其他的事了,当公众号有新的文章之后发个消息通知我:有新文章了。这时我再点开去查看。
RxJava中有这几种方法
onNext():一直向我推送文章
onComplete():文章推送完了
onError():推送出现异常,同时终止,不再有消息发出.
onSubscribe():RxJava 2.0 中新增的,传递参数为Disposable,可用于切断接收事件
RxJava的链式操作
Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> emitter) throws Exception { emitter.onNext(1); emitter.onNext(2); emitter.onNext(3); emitter.onComplete(); } }) .observeOn(AndroidSchedulers.mainThread())//回调在主线程 .subscribeOn(Schedulers.io())//执行在io线程 .subscribe(new Observer<Integer>() { @Override public void onSubscribe(Disposable d) { Log.d(TAG, "onSubscribe"); } @Override public void onNext(Integer value) { Log.d(TAG, "onNext=" + value); } @Override public void onError(Throwable e) { Log.d(TAG, "onError"); } @Override public void onComplete() { Log.d(TAG, "onComplete"); } });
线程切换流程(observeOn与subscribeOn)
当前为主(main)线程,订阅(向上走)
1.开始 subscribe 订阅
2.经 subscribeOn 将线程切换为IO线程(Schedulers:线程调度器)
3.经 observeOn 控制数据流的,跳过
4.经 create 在IO线程中执行
到这里,订阅完成,开始发射数据。
当前为IO线程,发射数据(向下走)
1.经 observeOn 将线程切换为主(main)线程
2.经 subscribeOn 控制订阅的,跳过
3.经 onNext 在主线程中执行
整个流程就走完了。
RxJava还有很多操作符,等后面慢慢学习。
二、Retrofit学习
简单的说,它是网络适配器,通过OkHttp发送请求
它是将okhttp进行了进一步的封装翻新
偷张图哈哈哈 https://www.jianshu.com/p/15edb4de0f62
三、进入正题,打通网络请求
1.Retrofit封装
创建Api接口
public interface IApiService { @POST("/lay-eggs/androidtest.php") Observable<TestBean> getData(@Query("time") String time); }
也可以用@QueryMap 直接整一个集合上去。
TestBean用JsonFormat自动生成
创建Retrofit管理类
public class RetrofitManager { private static RetrofitManager retrofitManager; private Retrofit retrofit; private static final String BASE_URL="http://yyyxuan.cn";//根地址 private IApiService apiService; /** * 单例模式 * @return */ public static RetrofitManager getInstance (){ if (retrofitManager==null){ synchronized (RetrofitManager.class){ if (retrofitManager==null){ retrofitManager= new RetrofitManager(); } } } return retrofitManager; } //构造函数 private RetrofitManager(){ initRetrofitManager(); } //创建Retrofit实例 private void initRetrofitManager() { retrofit=new Retrofit.Builder().baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create())//对服务器数据进行解析 .addCallAdapterFactory(RxJava2CallAdapterFactory.create())//RxJava适配器 .build(); apiService=retrofit.create(IApiService.class); } public IApiService apiservice(){return apiService;} }
2.订阅关系处理
定义添加删除订阅关系的接口
public interface SubscriptionHelper<T> { /** * 添加 * @param disposable */ void add(Disposable disposable); /** * 取消 * @param disposable */ void cancel(Disposable disposable); /** * 取消所有 */ void cancelAll(); }
创建订阅关系管理类
public class SubscriptionManager implements SubscriptionHelper<Object> { public static SubscriptionManager subscriptionManager; private CompositeDisposable mDisposables;//存放disposable容器 /** * 构造函数 new CompositeDisposable对象 */ public SubscriptionManager(){ if (mDisposables==null){ mDisposables=new CompositeDisposable(); } } /** * 单例 * @return */ public static SubscriptionManager getInstance(){ if (subscriptionManager==null){ synchronized (SubscriptionManager.class){ if (subscriptionManager==null){ subscriptionManager=new SubscriptionManager(); } } } return subscriptionManager; } /** * 订阅事件加入到CompositeDisposable容器中 * @param disposable 订阅事件 */ @Override public void add(Disposable disposable) { if(disposable==null) return; mDisposables.add(disposable); } /** * 取消订阅事件 * @param disposable 订阅事件 */ @Override public void cancel(Disposable disposable) { if (disposable!=null){ mDisposables.delete(disposable); } } /** * 清除容器所有 */ @Override public void cancelAll() { if (mDisposables!=null){ mDisposables.clear(); } } }
3.异常处理
网上有很多异常处理的类,可以去搜一下(忘记我看的哪篇文章了)
public class ExceptionHandle { private static final int UNAUTHORIZED = 401; private static final int FORBIDDEN = 403; private static final int NOT_FOUND = 404; private static final int REQUEST_TIMEOUT = 408; private static final int INTERNAL_SERVER_ERROR = 500; private static final int BAD_GATEWAY = 502; private static final int SERVICE_UNAVAILABLE = 503; private static final int GATEWAY_TIMEOUT = 504; public static ResponseException handleException(Throwable e){ //转换成ResponseException,根据状态码判定错误信息 ResponseException ex; if(e instanceof HttpException){ HttpException httpException=(HttpException)e; /** * 传入状态码,根据状态码判定错误信息 */ ex=new ResponseException(e,ERROR.HTTP_ERROR); switch (httpException.code()){ case UNAUTHORIZED: ex.message="未验证"; break; case FORBIDDEN: ex.message="服务禁止访问"; break; case NOT_FOUND: ex.message="服务不存在"; break; case REQUEST_TIMEOUT: ex.message="请求超时"; break; case GATEWAY_TIMEOUT: ex.message="网关超时"; break; case INTERNAL_SERVER_ERROR: ex.message="服务器内部错误"; break; case BAD_GATEWAY: break; case SERVICE_UNAVAILABLE: break; default: ex.message = "网络错误"; break; } return ex; }else if(e instanceof JsonParseException || e instanceof JSONException || e instanceof ParseException){ ex=new ResponseException(e,ERROR.PARSE_ERROR); ex.message="解析错误"; return ex; }else if(e instanceof ConnectException){ ex=new ResponseException(e,ERROR.NETWORD_ERROR); ex.message="连接失败"; return ex; }else if(e instanceof javax.net.ssl.SSLHandshakeException){ ex=new ResponseException(e,ERROR.SSL_ERROR); ex.message="证书验证失败"; return ex; }else { ex=new ResponseException(e,ERROR.UNKNOWN); ex.message="未知错误"; return ex; } } /** * 约定异常 */ public static class ERROR{ /** * 自定义异常 */ private static final int UNAUTHORIZED = 401;//请求用户进行身份验证 private static final int UNREQUEST=403;//服务器理解请求客户端的请求,但是拒绝执行此请求 private static final int UNFINDSOURCE=404;//服务器无法根据客户端的请求找到资源 private static final int SEVERERROR=500;//服务器内部错误,无法完成请求。 /** * 协议出错 */ public static final int HTTP_ERROR = 1003; /** * 未知错误 */ public static final int UNKNOWN = 1000; /** * 解析错误 */ public static final int PARSE_ERROR = 1001; /** * 网络错误 */ public static final int NETWORD_ERROR = 1002; /** * 证书出错 */ public static final int SSL_ERROR = 1005; } /** * 自定义Throwable */ public static class ResponseThrowable extends Exception{ public int code; public String message; public ResponseThrowable(Throwable throwable,int code){ super(throwable); this.code=code; } } /** * 服务器异常 */ public class ServerException extends RuntimeException{ public int code; public String message; } /** * 统一异常类,便于处理 */ public static class ResponseException extends Exception{ public int code; public String message; public ResponseException (Throwable throwable,int code){ super(throwable); this.code=code; } } }
4.Observer封装
上面讲到了四个方法以及他们的作用,这里简单的封装一下
public abstract class Observer<T> implements io.reactivex.Observer<T> { @Override public void onSubscribe(Disposable d) { OnDisposable(d); } @Override public void onNext(T t) { OnSuccess(t); } @Override public void onError(Throwable e) { OnFail(ExceptionHandle.handleException(e)); } @Override public void onComplete() { OnCompleted(); } protected abstract void OnDisposable(Disposable d); protected abstract void OnSuccess(T t); protected abstract void OnFail(ExceptionHandle.ResponseException e); protected abstract void OnCompleted(); }
5.MVP搭建
网上找了很详细的图解
View:负责绘制UI元素、与用户进行交互。
Model:负责存储、检索、操纵数据。
Presenter:作为View与Model交互的中间纽带,处理与用户交互的负责逻辑。
M与V层需要P层来进行通信。
Model层
添加订阅关系,进行网络请求。
public class TestModel { public void getTestInfo(String time, Observer<TestBean> observer){ RetrofitManager.getInstance().apiservice().getData(time) .observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.io()) .subscribe(observer); } }
各种基类的封装
P层 用来绑定和解除与v层关系
public class BasePresenter<V extends BaseView> { public V view; /** * 添加view * @param v */ public void addView(V v){ this.view=v; } /** * 解除 */ public void breakView(){ if (view!=null){ view=null; } } }
V层 定义回调功能,可根据不同需求更改
public interface BaseView { /** * 成功回调 * @param object */ void onSuccess(Object object); /** * 失败回调 * @param t 异常 */ void onFail(ExceptionHandle.ResponseException t); /** * 发射结束 */ void onCompleted(); }
activity基类
public abstract class BaseActivity<P extends BasePresenter> extends AppCompatActivity implements BaseView { public Context context; protected P presenter; //获取P层 protected abstract P createPresenter(); //获取是哪个activity protected abstract int getLayoutId(); @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); context=this; setContentView(getLayoutId()); presenter=createPresenter(); presenter.addView(this);//绑定view initView(); initData(); } public void initData(){ }; public void initView(){ }; @Override protected void onDestroy() { super.onDestroy(); if (presenter != null) { presenter.breakView(); SubscriptionManager.getInstance().cancelAll(); } } }
真正的Presenter
public class TestPresenter extends BasePresenter<BaseView> { private TestModel testModel; /** * 绑定M层 */ public TestPresenter (){ testModel=new TestModel(); } public void test(String time){ //网络请求,创建观察者 testModel.getTestInfo(time, new Observer<TestBean>() { @Override protected void OnDisposable(Disposable d) { SubscriptionManager.getInstance().add(d); } @Override protected void OnSuccess(TestBean testBean) { view.onSuccess(testBean); } @Override protected void OnFail(ExceptionHandle.ResponseException e) { view.onFail(e); } @Override protected void OnCompleted() { view.onCompleted(); } }); } }
真正的Activity
public class MainActivity extends BaseActivity<TestPresenter> implements BaseView { String TAG="aaa"; TextView textView; Button button; /** * 绑定p层 * @return */ @Override protected TestPresenter createPresenter() { return new TestPresenter(); } /** * 加载当前activity * @return */ @Override protected int getLayoutId() { return R.layout.activity_main; } /** * 成功回调 * @param object */ @Override public void onSuccess(Object object) { Log.d(TAG, "onSuccess: "+beanToJson(object)); TestBean testBean= (TestBean) object; textView.setText(testBean.getData().getContent()); } /** * 失败回调 * @param t 异常 */ @Override public void onFail(ExceptionHandle.ResponseException t) { Log.d(TAG, t.message.toString()); } @Override public void onCompleted() { } public String beanToJson(Object bean) { Gson gson = new Gson(); String jsonStr = gson.toJson(bean); return jsonStr; } /** * 初始化界面 */ @Override public void initView() { super.initView(); textView=findViewById(R.id.mtv); button=findViewById(R.id.mbtn); } /** * 初始化数据 */ @Override public void initData() { super.initData(); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { presenter.test("123"); } }); } }
别忘了最重要的网络权限(在AndroidManifest.xml)
<uses-permission android:name="android.permission.INTERNET" />
github:https://github.com/steffenx/RxJava-Retrofit-mvp
6.最后
写下这篇博客是帮助我学习,知识梳理,加深印象。以后也能翻出来看看对吧(狗头)