RxJava框架【库】Android开发

RxJava<第三十二篇>:RxJava+Retro

2019-04-14  本文已影响16人  NoBugException

本章主要针对RxJavaRetrofitOkHttp结合使用,现在说明一下三者的职责所在。

OkHttp:负责网络请求;
Retrofit:主要负责网络请求接口的封装,结合OkHttp可以处理网络请求的结果;
RxJava:负责网络请求的异步;

(1)权限

网络请求别忘了添加网络权限

<uses-permission android:name="android.permission.INTERNET" />
(2)依赖
implementation 'io.reactivex.rxjava2:rxjava:2.1.3'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'

或者

implementation 'com.jakewharton.rxbinding3:rxbinding:3.0.0-alpha2'

如果使用rxbinding,就添加rxbinding相关依赖,rxbinding依赖本身支持rxjava和rxandroid,所以如果添加rxbinding依赖就可以去除rxjava和rxandroid依赖了。

implementation 'com.squareup.okhttp3:okhttp:3.14.0'
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
//gson依赖
implementation 'com.google.code.gson:gson:2.8.5'
//gson转换器依赖
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
 //日志拦截器依赖
implementation 'com.squareup.okhttp3:logging-interceptor:3.5.0'
(3)具体实现
    public interface SearchFileAPIService {
   
            @FormUrlEncoded
            @POST("/selfClaim/interface/carList")
            Observable<ArrayList<Car>> getCarList(@Field("IMEI") String IMEI, @Field("appid") String appid, @Field("appkey") String appkey, @Field("userId") String userId);
    
    }
    Retrofit retrofit = new Retrofit.Builder().baseUrl("http://xxxx:7001")
            .addConverterFactory(GsonConverterFactory.create(new Gson()))
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build();
    SearchFileAPIService retrofitTest = retrofit.create(SearchFileAPIService.class);
    Observable<ArrayList<Car>> observable = retrofitTest.getCarList("868256021322879", "862679", "c907d5df8b26550eaf2841ed9bcf51bb44b9ae1b", "d3974829a20747579c90e2004a5ed1c5");
    observable
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<ArrayList<Car>>() {
                @Override
                public void onSubscribe(Disposable d) {
                    //开始请求
                }

                @Override
                public void onNext(ArrayList<Car> cars) {
                    //成功
                    for(Car car : cars){
                        Log.d("aaa", car.getCarNumber());
                    }
                }

                @Override
                public void onError(Throwable e) {
                    e.printStackTrace();
                    //失败
                    Log.d("aaa", "onFailure:"+e.getCause() + "\n" + e.getMessage());
                }

                @Override
                public void onComplete() {
                    //结束请求
                }
            });

单独使用Retrofit,网络请求的返回值类型是Call,与RxJava结合使用后返回值变成了observable,这样做的好处是:

另外,OkHttp可以设置网络超时以及其他配置。

(4)学会自主封装网络请求

封装网络请求需要大家自主完成,因为不同的项目可能有不同的封装方式,思路如下:

下面我直接贴一下我自己封装之后的代码,用到的技术有RxJavaRetrofitOkHttpMVPrxjava

(1) RetrofitAPI.java

public interface RetrofitAPI {

    @FormUrlEncoded
    @POST("/selfClaim/interface/carList")
    Observable<ArrayList<Car>> getCarList(@Field("IMEI") String IMEI, @Field("appid") String appid, @Field("appkey") String appkey, @Field("userId") String userId);

    @FormUrlEncoded
    @POST("/selfClaim/interface/interface1")
    Observable<ArrayList<Car>> getA(@Field("IMEI") String IMEI, @Field("appid") String appid, @Field("appkey") String appkey, @Field("userId") String userId);

    @FormUrlEncoded
    @POST("/selfClaim/interface/interface2")
    Observable<ArrayList<Car>> getB(@Field("IMEI") String IMEI, @Field("appid") String appid, @Field("appkey") String appkey, @Field("userId") String userId);

}

(2) RetrofitUtils.java

public class RetrofitUtils {

    private RetrofitAPI retrofitAPI;

    private String BASE_URL = "http://xxx.124.175.239:7001";

