问题
Feels like I'm missing something here, but where I used to do:
Schedulers.io().schedule(new Action1<Scheduler.Inner>() {
@Override
public void call(Scheduler.Inner inner) {
doWhatever();
}
});
I don't seem to be able to simply use a scheduler to run a background task anymore, without managing unsubscribes (https://github.com/Netflix/RxJava/wiki/Scheduler and https://github.com/Netflix/RxJava/blob/master/rxjava-core/src/main/java/rx/Scheduler.java).
Is there a pattern for 0.18 that allows me to run doWhatever easily, without keeping track of workers, unsubscribing, etc?
Seems like you could do:
final Worker worker = Schedulers.io().createWorker();
worker.schedule(new Action0() {
@Override
public void call() {
doWhatever();
worker.unsubscribe();
}
});
but this seems like a lot more work, (especially for the android.mainThread scheduler).
What have I missed here?
回答1:
Using Scheduler with Observable
If you are using RxJava, I think you should let Observables deal with the Schedulers. In my code I don't think I ever had to create my own worker and mange it.
Example of using Observable with Scheduler and switching between two thread types.
public void doSomething() {
Observable
.create(new Observable.OnSubscribe<Boolean>() {
@Override
public void call(Subscriber<? super Void> subscriber) {
int sleepTime = (int) (Math.random() * 10000);
System.out.println("Running on: " + Thread.currentThread().getId() + " sleep: " + sleepTime);
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
System.out.println("Error!!! " + Thread.currentThread().getId());
subscriber.onError(e);
return;
}
System.out.println("Done!!! " + Thread.currentThread().getId());
subscriber.onNext(true);
subscriber.onCompleted();
}
})
// this will schedule your work in a background io thread. In this example the "call" method above.
.subscribeOn(Schedulers.io())
// this will schedule your next/complete/error on the androids main thread.
.observeOn(AndroidSchedulers.mainThread())
// kick off the actual work.
.subscribe(new Subscriber<Boolean>() {
@Override
public void onCompleted() {
// runs in main thread.
}
@Override
public void onError(Throwable e) {
// runs in main thread.
}
@Override
public void onNext(Boolean result) {
// runs in main thread.
}
});
}
Using Scheduler Directly
However, I do understand that there might be a case requiring you to use the scheduler directly. So, if you want to use the Scheduler directly. I think the following fits what you are looking for.
Create a scheduler utility with a runAction.
public static void runAction(Action0 action, Scheduler scheduler) {
Scheduler.Worker worker = scheduler.createWorker();
worker.schedule(new Action0() {
@Override
public void call() {
action.call();
worker.unsubscribe();
}
});
}
Then to use it, pass an action to execute and the scheduler to use.
SchedulerUtil.runAction(new Action0() {
@Override
public void call() {
int sleepTime = (int) (Math.random() * 10000);
System.out.println("Running on: " + Thread.currentThread().getId() + " sleep: " + sleepTime);
try {
Thread.sleep(sleepTime);
} catch (InterruptedException ignored) {
}
System.out.println("Done!!! " + Thread.currentThread().getId());
}
}, Schedulers.io());
来源:https://stackoverflow.com/questions/23279995/in-0-18-how-do-background-tasks-get-executed-on-a-scheduler