在Android上,總是通過設計在主Thread
上調用一些回調。以下ServiceConnection
:RxJava:如何從上游保留線程
private Completable dismissService() {
return Completable.fromEmitter(new Action1<CompletableEmitter>() {
@Override
public void call(final CompletableEmitter completableEmitter) {
final ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// here always main Thread...
unbindService(this);
completableEmitter.onCompleted();
}
@Override
public void onServiceDisconnected(ComponentName name) {
// no-op
}
};
completableEmitter.setCancellation(new AsyncEmitter.Cancellable() {
@Override
public void cancel() throws Exception {
unbindService(conn);
}
});
bindService(new Intent(MainActivity.this, MyService.class), conn, BIND_AUTO_CREATE);
}
});
}
不過,我想通過Completable返回dismissService()
發射其結果就什麼Thread
它被調用的。我試圖用一個newSingleThreadExecutor()
以下(哈克?)解決方案:
private Completable dismissServiceRetainingThread() {
return Single.fromCallable(new Callable<Thread>() {
@Override
public Thread call() throws Exception {
return Thread.currentThread();
}
}).flatMapCompletable(new Func1<Thread, Completable>() {
@Override
public Completable call(final Thread thread) {
return Completable.fromEmitter(new Action1<CompletableEmitter>() {
@Override
public void call(final CompletableEmitter completableEmitter) {
final ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// here always main Thread...
unbindService(this);
completableEmitter.onCompleted();
}
@Override
public void onServiceDisconnected(ComponentName name) {
// no-op
}
};
completableEmitter.setCancellation(new AsyncEmitter.Cancellable() {
@Override
public void cancel() throws Exception {
unbindService(conn);
}
});
bindService(new Intent(MainActivity.this, MyService.class), conn, BIND_AUTO_CREATE);
}
}).observeOn(Schedulers.from(
Executors.newSingleThreadExecutor(
new ThreadFactory() {
@Override
public Thread newThread(@NonNull Runnable runnable) {
return thread;
}
}
)));
}
});
}
但是,有以下IllegalThreadStateException
崩潰:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.jenzz.rxjavathreadingtest, PID: 5307
java.lang.IllegalThreadStateException
at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:930)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1348)
at java.util.concurrent.Executors$DelegatedExecutorService.execute(Executors.java:591)
at rx.internal.schedulers.ExecutorScheduler$ExecutorSchedulerWorker.schedule(ExecutorScheduler.java:79)
at rx.Completable$28$1.onCompleted(Completable.java:1805)
at rx.internal.operators.CompletableFromEmitter$FromEmitter.onCompleted(CompletableFromEmitter.java:73)
at com.jenzz.rxjavathreadingtest.MainActivity$5$2$1.onServiceConnected(MainActivity.java:117)
任何想法如何,我可以跳回原始Thread
是以前用於上游,例如使用subscribeOn(Schedulers.io())
?
謝謝。這聽起來很合理。我決定只是默認通知主線程並在JavaDoc中記錄這種行爲。調用者總是可以使用'.observeOn(Schedulers.io())',就像你建議直接切換到背景'Thread'一樣。 – jenzz