    private RetrofitUtils(){
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(10, TimeUnit.SECONDS)//设置连接超时时长
                .readTimeout(20, TimeUnit.SECONDS)//设置读超时时长
                .writeTimeout(20, TimeUnit.SECONDS)//设置写超时时长
                .addInterceptor(getHttpLoggingInterceptor())//添加日志拦截器
                .build();
        Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create(new Gson()))
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .client(client)
                .build();
        retrofitAPI = retrofit.create(RetrofitAPI.class);
    }

    static class SingleHolder{
        public static RetrofitUtils instance = new RetrofitUtils();
    }

    public static RetrofitUtils getInstance(){
        return RetrofitUtils.SingleHolder.instance;
    }

    /**
     * 创建日志拦截器
     * @return
     */
    private HttpLoggingInterceptor getHttpLoggingInterceptor() {
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(
                new HttpLoggingInterceptor.Logger() {

                    @Override
                    public void log(String message) {
                        Log.e("aaa", "log = " + message);
                    }

                });
        loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        return loggingInterceptor;
    }

    public RetrofitAPI getRetrofitAPI(){
        return retrofitAPI;
    }


    /**
     * 通用方法
     * @param activity
     * @param observable
     * @param <T>
     */
    public <T> void getDataFromAPI(Activity activity, Observable<T> observable, ResultCallBack callBack){
        observable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                //AutoDispose的关键语句
                .as(AutoDispose.<T>autoDisposable(AndroidLifecycleScopeProvider.from((LifecycleOwner) activity)))
                .subscribe(new Observer<T>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        //开始请求
                        if(activity instanceof BaseActivity){
                            BaseActivity baseActivity = (BaseActivity) activity;
                            baseActivity.loadingDialogShow("请稍等...");
                        }
                    }

                    @Override
                    public void onNext(T t) {
                        //成功
                        callBack.success(t);

                    }

                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                        //失败
                        Log.d("aaa", "onFailure:"+e.getCause() + "\n" + e.getMessage());

                        if (e instanceof SocketTimeoutException) {
                            callBack.failed("网络中断,请检查您的网络状态!");
                        } else if (e instanceof ConnectException) {
                            callBack.failed("网络中断,请检查您的网络状态!");
                        }else{
                            callBack.failed("未知异常!");
                        }

                        if(activity instanceof BaseActivity){
                            BaseActivity baseActivity = (BaseActivity) activity;
                            baseActivity.loadingDialogDismiss();
                        }
                    }

                    @Override
                    public void onComplete() {
                        //结束请求
                        if(activity instanceof BaseActivity){
                            BaseActivity baseActivity = (BaseActivity) activity;
                            baseActivity.loadingDialogDismiss();
                        }
                    }
                });
    }

}

(3) 网络请求进度条对话框

<!-- 自定义loading dialog -->
<style name="loading_dialog" parent="android:style/Theme.Dialog">
    <item name="android:windowFrame">@null</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowIsFloating">true</item>
    <item name="android:backgroundDimEnabled">false</item>
    <item name="android:windowBackground">@color/bg_dialog_white</item>
    <item name="android:windowContentOverlay">@null</item>
</style>
public class BaseActivity extends AppCompatActivity {

    private Dialog loadingDialog;

    /**
     * 弹出进度条
     */
    public void loadingDialogShow(String msg) {
        TextView tipTextView = null;
        if (loadingDialog == null) {
            LayoutInflater inflater = LayoutInflater.from(this);
            View v = inflater.inflate(R.layout.loading_dialog, null);// 得到加载view
            LinearLayout layout = v.findViewById(R.id.dialog_view);// 加载布局
            ImageView spaceshipImage = v.findViewById(R.id.img);
            tipTextView = v.findViewById(R.id.tipTextView);// 提示文字
            // 加载动画
            Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(this, R.anim.loading_animation);
            // 使用ImageView显示动画
            spaceshipImage.startAnimation(hyperspaceJumpAnimation);
            tipTextView.setText(msg);// 设置加载信息

            loadingDialog = new Dialog(this, R.style.loading_dialog);// 创建自定义样式dialog
            loadingDialog.setCanceledOnTouchOutside(false);
            loadingDialog.setCancelable(true);// 不可以用“返回键”取消
            loadingDialog.setContentView(layout, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));// 设置布局
        }

        tipTextView.setText(msg);

