retrofit+okhttp+rxjava使用、封裝
阿新 • • 發佈:2018-11-09
概述
該demo對聯網框架進行了封裝,包括連網獲取,activity onDestroy時網路取消,請求響應的log,聯網的管理等。
所需依賴
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
整體結構
下面是目錄結構
1.NetCore
該類為單例類,做retrofit和NetApi例項初始化,方便NetService呼叫
/** * author: zhouchaoxiang * date: 2018/6/22 * explain: */ public class NetCore { private final Retrofit mRetrofit; private final NetApi mNetApi; private static class Instance { private static NetCore instance= new NetCore(); } public static NetCore getInstance() { return Instance.instance; } private NetCore() { mRetrofit = new Retrofit.Builder() .baseUrl("http://127.0.0.1:8080/android/") .client(getOkHttpClient()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .build(); mNetApi = mRetrofit.create(NetApi.class); } public NetApi getNetApi() { return mNetApi; } /** * OkHttpClient */ private OkHttpClient getOkHttpClient() { return new OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.SECONDS) .writeTimeout(10, TimeUnit.SECONDS) .addInterceptor(new LoggingInterceptor())//聯網日誌列印 .build(); } }
2.NetApi
定義聯網介面
/** * author: zhouchaoxiang * date: 2018/6/27 * explain: */ public interface NetApi { @GET("get/{path}") Observable<ResponseBody> get(@Path("path") String path, @Query("param") String param); @FormUrlEncoded @POST("post") Observable<TextBean> post(@Field("param") String param); @POST("http://127.0.0.1:8080/android/post2") Observable<ResponseBody> post2(@Body RequestBean requestBean); @Multipart @POST("upload") Observable<ResponseBody> upload(@Part("description") RequestBody description, @Part MultipartBody.Part file); }
3.NetService
聯網的實體類,在這裡初始化NetCore,並呼叫聯網方法,和上面的NetApi對應
/** * author: zhouchaoxiang * date: 2018/6/27 * explain: 聯網實體類 */ public class NetService { private static NetApi mNetApi = NetCore.getInstance().getNetApi(); public static void get(String param) { mNetApi.get("path", param); } public static void post(String param, DemoObserver<TextBean> observer) { requestHandler(mNetApi.post(param)) .subscribe(observer); } public static void upload(RequestBody description, MultipartBody.Part file, DemoObserver<ResponseBody> observer) { requestHandler(mNetApi.upload(description, file)) .subscribe(observer); } /** * 聯網執行緒切換,也可做返回資料的統一處理 */ private static <RESPONSE> Observable<RESPONSE> requestHandler(Observable<RESPONSE> response) { return response.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } }
4.DemoObserver
對rxjava的Observer封裝,所有的聯網訂閱事件交給SubscriptionManager管理
/** * author: zhouchaoxiang * date: 2018/6/27 * explain: */ public abstract class DemoObserver<T> implements Observer<T> { private final BasePresent mPresent; public DemoObserver(BasePresent present) { mPresent = present; } @Override public void onSubscribe(Disposable d) { mPresent.addDisposable(d); SubscriptionManager.getInstance().add(d); onBefore(d); } @Override public void onNext(T value) { if (null == value) { onFail(ExceptionHandle.ERROR.NULL_ERROR); } else { onSuccess(value); } } @Override public void onError(Throwable e) { e.printStackTrace(); ExceptionHandle.ERROR error = ExceptionHandle.handleException(e); onFail(error); } @Override public void onComplete() { onCompleted(); } protected void onBefore(Disposable d) { } protected void onCompleted() { } protected abstract void onSuccess(T value); protected abstract void onFail(ExceptionHandle.ERROR error); }
5.SubscriptionManager
rxjava訂閱管理類
/** * author: zhouchaoxiang * date: 2018/6/27 * explain: */ public class SubscriptionManager { private CompositeDisposable mDisposables; private static class Instance { private static SubscriptionManager instance = new SubscriptionManager(); } public static SubscriptionManager getInstance() { return Instance.instance; } private SubscriptionManager() { mDisposables = new CompositeDisposable(); } public void add(Disposable d) { if (null != d) mDisposables.add(d); } public void addAll(Disposable... d) { if (null != d) mDisposables.addAll(d); } public void cancel(Disposable d) { if (null != d) mDisposables.delete(d); } public void cancelAll() { mDisposables.clear(); } }
到這裡網路請求部分就封裝完了,下面是使用了
6.BasePresenter
/** * author: zhouchaoxiang * date: 2018/6/27 * explain: */ public class BasePresent<V extends BaseView> { protected V view; private List<Disposable> mDisposables = new ArrayList<>();//訂閱集合 public BasePresent(V view) { this.view = view; } /** * 斷開連線 */ public void detach() { if (null != view) view = null; //取消訂閱 for (Disposable disposable : mDisposables) { if (!disposable.isDisposed()) { SubscriptionManager.getInstance().cancel(disposable); } } mDisposables.clear(); } /** * 新增聯網標識,方便移除 */ public void addDisposable(Disposable disposable) { mDisposables.add(disposable); } }
7.BaseActivity
/** * author: zhouchaoxiang * date: 2018/6/28 * explain: */ public abstract class BaseActivity<p extends BasePresent> extends AppCompatActivity { protected p mPresent; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); mPresent = getPresent(); initData(); initView(); initEvent(); } protected abstract p getPresent(); protected abstract void initData(); protected abstract void initView(); protected abstract void initEvent(); @Override protected void onDestroy() { super.onDestroy(); //分離present if (null != mPresent) { mPresent.detach(); mPresent = null; } } }
8.TextActivity
/** * author: zhouchaoxiang * date: 2018/6/28 * explain: */ public class TextActivity extends BaseActivity<TextPresent> implements TextView { private static final String TAG = "http"; Button mBtNetworking; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { setContentView(R.layout.acitivity_text); super.onCreate(savedInstanceState); } @Override protected TextPresent getPresent() { return new TextPresent(this); } @Override protected void initData() { } @Override protected void initView() { mBtNetworking = findViewById(R.id.bt_networking); } @Override protected void initEvent() { mBtNetworking.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mPresent.post("param"); } }); } @Override public void onPostSuccess() { Log.i(TAG, "onPostSuccess: 請求成功"); } @Override public void onPostFail(ExceptionHandle.ERROR fail) { Log.i(TAG, "onPostSuccess: 請求失敗:" + fail.getMessage()); } }
9.TextPresent
/** * author: zhouchaoxiang * date: 2018/6/28 * explain: */ public class TextPresent extends BasePresent<TextView> { private static final String TAG = "http"; public TextPresent(TextView view) { super(view); } public void post(String param) { NetService.post(param, new DemoObserver<TextBean>(this) { @Override protected void onSuccess(TextBean value) { view.onPostSuccess(); } @Override protected void onFail(ExceptionHandle.ERROR error) { view.onPostFail(error); } }); } public void upload(File file) { // 建立 RequestBody,用於封裝構建RequestBody RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file); // MultipartBody.Part 和後端約定好Key,這裡的partName是用image MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestFile); // 新增描述 String descriptionString = "hello, 這是檔案描述"; RequestBody description = RequestBody.create(MediaType.parse("multipart/form-data"), descriptionString); NetService.upload(description, body, new DemoObserver<ResponseBody>(this) { @Override protected void onSuccess(ResponseBody value) { view.onPostSuccess(); } @Override protected void onFail(ExceptionHandle.ERROR error) { view.onPostFail(error); } }); } }
到這裡就結束了。
新增一個demo地址:https://github.com/xiaoXiangGuo/android/tree/master