公司的大佬用的是這一套,那我這個菜鳥確定要學習使用了。php
我在網上找了不少文章,寫的都很詳細,好比java
https://www.jianshu.com/u/5fd2523645dareact
https://www.jianshu.com/p/193d8c37c73candroid
趁熱打鐵,寫一篇學習筆記,理順思路。git
//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'
簡單的說,核心是觀察者模式。那麼這個就頗有意思了,舉個栗子github
我訂閱了公衆號以後就能夠去幹其餘的事了,當公衆號有新的文章以後發個消息通知我:有新文章了。這時我再點開去查看。json
RxJava中有這幾種方法api
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"); } });
當前爲主(main)線程,訂閱(向上走)
1.開始 subscribe 訂閱
2.經 subscribeOn 將線程切換爲IO線程(Schedulers:線程調度器)
3.經 observeOn 控制數據流的,跳過
4.經 create 在IO線程中執行
到這裏,訂閱完成,開始發射數據。
當前爲IO線程,發射數據(向下走)
1.經 observeOn 將線程切換爲主(main)線程
2.經 subscribeOn 控制訂閱的,跳過
3.經 onNext 在主線程中執行
整個流程就走完了。
RxJava還有不少操做符,等後面慢慢學習。
簡單的說,它是網絡適配器,經過OkHttp發送請求
它是將okhttp進行了進一步的封裝翻新
偷張圖哈哈哈 https://www.jianshu.com/p/15edb4de0f62
建立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;} }
定義添加刪除訂閱關係的接口
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(); } } }
網上有不少異常處理的類,能夠去搜一下(忘記我看的哪篇文章了)
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; } } }
上面講到了四個方法以及他們的做用,這裏簡單的封裝一下
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(); }
網上找了很詳細的圖解
View:負責繪製UI元素、與用戶進行交互。
Model:負責存儲、檢索、操縱數據。
Presenter:做爲View與Model交互的中間紐帶,處理與用戶交互的負責邏輯。
M與V層須要P層來進行通訊。
添加訂閱關係,進行網絡請求。
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(); } } }
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(); } }); } }
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
寫下這篇博客是幫助我學習,知識梳理,加深印象。之後也能翻出來看看對吧(狗頭)