在Android中如何使用RxJava(或RxAndroid等)代替AsyncTask有助于防止上下文泄漏?在AsyncTask中,如果您执行它并且用户离开应用程序,那么活动上下文可以为null并且应用程序可能会崩溃。我听说RxJava可以在进行线程时帮助防止这种类型的崩溃。我还听说它可以做更好的错误处理,然后是AsyncTask的doInBackground方法(它会严重处理错误)。大多数时候我只是在doInBackground中返回null(例如),如果有任何失败,但我已经读过RxJava可以返回确切的错误而不是泄漏。谁能举个例子?
如果用户在尝试向UI报告结果时离开应用,则会在AsyncTask中发生崩溃的小演示:
@SuppressWarnings("unused")
private class GetTask extends AsyncTask<Void, Void, Void> {
@Override
protected void onPostExecute(String result) {
pd = new ProgressDialog(getActivity().getApplicationContext());//can crash right here
pd.setTitle("Grabbing Track!");
pd.setMessage("Please wait...");
pd.setCancelable(false);
pd.setIndeterminate(true);
pd.show();
}}
这是一个doInBackground方法调用,它不会发出有用的错误:
@Override
protected String doInBackground(String... params) {
String myIntAsString = 1/0 + ""; //this should give an error (how do we report it to the caller??
//or if we are parsing json and it fails, how do we report it to the caller cleanly. Can RxJava help?
}
答案 0 :(得分:9)
我认为关于RxJava的好处是,如果你有一堆任务,你可以把它们放在一个顺序中,这样你就知道什么时候完成而下一个即将开始。在AsyncTask中如果你有多个运行,你不能保证哪个任务将首先完成,然后你必须做很多错误检查,如果你关心订单。所以RxJava允许你对调用进行排序。
关于内存泄漏,我们可以将AsyncTask作为活动的内部类。现在,因为当活动被破坏时它与活动相关联,上下文仍然悬而未开,并且不会被垃圾收集,这就是内存泄漏部分。
这是RxJava可以提供帮助的地方。如果发生任何错误,那么我们可以调用订阅者onError方法。订阅者可以这样:
public Observable<JsonObject> get_A_NetworkCall() {
// Do your network call...but return an observable when done
}
Subscription subscription = get_A_NetworkCall()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<jsonResponse>() {
@Override
public void onCompleted() {
// Update UI
}
@Override
public void onError() {
// show error on UI
}
@Override
public void onNext(JsonObject response) {
// Handle result of jsonResponse
}
});
或类似的东西 - 这是伪造的。关键是你可以更干净地报告错误并在一行中切换线程。在这里,我们报告了机器人主线程,但在新线程上进行了工作。在我们的活动onDestroy方法完成之后,我们可以简单地取消订阅observable并将其杀死并防止我们遇到的任何内存泄漏与AsyncTask。这对我来说应该是任何asyncTasks的替代品。
答案 1 :(得分:5)
我使用了两件事的组合。首先,RxAndroid
非常有用:
https://github.com/ReactiveX/RxAndroid
您可以在其上使用AppObservable.bindActivity
绑定一个observable,以便在主线程上观察其输出,如果计划销毁该活动,则不会转发消息。您仍然需要管理暂停/恢复生命周期。为此,我使用这样的复合订阅(pseudojava即将发布):
public class MyActivity extends Activity {
private final CompositeSubscription subscriptions = new CompositeSubscription();
@Override
public void onResume() {
super.onResume();
subscriptions.add(AppObservable.bindActivity(this, myObservable)
.subscribe());
subscriptions.add(AppObservable.bindActivity(this, myOtherObservable)
.subscribe());
}
@Override
public void onPause() {
subscriptions.clear();
super.onPause();
}
}
显然,如果您想对数据执行某些操作,您希望在subscribe
中执行更多操作,但重要的是收集返回的Subscription
实例并将其添加到{ {1}}。当它清除它们时,它也会取消订阅它们。
使用这两个奇怪的技巧&#39;当事件处于不工作状态时,应该让事情不再回到活动状态。