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

猜你喜欢

转载自blog.csdn.net/qq_39191116/article/details/80879813