        if (!loadingDialog.isShowing()) {
            loadingDialog.show();
        }
    }

    /**
     * 关闭进度条
     */
    public void loadingDialogDismiss() {

        if (loadingDialog != null && loadingDialog.isShowing()) {
            try {
                loadingDialog.dismiss();
                loadingDialog = null;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //关闭进度条
        loadingDialogDismiss();
    }
}

loading_dialog.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/dialog_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@android:color/transparent"
    android:gravity="center"
    android:orientation="horizontal"
    android:padding="10dp" >

    <ImageView
        android:id="@+id/img"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:scaleType="center"
        android:src="@mipmap/aliwx_img_loading" />

    <TextView
        android:id="@+id/tipTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textStyle="bold"
        android:layout_marginLeft="5dp"
        android:textColor="#FF34A350"
        android:text="数据加载中……"
        android:textSize="16sp" />

</LinearLayout>

图标:aliwx_img_loading.png

aliwx_img_loading.png

(4) HttpModel.java

public class HttpModel {

    private String IMEI = "868256021322879";
    private String appid = "862679";
    private String appkey = "c907d5df8b26550eaf2841ed9bcf51bb44b9ae1b";
    private RetrofitAPI retrofitAPI;


    public HttpModel(){
        retrofitAPI = RetrofitUtils.getInstance().getRetrofitAPI();
    }

    /**
     * 获取车辆列表
     */
    public void getCarList(Activity activity, String userID, ResultCallBack callBack){
        RetrofitUtils.getInstance().getDataFromAPI(activity, retrofitAPI.getCarList(IMEI, appid, appkey, userID), callBack);
    }

    /**
     * 获取车辆列表
     */
    public void getA(Activity activity, String userID, ResultCallBack callBack){
        RetrofitUtils.getInstance().getDataFromAPI(activity, retrofitAPI.getA(IMEI, appid, appkey, userID), callBack);
    }

    /**
     * 获取车辆列表
     */
    public void getB(Activity activity, String userID, ResultCallBack callBack){
        RetrofitUtils.getInstance().getDataFromAPI(activity, retrofitAPI.getB(IMEI, appid, appkey, userID), callBack);
    }
}

(5) IMainView.java

public interface IMainView {

    void setResult(String result);

}

(6) 辅助接口

public interface ResultCallBack<T> {

    void success(T t);

    void failed(String error);

}

(7) MainPresenter.java

public class MainPresenter {

    private HttpModel httpModel;
    private IMainView view;

    public MainPresenter(IMainView view){
        httpModel = new HttpModel();
        this.view = view;
    }

    /**
     * 获取车辆列表1
     * @param activity
     */
    public void getCarList(Activity activity, String userID){
        httpModel.getCarList(activity, userID, new ResultCallBack<ArrayList<Car>>() {
            @Override
            public void success(ArrayList<Car> cars) {
                if(cars != null && cars.size() > 0){
                    view.setResult("已获取到车辆!");
                    for(int i=0;i<cars.size();i++){
                        Log.d("aaa", "success:"+cars.get(i).getCarNumber());
                    }
                }else{
                    view.setResult("没有获取到车辆!");
                }

            }

            @Override
            public void failed(String error) {
                view.setResult(error);
            }
        });
    }

}

(8) 界面

public class MainActivity extends BaseActivity implements IMainView {

    private TextView result_text;
    private MainPresenter mainPresenter;

    @SuppressLint("CheckResult")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        result_text = findViewById(R.id.result_text);

        mainPresenter = new MainPresenter(this);

        RxView.clicks(findViewById(R.id.bt_1))
                .throttleFirst(2, TimeUnit.SECONDS)
                //AutoDispose的关键语句
                .as(AutoDispose.<Unit>autoDisposable(AndroidLifecycleScopeProvider.from(this)))
                .subscribe(new Consumer<Unit>() {
                    @Override
                    public void accept(Unit unit) throws Exception {
                        //获取车辆别表
                        mainPresenter.getCarList(MainActivity.this, "d3974829a20747579c90e2004a5ed1c5");

                    }
                });
    }

    @Override
    public void setResult(String result) {
        //显示结果
        result_text.setText(result);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mainPresenter = null;
    }
}
(5)展示效果
44.gif
上一篇下一篇

猜你喜欢

热点阅读