尝试在Observer中使用BroadcastReceiver时遇到问题。
BroadcastReceiver发出的项目正在主线程上发出,而不是在subscribeOn
上传递的线程上发出。
例如,给定以下代码,该代码与该link中的RxBroadcastReceiver类几乎相同:
public static final class RxBroadcastReceiver implements ObservableOnSubscribe<String> {
public static Observable<String> create(Context context, IntentFilter intentFilter) {
return Observable.create(new RxBroadcastReceiver(context, intentFilter));
}
private final Context context;
private final IntentFilter intentFilter;
private RxBroadcastReceiver(Context context, IntentFilter intentFilter) {
this.context = context;
this.intentFilter = intentFilter;
}
@Override
public void subscribe(final ObservableEmitter<String> emitter) throws Exception {
final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String threadName = Thread.currentThread().getName();
emitter.onNext(threadName);
}
};
context.registerReceiver(broadcastReceiver, intentFilter);
emitter.setDisposable(Disposables.fromRunnable(new Runnable() {
@Override
public void run() {
context.unregisterReceiver(broadcastReceiver);
}
}));
}
}
运行以下代码时:
RxBroadcastReceiver.create(context, filter)
.subscribeOn(Schedulers.io())
.subscribe(new Consumer<String>() {
@Override
public void accept(final String executedThread) throws Exception {
String acceptedThread = Thread.currentThread().getName();
System.out.println("executedThread: " + executedThread);
System.out.println("acceptedThread: " + acceptedThread);
}
});
输出显示执行的线程是主线程,而不是Schedulers.io中的线程:
executedThread: main
acceptedThread: main
如果使用以下代码,则:
public static final class RxJavaBroadcaster implements ObservableOnSubscribe<String> {
public static Observable<String> create() {
return Observable.create(new RxJavaBroadcaster());
}
@Override
public void subscribe(final ObservableEmitter<String> emitter) throws Exception {
String threadName = Thread.currentThread().getName();
emitter.onNext(threadName);
}
}
运行以下代码时:
RxJavaBroadcaster.create()
.subscribeOn(Schedulers.io())
.subscribe(new Consumer<String>() {
@Override
public void accept(final String executedThread) throws Exception {
String acceptedThread = Thread.currentThread().getName();
System.out.println("executedThread: " + executedThread);
System.out.println("acceptedThread: " + acceptedThread);
}
});
按预期,输出不在主线程中
executedThread: RxCachedThreadScheduler-1
acceptedThread: RxCachedThreadScheduler-1
之所以我认为这些项是在主线程上发出的,是因为BroadcastReceiver.onReceive总是在其进程的主线程中调用。
鉴于上述正确的解决方案(我可以想到的另一种解决方案)将是,通过此method注册通过自定义处理程序的BroadcastReceiver。
然后我的问题是:
Scheduler
的正确subscribeOn
?有人看到其他选择吗?
我的问题与本question中描述的问题完全相同,实际上我已经在使用那里提出的解决方案(称为第二个subscribeOn),但是我希望使用其他方法。
答案 0 :(得分:0)
如果我理解正确,则希望在特定的Scheduler上发出并在主线程上接受。我认为您的解决方案将使用RxAndroid https://github.com/ReactiveX/RxAndroid
将代码从预期结果更改为使用observeOn(AndroidSchedulers.mainThread())
RxJavaBroadcaster.create()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<String>() {
@Override
public void accept(final String executedThread) throws Exception {
String acceptedThread = Thread.currentThread().getName();
System.out.println("executedThread: " + executedThread);
System.out.println("acceptedThread: " + acceptedThread);
}
});