Android-RxJava vs AsyncTask防止getActivity()内存泄漏

Android-RxJava vs AsyncTask防止getActivity()内存泄漏,android,memory-leaks,android-asynctask,rx-java,Android,Memory Leaks,Android Asynctask,Rx Java,在Android中使用RxJava(或RxAndroid等)而不是AsyncTask如何帮助防止上下文泄漏?在AsyncTask中,如果您执行它并且用户离开应用程序,则活动上下文可能为空,应用程序可能崩溃。我听说RxJava在执行线程时可以帮助防止这种类型的崩溃。我还听说它可以比AsyncTask的doInBackground方法(它处理错误很糟糕)做得更好。大多数情况下,如果出现任何故障,我只会在doInBackground中返回null(例如),但我已经了解到RxJava可以返回准确的错误,

在Android中使用RxJava(或RxAndroid等)而不是AsyncTask如何帮助防止上下文泄漏?在AsyncTask中,如果您执行它并且用户离开应用程序,则活动上下文可能为空,应用程序可能崩溃。我听说RxJava在执行线程时可以帮助防止这种类型的崩溃。我还听说它可以比AsyncTask的doInBackground方法(它处理错误很糟糕)做得更好。大多数情况下,如果出现任何故障,我只会在doInBackground中返回null(例如),但我已经了解到RxJava可以返回准确的错误,而不会泄漏。有人能举个例子吗

下面是AsyncTask崩溃的一个小演示,如果用户在尝试向UI报告结果时离开应用程序:

     @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();
    }}

我认为RxJava的好处在于,如果你有一堆任务,你可以将它们按顺序排列,这样你就知道一个任务何时完成,下一个任务何时开始。在异步任务中,如果有多个任务正在运行,则无法保证先完成哪个任务,如果关心顺序,则必须执行大量错误检查。因此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 
        }
});
public observeable get\u A\u NetworkCall(){
//进行网络呼叫…但完成后返回一个可观察的
}
订阅订阅=获取网络调用()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.订阅(新观察员){
@凌驾
未完成的公共无效(){
//更新用户界面
}
@凌驾
公开无效{
//在UI上显示错误
}
@凌驾
public void onNext(JsonObject响应){
//处理jsonResponse的结果
}
});

或者类似的东西-这是伪代码。关键是,您可以更清晰地报告错误,并在一行中切换线程。这里我们报告的是androids主线程,但在一个新线程上进行工作。在我们使用activities onDestroy方法完成之后,我们可以简单地取消订阅observable,它会杀死它,并防止我们在AsyncTask中遇到的任何内存泄漏。这对我来说应该是任何异步任务的替代品

我使用两种东西的组合。首先,
RxAndroid
非常有用:

您可以在其上使用
AppObservable.bindActivity
来绑定可观察对象,以便在主线程上观察其输出,并且如果计划销毁该活动,则不会转发消息。不过,您仍然需要管理暂停/恢复生命周期。为此,我使用这样的复合订阅(接下来是伪Java):

显然,如果您想对数据做些什么,您希望在
subscribe
中做更多的事情,但重要的是收集返回的
Subscription
实例,并将它们添加到
CompositeSubscription
中。当它清除它们时,它也会取消它们的订阅


当活动处于不工作状态时,使用这两个“奇怪的技巧”应该可以防止事情回到活动中。

有趣的是,你问了这个问题,我刚刚读完这篇文章:添加。。。您需要记住在onPause()或onDestroy上取消订阅,如下SubscriberObj.unSubscribe();
    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 
        }
});
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();
  }

}