使用 RxJava 和 Retrofit

使用 RxJava 和 Retrofit

一、RxJava 简介

RxJavaReactive ExtensionsJVM实现:用于通过使用observable序列来构建异步和基于事件的程序的库。官方描述:

RxJava is a Java VM implementation of Reactive Extensions: a library for composing asynchronous and event-based programs by using observable sequences.

It extends the observer pattern to support sequences of data/events and adds operators that allow you to compose sequences together declaratively while abstracting away concerns about things like low-level threading, synchronization, thread-safety and concurrent data structures.

二、RxJava 配合 Retrofit 使用

1.添加gradle依赖

compile 'com.squareup.retrofit2:retrofit:2.2.0'
compile 'com.squareup.retrofit2:converter-gson:2.2.0'
compile 'com.squareup.retrofit2:adapter-rxjava2:2.2.0'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'

2.在 AndroidManifest.xml 里加入网络访问权限,创建 MovieEntity 实体类,解析服务器返回的 JSON 数据,建议使用 Gson 解析,使用 GsonFormatGsonOrXmlFormat 插件一键生成

<uses-permission android:name="android.permission.INTERNET"/>
// MovieEntity 类的代码就不贴了

3.创建一个Java接口 ApiService 来作为HTTP请求接口,返回值是 Observable

public interface ApiService {
    @GET("top250")
    Observable<MovieEntity> getTopMovies(@Query("start") int start, @Query("count") int count);
}

4.实例化 Retrofit ,并通过 Retrofit 对象实现上面的接口,封装在 HttpMethod 类里面,并且实现接口的方法。

public class HttpMethods {
    private static final String BASE_URL = "https://api.douban.com/v2/movie/";
    private static final int TIME_OUT = 4;
    private Retrofit retrofit;
    private ApiService apiService;


    /**
     * 私有化构造函数
     */
    private HttpMethods() {
        OkHttpClient client = new OkHttpClient();
        client.newBuilder().connectTimeout(TIME_OUT, TimeUnit.SECONDS);

        retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();
        apiService = retrofit.create(ApiService.class);
    }

    /**
     * 创建单例
     */
    private static class SingleInstance{
        private static final HttpMethods INSTANCE = new HttpMethods();
    }

    /**
     * 获取单例
     * @return
     */
    public static HttpMethods getInstance(){
        return SingleInstance.INSTANCE;
    }

    /**
     * get top movies
     * @param start 起始位置
     * @param count 获取数量
     * @param observer 观察值对象
     */
    public void getTopMovies(int start, int count, Observer<MovieEntity> observer) {
        apiService.getTopMovies(start, count)
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer);
    }

5.MainActivity 里实现请求

public class MainActivity extends AppCompatActivity {
    private final String TAG = String.valueOf(getCallingActivity());
    //private static String BASE_URL = "https://api.douban.com/v2/movie/";
    private Button getData;
    private RecyclerView recyclerView;
    private List<String> dataList = new ArrayList<>();
    private int START = 0; // 起始页数
    private int COUNT = 25; // 每次加载数量

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

        // 设置 RecyclerView
        recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setHasFixedSize(true);

        // 设置 Button
        getData = (Button) findViewById(R.id.get_data);
        getData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getMovies();
            }
        });
    }


    private void getMovies() {
        HttpMethods.getInstance().getTopMovies(START,COUNT, new Observer<MovieEntity>() {
            @Override
            public void onSubscribe(Disposable d) {
                Log.e(TAG, "onSubscribe: " + d.toString());
            }

            /**
             * 请求成功
             * @param value 返回数据
             */
            @Override
            public void onNext(MovieEntity value) {
                for (int i = 0; i < COUNT; i++) {
                    if (START < 250/COUNT){ // 判断是否加载完
                        String title = value.getSubjects().get(i).getTitle();
                        Log.e(TAG, "onNext: " + (i+(START-1)*COUNT+1) + title);
                        dataList.add(title);
                    } else {
                        dataList.add("没有更多了");
                    }
                }
                recyclerView.setAdapter(new MyAdapter(dataList));
            }

            /**
             * 请求错误
             * @param e 抛出异常
             */
            @Override
            public void onError(Throwable e) {
                Log.e(TAG, "onError: " + e.getMessage());

            }

            /**
             * 每次请求完成执行
             */
            @Override
            public void onComplete() {
                Log.e(TAG, "onComplete: ");
            }
        });
        START++; // 页数加一
    }
}
  • 附上:RecyclerView 的 Adapter 和 ViewHolder
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>{

    private List<String> datas = null;
    public MyAdapter(List<String> datas) {
        this.datas = datas;
    }


    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item,parent,false);
        ViewHolder holder = new ViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.title.setText(datas.get(position));
    }

    @Override
    public int getItemCount() {
        return datas.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        public TextView title;
        public ViewHolder(View itemView) {
            super(itemView);
            title = (TextView) itemView.findViewById(R.id.title);
        }
    }
}
  • 效果图:
    这里写图片描述
    这里写图片描述

参考:

  1. tough1985: RxJava 与 Retrofit 结合的最佳实践

  2. 扔物线: 给 Android 开发者的 RxJava 详解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值