2017-01-18 4 views
1
  1. Будет ли rxjava mSubscription.unsubscribe onСоздать работу так же, как onDestroy в действии?Выполняет ли mSubscription.unsubscribe onCreate работу так же, как onDestroy в Activity?

  2. Будет ли она работать так же, как и отказаться, чтобы предотвратить утечку памяти, поместив его в OnCreate, как subscription.subscribeOn().observeOn().subscribe().unsubscribe , потому что активность постоянно вызывается для заполнения следующего фрагмента и выскочить обратно в стек. если mSubscription.unsubscribe выполняется в onDestroy в Activity, это дает исключение RunTimeException: невозможно уничтожить активность из-за NullPointerException

  3. Я пропустил какой-то вопрос о жизненном цикле здесь?

Спасибо!

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; 

     } 
    } 
+0

Почему вы не вызываете отписаться в onComplete()? –

+0

где это должно быть onComplete() be? –

+0

внутри вашего метода подписки –

ответ

0

Короче - как только вы подписаться на Observable вы готовы получать и реагировать на уведомления от него (onNext, onError, onComplete). Также в большинстве случаев (для холодных наблюдений) это фактически является точкой запуска для Observable для запуска испускающих элементов.

Unsubscribing from Observable означает, что вы больше не заинтересованы в получении каких-либо дополнительных уведомлений. Вам нужно unsubscribe, когда вы больше не хотите получать что-либо, подобно тому, как вы можете освободить любые ресурсы в методе onDestroy(). Разумеется, параллель с жизненным циклом активности просто для сравнения - процесс подписки/отмены подписки - это совершенно отдельная вещь.

Вы можете прочитать подробно о том, что 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(); 
    } 
} 
+0

спасибо! я упустил нулевой контролер для моей подписки в onDestroy –