rxjava mSubscription.unsubscribe onCreate 的工作方式与 Activity 中的 onDestroy 相同吗?
它是否会以相同的方式工作并通过将其放在 onCreate 中作为
subscription.subscribeOn().observeOn().subscribe().unsubscribe
取消订阅以防止内存泄漏 因为 Activity 不断被调用来填充下一个 fragment 并弹出回堆栈。如果 mSubscription.unsubscribe 在 Activity 的 onDestroy 中完成,则会抛出 RunTimeException: Unable to destroy Activity due to NullPointerException我在这里错过了一些生命周期问题吗?
谢谢!
private ViewPager viewPager;
private TabLayout tabLayout;
private int mPosition;
private String id;
private Subscription mSubscription;
private Context mContext;
private RealmResults<Experience> realmResults;
private String animateExtraColumnName, tag;
private Boolean automaticUpdate, animateResults;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_employment);
User currentUser = AppDelegate.getCurrentUser();
assert currentUser != null;
mEmployee = getRealm().where(Employee.class).equalTo("user.id", currentUser.getId()).findFirst();
//Server returns Experience's ID
if (employeeExperience == null) {
AccessToken accessToken = currentUser.getAccessTokenAsTokenType(AppDelegate.getContext(), "Bearer");
employeeExperienceAPIOAuth2Call apiCall = new employeeExperienceAPIOAuth2Call(AppDelegate.getContext(), accessToken);
Observable<ResponseEmployeeExperience> postEmployeeExperienceObservable = apiCall.postEmployeeExperiencesRX();
mSubscription = postEmployeeExperienceObservable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe((data) -> {
Log.d(TAG, "onCreate: Subscribe ");
employeeExperience = data.getEmployeeExperience();
Log.d(TAG, "onCreate: employeeExperience.getId()");
getRealm().beginTransaction();
getRealm().copyToRealmOrUpdate(employeeExperience);
// This adds the new employeeExperience object into the EmployeeExperiences RealmList
employee.employeeExperiences.add(employeeExperience);
getRealm().commitTransaction();
getRealm().close();
//unsubscribe here because the activity doesnt close itself to begin with?
mSubscription.unsubscribe();
Log.d(TAG, "onCreate: Unsubscribe: ");
// prepare data needed by our fragment
FragmentAddOrUpdateEmploymentHistory addEmploymentHistoryFragment = new FragmentAddOrUpdateEmploymentHistory();
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().replace(R.id.edit_frame_layout, addEmploymentHistoryFragment, "EDIT_FRAGMENT").commit();
}, (error) -> {
// TODO do whatever error handling we need to do here
Log.d(TAG, "onCreate: postEmployeeExp error");
error.printStackTrace();
});
}
} else if (employee.getEmployeeExperiences() != null) {
employeeExperience = getRealm().where(employeeExperience.class).equalTo("id", id).findFirst();
FragmentAddOrUpdateEmploymentHistory addEmploymentHistoryFragment = new FragmentAddOrUpdateEmploymentHistory();
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().replace(R.id.edit_frame_layout, addEmploymentHistoryFragment, "EDIT_FRAGMENT").commit();
}
ImageButton checkButton = (ImageButton) findViewById(R.id.edit_toolbar_check);
checkButton.setOnClickListener(this);
ImageButton crossButton = (ImageButton) findViewById(R.id.edit_toolbar_cross);
crossButton.setOnClickListener(this);
}
@Override
protected void onStart() {
super.onStart();
}
@Override
public void onClick(View view) {
Fragment editFragments = getSupportFragmentManager().findFragmentByTag("EDIT_FRAGMENT");
switch (view.getId()) {
case R.id.edit_toolbar_check:
if (editFragments instanceof FragmentEditDate) {
Log.d(TAG, "onClick: editdate ");
getSupportFragmentManager().popBackStack();
} else if (editFragments instanceof FragmentSalary){
Log.d(TAG, "onClick: salary ");
getSupportFragmentManager().popBackStack();
} else if (editFragments instanceof FragmentAddOrUpdateEmploymentHistory) {
Log.d(TAG, "onClick: employmenthistory ");
finish();
} else if (editFragments instanceof FragmentSingleChoice) {
Log.d(TAG, "singlechoice " );
getSupportFragmentManager().popBackStack();
}
else if (editFragments instanceof FragmentMultipleChoice) {
Log.d(TAG, "multiplechoice " );
getSupportFragmentManager().popBackStack();
}
break;
case R.id.edit_toolbar_cross:
if (editFragments instanceof FragmentAddOrUpdateEmploymentHistory) {
getRealm().beginTransaction();
employeeExperience.DELETE();
getRealm().commitTransaction();
getRealm().close();
}
finish();
} else {
finish();
}
} else {
getSupportFragmentManager().popBackStack(); }
break;
}
}
最佳答案
简而言之 - 一旦您订阅 Observable
您已准备好接收来自它的通知并对其使用react( onNext
、 onError
、 onComplete
)。同样在大多数情况下(对于冷 Observables),这实际上是 Observable
的触发点。开始发射元素。
Unsubscribing
来自 Observable 意味着您不再有兴趣接收任何进一步的通知。您需要unsubscribe
当你不再想接收任何东西时,类似于如何释放 Activity 的 onDestroy()
中的任何资源方法。当然,与 Activity 生命周期的并行只是为了比较 - 订阅/取消订阅过程是完全独立的事情。
您可以详细阅读 subscribing
和unsubscribing
意味着[此处][1] [1]:http://reactivex.io/documentation/contract.html
也就是说,对您的代码有一些具体建议:
您当前在 Android 主线程上执行了太多操作。我建议将所有与实际相关的内容作为 RX 链的一部分移动,而不是在 onNext()
中。处理程序位于 subscribe(...)
。这样它将在 io
上执行线。像这样的东西:
...
mSubscription = postEmployeeExperienceObservable
.subscribeOn(Schedulers.io())
.doOnNext(data -> saveDataToRealm(data))
.observeOn(AndroidSchedulers.mainThread())
.subscribe((data) -> {
// prepare data needed by our fragment
FragmentAddOrUpdateEmploymentHistory addEmploymentHistoryFragment = new FragmentAddOrUpdateEmploymentHistory();
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().replace(R.id.edit_frame_layout, addEmploymentHistoryFragment, "EDIT_FRAGMENT").commit();
}, (error) -> {
// TODO do whatever error handling we need to do here
Log.d(TAG, "onCreate: postEmployeeExp error");
error.printStackTrace();
});
}
private Data saveDataToRealm(Data data) {
employeeExperience = data.getEmployeeExperience();
Log.d(TAG, "onCreate: employeeExperience.getId()");
getRealm().beginTransaction();
getRealm().copyToRealmOrUpdate(employeeExperience);
// This adds the new employeeExperience object into the EmployeeExperiences RealmList
employee.employeeExperiences.add(employeeExperience);
getRealm().commitTransaction();
getRealm().close();
}
就取消订阅而言 - 如果您确实想要unsubscribe
来自onNext()
内事件,更好的策略是通过 Subscriber<Data>
订阅然后使用它的 unsubscribe()
方法。换句话说 - 你不会调用 mSubscription.unsubscribe()
而是 this.unsubscribe()
.
mSubscription = postEmployeeExperienceObservable
.subscribeOn(Schedulers.io())
.doOnNext(data -> saveDataToRealm(data))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Data>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Data data) {
...
this.unsubscribe();
}
});
综上所述,我认为您真的不需要 unsubscribe
来自onNext()
方法在你的情况下,相反你可以在 onDestroy()
中这样做,当然检查之前是否创建了订阅:
@Override
protected void onDestroy() {
super.onDestroy();
if (mSubscription != null) {
mSubscription.unsubscribe();
}
}
关于java - mSubscription.unsubscribe onCreate 与 Activity 中的 onDestroy 的工作方式相同吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41709934/