RxJava异步请求加载状态控制

Posted 骑猪撞交警

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RxJava异步请求加载状态控制相关的知识,希望对你有一定的参考价值。

在我看来,RxJava最大的特点就是异步,无论你是解析复杂的数据或是IO操作,我们都可以利用它内置的线程池进行线程间的调度,简单的使用

subscribeOn(Schedulers.io()).doOnNext(...)
observeOn(AndroidSchedulers.mainThread()).doOnNext(...)

这种操作就可以指定操作在你想要的线程里执行.

当然,网络请求这种耗时的操作肯定也是要放在子线程执行的,那么是异步操作,我们就会有等待时间,安卓里通常的做法是在界面上盖一个加载中的loading;等操作完成,切换到UI线程时,我们再把它隐藏起来.

于是有

private final HomeContract.View mView;
retrofit.create(ApiService.class)
                .getHomeData(loginCallInfo.getAccessToken(), loginCallInfo.getUserId(), Constants.PLATFORM, Constants.APPLICATIONID, 1)
                .subscribeOn(Schedulers.io())
                .observeOn(androidSchedulers.mainThread())
                .subscribe(new Observer<HomeData>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        if (!d.isDisposed()) {
                            mView.setLoadingView();
                        }
                    }

                    @Override
                    public void onNext(HomeData value) {
                        if (value == null) {
                            mView.setEmptyView();
                        } else {
                            mView.setSuccessView();
                            ...//这里显示正常视图
                        }
                    }

                    @Override
                    public void onError(Throwable t) {
                        Logger.d(t.getMessage());
                        mView.setErrorView();
                    }

                    @Override
                    public void onComplete() {

                    }
                });

在HomeContract.java中

public class HomeContract {

    interface View extends BaseView<Presenter> {

        void setLoadingView();

        void setSuccessView();

        void setErrorView();

        void setEmptyView();
    }
}

具体在HomeFragment里的实现

@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle
        savedInstanceState) {
  View root =inflater.inflate(R.layout.fragment_home,container,false);
  progress = (ProgressBar) root.findViewById(R.id.loading);
  fl_excep = (FrameLayout) root.findViewById(R.id.fl_error);
  retry = ((Button) root.findViewById(R.id.btn_retry));
  retry.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    Logger.e("正在重试");//重试操作      }   }); } @Override public void setLoadingView() { if (progress.getVisibility() == View.GONE) { progress.setVisibility(View.VISIBLE); } } @Override public void setSuccessView() { if (progress.getVisibility() == View.VISIBLE) { progress.setVisibility(View.GONE); } } @Override public void setErrorView() { if (progress.getVisibility() == View.VISIBLE) { progress.setVisibility(View.GONE); fl_excep.setVisibility(View.VISIBLE); retry.setText(R.string.request_err); } } @Override public void setEmptyView() { if (progress.getVisibility() == View.VISIBLE) { progress.setVisibility(View.GONE); fl_excep.setVisibility(View.VISIBLE); retry.setText(R.string.empty_des); } }

最后,看下xml布局

fragment_home.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/translucent">
<--这里是你想显示的正常视图-->    
<include layout="@layout/public_loading" />
</FrameLayout>

public_loading.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ProgressBar
        android:id="@+id/loading"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:visibility="gone" />

    <FrameLayout
        android:id="@+id/fl_error"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone">

        <Button
            android:id="@+id/btn_retry"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:background="@null"
            android:text="网络错误,点击重试"
            android:textSize="20sp" />
    </FrameLayout>
</FrameLayout>
这样,一个控制加载状态的功能就写完了.

 







以上是关于RxJava异步请求加载状态控制的主要内容,如果未能解决你的问题,请参考以下文章

ajax同步与异步的区别

ajax的async属性(控制同步和异步)

RxJava2 Observable中的异步任务状态&&取消等效项?

怎么用promise实现异步控制

使用 rxJava 和改造多次调用另一个请求中的请求

最适合使用RxJava处理的四种场景