8.4 RxJava3.X 的线程控制
1. 内置的Scheduler
如果我们不指定线程,则默认是在调用subscribe方法的线程上进行回调。 如果我们想要切换的话,就会用到Scheduler。 下面是RxJava几个内置的Scheduler(调度器)
2. 控制线程
在RxJava中使用subscribeOn和observeOn操作符可以来控制线程。 使用方法详情见前面笔记。
RxJava 3.x 结合OkHttp访问网络
1. 首先创建Observable
OkHttpClient mOkHttpClient;
private Observable < String > getObservable ( final String ip) {
Observable observable = Observable . create ( new ObservableOnSubscribe < String > ( ) {
@Override
public void subscribe ( @NonNull ObservableEmitter < String > emitter) throws Throwable {
mOkHttpClient = new OkHttpClient ( ) ;
Request request = new Request. Builder ( )
. url ( "http://www.baidu.com" )
. build ( ) ;
Call call = mOkHttpClient. newCall ( request) ;
call. enqueue ( new Callback ( ) {
@Override
public void onFailure ( Call call, IOException e) {
emitter. onError ( new Exception ( "error" ) ) ;
}
@Override
public void onResponse ( Call call, Response response) throws IOException {
String str = response. body ( ) . string ( ) ;
emitter. onNext ( str) ;
emitter. onComplete ( ) ;
}
} ) ;
}
} ) ;
return observable;
}
2. 实现观察者
将发射事件的线程切换到io线程,然后将访问网络的回调设置回主线程,所以可以正常显示Toast。 RxJava也解决了OkHttp的回调不在主线程的问题。 然后我们通过postAsynHttp方法传入ip的值就可以
private String TAG = "Ning" ;
private void postAsynHttp ( String size) {
getObservable ( size) . subscribeOn ( Schedulers . io ( ) )
. observeOn ( AndroidSchedulers . mainThread ( ) )
. subscribe ( new Observer < String > ( ) {
@Override
public void onSubscribe ( @NonNull Disposable d) {
}
@Override
public void onNext ( @NonNull String s) {
Log . d ( TAG, "onNext: " + s) ;
Toast . makeText ( getApplicationContext ( ) , "请求成功" , Toast . LENGTH_SHORT ) . show ( ) ;
}
@Override
public void onError ( @NonNull Throwable e) {
Log . d ( TAG, "onError: " + e. getMessage ( ) ) ;
}
@Override
public void onComplete ( ) {
Log . d ( TAG, "onComplete" ) ;
}
} ) ;
}
RxJava3.X 结合Retrofit访问网络
1. 配置gradle
implementation 'io.reactivex.rxjava3:rxandroid:3.0.2'
implementation 'io.reactivex.rxjava3:rxjava:3.1.5'
implementation 'com.squareup.retrofit2:retrofit:2.7.0'
implementation 'com.squareup.retrofit2:converter-gson:2.7.0'
implementation 'com.squareup.retrofit2:adapter-rxjava3:2.9.0'
2. 返回类的设置
package com. example. rxjava ;
public class User {
private String name;
private int followers;
public String getName ( ) {
return name;
}
public void setName ( String name) {
this . name = name;
}
public void setFollowers ( int followers) {
this . followers = followers;
}
public int getFollowers ( ) {
return followers;
}
}
3. 网络接口
package com. example. rxjava ;
import io. reactivex. rxjava3. core. Single ;
import retrofit2. http. GET;
import retrofit2. http. Path ;
public interface IpServiceForPost {
@GET ( "users/{user}" )
Single < User > getUser ( @Path ( "user" ) String userId) ;
}
4. 创建Retrofit
Retrofit retrofit = new Retrofit. Builder ( )
. baseUrl ( "http://api.github.com/" )
. addConverterFactory ( GsonConverterFactory . create ( ) )
. addCallAdapterFactory ( RxJava3CallAdapterFactory . create ( ) )
. build ( ) ;
5. 动态代理接口对象
IpServiceForPost ipServiceForPost = retrofit. create ( IpServiceForPost . class ) ;
6. 订阅处理结果
ipServiceForPost. getUser ( "octocat" )
. subscribeOn ( Schedulers . io ( ) )
. observeOn ( AndroidSchedulers . mainThread ( ) )
. subscribe ( new SingleObserver < User > ( ) {
@Override
public void onSubscribe ( @NonNull Disposable d) {
}
@Override
public void onSuccess ( @NonNull User user) {
Log . d ( TAG, "onSuccess: " + user. getName ( ) + " " + user. getFollowers ( ) ) ;
}
@Override
public void onError ( @NonNull Throwable e) {
Log . d ( TAG, "onError: " ) ;
}
} ) ;
补充
一个界面可能会有多个请求,对于每个请求来说,我们都会在onSubscribe方法中将Disposable添加到compositeDisposables中。 调用compositeDisposables的clear方法时,会取消所有的请求。
RxJava3.x 实现RxBus
通过RxJava来实现事件总线RxBus。用来替代EventBus和otto
1. 创建RxBus
首先创建RxBus,这里的RxBus只支持基本的功能
package com. example. rxjava ;
import io. reactivex. rxjava3. core. Observable ;
import io. reactivex. rxjava3. subjects. PublishSubject ;
import io. reactivex. rxjava3. subjects. Subject ;
public class RxBus {
private final Subject < Object > subject;
private static volatile RxBus rxBus;
private RxBus ( ) {
subject = PublishSubject . create ( ) . toSerialized ( ) ;
}
public static RxBus getInstance ( ) {
if ( rxBus == null ) {
synchronized ( RxBus . class ) {
if ( rxBus == null ) {
rxBus = new RxBus ( ) ;
}
}
}
return rxBus;
}
public void post ( Object ob) {
subject. onNext ( ob) ;
}
public < T > Observable < T > toObservable ( Class < T > eventType) {
return subject. ofType ( eventType) ;
}
}
ofType的源码 ofType的源码使用了filter操作符和cast操作符。 通过filter来判定是不是指定类型的数据,如果不是指定类型的数据,就不会交给订阅者。 通过cast操作符来将Observable转化成指定类型的Observable
public final < @NonNull U > Observable < U > ofType ( @NonNull Class < U > clazz) {
Objects . requireNonNull ( clazz, "clazz is null" ) ;
return filter ( Functions . isInstanceOf ( clazz) ) . cast ( clazz) ;
}
2. 事件类
package com. example. rxjava ;
public class MessageEvent {
private String message;
public MessageEvent ( String message) {
this . message = message;
}
public String getMessage ( ) {
return message;
}
public void setMessage ( String message) {
this . message = message;
}
}
3. 发送事件
我们在RxBusActivity定义了一个Button,点击这个Button的时候就会发送事件。
package com. example. rxjava ;
import androidx. appcompat. app. AppCompatActivity ;
import android. os. Bundle ;
import android. view. View ;
import android. widget. Button ;
public class RxBusActivity extends AppCompatActivity {
private Button bt_post;
private TextView bt_text;
@Override
protected void onCreate ( Bundle savedInstanceState) {
super . onCreate ( savedInstanceState) ;
setContentView ( R . layout. activity_rx_bus) ;
bt_post = ( Button ) this . findViewById ( R . id. bt_post) ;
bt_text = this . findViewById ( R . id. bt_text) ;
bt_post. setOnClickListener ( new View. OnClickListener ( ) {
@Override
public void onClick ( View v) {
RxBus . getInstance ( ) . post ( new MessageEvent ( "用RxJava实现RxBus" ) ) ;
}
} ) ;
}
}
4. 接收事件
RxBus . getInstance ( )
. toObservable ( MessageEvent . class )
. subscribe ( new Observer < MessageEvent > ( ) {
@Override
public void onSubscribe ( @NonNull Disposable d) {
}
@Override
public void onNext ( @NonNull MessageEvent messageEvent) {
if ( messageEvent != null ) {
bt_text. setText ( messageEvent. getMessage ( ) ) ;
}
}
@Override
public void onError ( @NonNull Throwable e) {
bt_text. setText ( "error!" ) ;
}
@Override
public void onComplete ( ) {
}
} ) ;
5. 取消订阅事件
取消订阅事件,防止内存泄露