mSubscription.unsubscribe onCreate是否与Activity中的onDestroy相同?

时间:2017-01-18 01:24:30

标签: java android rx-java unsubscribe

  1. rxjava mSubscription.unsubscribe onCreate的工作方式与活动中的onDestroy相同吗?

  2. 它是否会以相同的方式运行并取消订阅以将内存泄漏作为subscription.subscribeOn().observeOn().subscribe().unsubscribe放入onCreate中以防止内存泄漏 因为不断调用Activity来填充下一个片段并弹回堆栈。如果mSubscription.unsubscribe在Activity中的onDestroy中完成,则会产生一个RunTimeException:由于NullPointerException而无法销毁活动

  3. 我在这里错过了一些生命周期问题吗?

  4. 谢谢!

        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;
    
            }
        }
    

1 个答案:

答案 0 :(得分:0)

简而言之 - 一旦您订阅Observable,您就可以接收并回复来自onNextonErroronComplete的通知。同样在大多数情况下(对于冷Observables),这实际上是Observable开始发射项目的触发点。

来自Observable的

Unsubscribing表示您不再有兴趣接收任何进一步的通知。当您不再希望收到任何内容时,您需要unsubscribe,类似于您可以在Activity的onDestroy()方法中释放任何资源。当然,与活动的生命周期并行只是为了比较 - 订阅/取消订阅过程是完全独立的。

您可以详细了解subscribingunsubscribing的含义[这里] [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() 1}}方法。换句话说 - 您不会拨打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();
    }
}