1. RxJAVA简介
1.1 响应式编程
在介绍RxJava前,我们先聊聊响应式编程。那么什么是响应式编程呢?响应式编程是一种基于异步数据 流概念的编程模式。数据流就像一条河:它可以被观测,被过滤,被操作,或者为新的消费者与另外一 条流合并为一条新的流。 响应式编程的一个关键概念是事件。事件可以被等待,可以触发过程,也可以触发其它事件。事件是唯 一的以合适的方式将我们的现实世界映射到我们的软件中:如果屋里太热了我们就打开一扇窗户。同样 的,当我们的天气app从服务端获取到新的天气数据后,我们需要更新app上展示天气信息的UI;汽车上 的车道偏移系统探测到车辆偏移了正常路线就会提醒驾驶者纠正,就是是响应事件。 今天,响应式编程最通用的一个场景是UI:我们的移动App必须做出对网络调用、用户触摸输入和系统弹框的响应。在这个世界上,软件之所以是事件驱动并响应的是因为现实生活也是如此。
1.2 什么是RxJava
1.RxJava 是一种响应式编程,来创建基于事件的异步操作库。基于事件流的链式调用、逻辑清晰简 洁。
2.RxJava 我的理解是将事件从起点(上游)流向终点(下游),中间有很多卡片对数据进操作并传 递,每个卡片获取上一个卡片传递下来的结果然后对事件进行处理然后将结果传递给下一个卡片, 这样事件就从起点通过卡片一次次传递直到流向终点。
3.RxJava本质上是一个异步操作库,是一个能让你用极其简洁的逻辑去处理繁琐复杂任 务的异步事件库。
1.3 RxJava好在哪
Android平台上为已经开发者提供了AsyncTask,Handler等用来做异步操作的类库,那我们为什么还要选 择RxJava呢?答案是简洁!RxJava可以用非常简洁的代码逻辑来解决复杂问题;而且即使业务逻辑的越 来越复杂,它依然能够保持简洁!再配合上Lambda用简单的几行代码分分钟就解决你负责的业务问 题。
1.4RxJava原理理解
如图:
2.观察者模式
举个栗子,Android中View的点击监听器的实现,View是被观察者,OnClickListener对象是观察者, Activity要如何知道View被点击了?那就是派一个OnClickListener对象,入驻View,与View达成一个订 阅关系,一旦View被点击了,就通过OnClickListener对象的OnClick方法传达给Activity。采用观察者模 式可以避免去轮询检查,节约有限的cpu资源。
2.1使用
在使用之前我们需要导入依赖哦!
//for rxjava
implementation 'io.reactivex.rxjava2:rxjava:2.2.6'
//for rxandroid
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
//衔接 Retrofit & RxJava,此处一定要注意使用RxJava2的版本
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.5.0'
1. 建立被观察者 (Observable ) & 生产事件
Observable<Integer> observable = Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(@NonNull ObservableEmitter<Integer> emitter) throws Throwable {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
emitter.onNext(4);
emitter.onComplete();
}
});
2. 建立观察者 (Observer ) 并 定义响应事件的行为
Observer<Integer> observer = new Observer<Integer>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
Log.i("onSubscribe","对onSubscribe作出响应");
}
@Override
public void onNext(@NonNull Integer integer) {
Log.i("onNext","对onNext作出响应");
}
@Override
public void onError(@NonNull Throwable e) {
Log.i("onError","对onError作出响应");
}
@Override
public void onComplete() {
Log.i("onComplete","对onComplete作出响应");
}
};
3. 经过订阅 (Subscribe) 链接观察者和被观察者
observable.subscribe(observer);
3.Retrofit+RxJava的使用
3.1结合使用的目的?
3.1.1代码简洁
借助 retorfit 加 rxjava,我们就不需要再做其他多余的封装或修改。网络请求写起来就会简单许多,而 且结构也清晰。被观察者就是请求的发起,观察者就是请求的回调。
3.1.2操作符的作用
rxjava 的优势就在于其操作符的使用,我理解的「操作符」就是 rxjava 为我们提供了一系列方法,可以 运用在观察者模式中的「被观察者」「观察者」或「订阅过程」之间来控制。实际项目中我遇到过以下 几种常见情况,可以用操作符来处理。
1. 请求结果需要做数据处理之后,再给页面展示。 「map」操作符,这个操作符就是在请求回来之 后直接对数据做处理之后再返回给观察者。
2. 请求结果是做为下一个请求的请求入参。「flatMap」操作符,这个操作符是在遇到串联请求时使 用的,当第一个请求返回结果之后,再拿着结果去请求下一个接口。
3.2使用
3.2.1添加依赖
//for rxjava
implementation 'io.reactivex.rxjava2:rxjava:2.2.0'
//for rxandroid
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
//rxjava adapter for retrofit
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.5.0'
3.2.2retrofit 配置
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.vvhan.com/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
3.2.3开始改造
因为 rxjava 采用了观察者模式,所以整体思想是要有一个被观察者,一个观察者以及一个订阅关系。 被观察者 Observable 就是我们的请求方法。
public interface GetNews_interface {
@GET("api/hotlist?type=baiduRD")
Observable<News> getCall();
}
call.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<News>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(News news) {
adapter.setList(news.getData());
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
4.Retrofit+OkHTTP+RxJava+RecycleView的实现
步骤如下:
1.创建项目
2.导入依赖
3.添加网络权限
<uses-permission android:name="android.permission.INTERNET" />
4.在activity_main.xml添加Recycle,并给其设置id
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_show"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
5.创建子布局
news_item.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
app:cardCornerRadius="5dp"
android:elevation="5dp"
android:layout_height="200dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/iv_show"
android:layout_width="200dp"
android:layout_height="190dp"
android:scaleType="fitXY" />
<TextView
android:layout_width="200dp"
android:layout_height="40dp"
android:layout_alignParentTop="true"
android:layout_toRightOf="@id/iv_show"
android:id="@+id/tv_title"
android:textStyle="bold"/>
<TextView
android:layout_marginTop="40dp"
android:layout_width="wrap_content"
android:layout_height="155dp"
android:layout_below="@id/tv_title"
android:layout_toRightOf="@id/iv_show"
android:id="@+id/tv_desc"/>
</RelativeLayout>
</androidx.cardview.widget.CardView>
6.创建实体类
public class News {
private boolean success;
private String title;
private String subtitle;
private String update_time;
private List<Data> data;
public News(List<Data> data) {
this.data = data;
}
public class Data {
private String title;
private String pic;
private String desc;
public Data(String title, String pic, String desc) {
this.title = title;
this.pic = pic;
this.desc = desc;
}
public String getTitle() {
return title;
}
public String getPic() {
return pic;
}
public String getDesc() {
return desc;
}
}
public List<Data> getData() {
return data;
}
@Override
public String toString() {
return "News{" +
"success=" + success +
", title='" + title + '\'' +
", subtitle='" + subtitle + '\'' +
", update_time='" + update_time + '\'' +
", data=" + data +
'}';
}
}
7.创建适配器
public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.ViewHolder> {
private List<News.Data> list;
public void setList(List<News.Data> list){
this.list = list;
notifyDataSetChanged();
}
@NonNull
@Override
public NewsAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.news_item, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull NewsAdapter.ViewHolder holder, int position) {
News.Data data = list.get(position);
holder.tv_title.setText(data.getTitle());
holder.tv_desc.setText(data.getDesc());
Glide.with(holder.view).load(data.getPic()).into(holder.iv_show);
}
@Override
public int getItemCount() {
return list == null ? 0:list.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
View view;
private ImageView iv_show;
private TextView tv_title,tv_desc;
public ViewHolder(@NonNull View itemView) {
super(itemView);
iv_show = itemView.findViewById(R.id.iv_show);
tv_title = itemView.findViewById(R.id.tv_title);
tv_desc = itemView.findViewById(R.id.tv_desc);
view = itemView;
}
}
}
8.设置适配器
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rv_show = findViewById(R.id.rv_show);
//设置适配器
adapter = new NewsAdapter();
rv_show.setAdapter(adapter);
//设置布局
LinearLayoutManager layoutManager = new LinearLayoutManager(MainActivity.this);
rv_show.setLayoutManager(layoutManager);
initData01();
}
9.进行网络请求
1. 创建请求接口
2. 开始网络请求
3. 处理返回结果
private void initData01() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.vvhan.com/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
//实例化接口
GetNews_interface request = retrofit.create(GetNews_interface.class);
//封装请求
Observable<News> call = request.getCall();
call.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<News>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(News news) {
adapter.setList(news.getData());
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
}