1. 程式人生 > >retrofit+okhttp+rxjava使用、封裝

retrofit+okhttp+rxjava使用、封裝

概述

該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