sockeqwe / mosby

A Model-View-Presenter / Model-View-Intent library for modern Android apps
http://hannesdorfmann.com/mosby/
Apache License 2.0
5.49k stars 841 forks source link

MVI - Sample: NullpointerException after screen orientation change #244

Open sockeqwe opened 7 years ago

sockeqwe commented 7 years ago
05-08 16:19:15.739 2754-2754/com.hannesdorfmann.mosby3.sample.mvi E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                    io.reactivex.exceptions.OnErrorNotImplementedException
                                                                                        at io.reactivex.internal.functions.Functions$14.accept(Functions.java:229)
                                                                                        at io.reactivex.internal.functions.Functions$14.accept(Functions.java:226)
                                                                                        at io.reactivex.internal.observers.LambdaObserver.onError(LambdaObserver.java:72)
                                                                                        at io.reactivex.internal.observers.LambdaObserver.onNext(LambdaObserver.java:62)
                                                                                        at io.reactivex.internal.util.NotificationLite.accept(NotificationLite.java:246)
                                                                                        at io.reactivex.subjects.BehaviorSubject$BehaviorDisposable.test(BehaviorSubject.java:490)
                                                                                        at io.reactivex.subjects.BehaviorSubject$BehaviorDisposable.emitFirst(BehaviorSubject.java:451)
                                                                                        at io.reactivex.subjects.BehaviorSubject.subscribeActual(BehaviorSubject.java:153)
                                                                                        at io.reactivex.Observable.subscribe(Observable.java:10700)
                                                                                        at io.reactivex.Observable.subscribe(Observable.java:10686)
                                                                                        at io.reactivex.Observable.subscribe(Observable.java:10589)
                                                                                        at com.hannesdorfmann.mosby3.mvi.MviBasePresenter.subscribeViewStateConsumerActually(MviBasePresenter.java:374)
                                                                                        at com.hannesdorfmann.mosby3.mvi.MviBasePresenter.attachView(MviBasePresenter.java:259)
                                                                                        at com.hannesdorfmann.mosby3.FragmentMviDelegateImpl.onViewCreated(FragmentMviDelegateImpl.java:141)
                                                                                        at com.hannesdorfmann.mosby3.mvi.MviFragment.onViewCreated(MviFragment.java:101)
                                                                                        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1314)
                                                                                        at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528)
                                                                                        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595)
                                                                                        at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:2900)
                                                                                        at android.support.v4.app.FragmentController.dispatchActivityCreated(FragmentController.java:201)
                                                                                        at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:603)
                                                                                        at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:178)
                                                                                        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1163)
                                                                                        at android.app.Activity.performStart(Activity.java:5018)
                                                                                        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2032)
                                                                                        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
                                                                                        at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3512)
                                                                                        at android.app.ActivityThread.access$700(ActivityThread.java:130)
                                                                                        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1201)
                                                                                        at android.os.Handler.dispatchMessage(Handler.java:99)
                                                                                        at android.os.Looper.loop(Looper.java:137)
                                                                                        at android.app.ActivityThread.main(ActivityThread.java:4745)
                                                                                        at java.lang.reflect.Method.invokeNative(Native Method)
                                                                                        at java.lang.reflect.Method.invoke(Method.java:511)
                                                                                        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
                                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
                                                                                        at dalvik.system.NativeStart.main(Native Method)
                                                                                     Caused by: java.lang.NullPointerException
                                                                                        at com.hannesdorfmann.mosby3.sample.mvi.view.home.HomeAdapter.setLoadingNextPage(HomeAdapter.java:76)
                                                                                        at com.hannesdorfmann.mosby3.sample.mvi.view.home.HomeFragment.renderShowData(HomeFragment.java:148)
                                                                                        at com.hannesdorfmann.mosby3.sample.mvi.view.home.HomeFragment.render(HomeFragment.java:133)
                                                                                        at com.hannesdorfmann.mosby3.sample.mvi.view.home.HomePresenter$$Lambda$14.accept(Unknown Source)
                                                                                        at com.hannesdorfmann.mosby3.mvi.MviBasePresenter$1.accept(MviBasePresenter.java:376)
                                                                                        at io.reactivex.internal.observers.LambdaObserver.onNext(LambdaObserver.java:59)
                                                                                        at io.reactivex.internal.util.NotificationLite.accept(NotificationLite.java:246) 
                                                                                        at io.reactivex.subjects.BehaviorSubject$BehaviorDisposable.test(BehaviorSubject.java:490) 
                                                                                        at io.reactivex.subjects.BehaviorSubject$BehaviorDisposable.emitFirst(BehaviorSubject.java:451) 
                                                                                        at io.reactivex.subjects.BehaviorSubject.subscribeActual(BehaviorSubject.java:153) 
                                                                                        at io.reactivex.Observable.subscribe(Observable.java:10700) 
                                                                                        at io.reactivex.Observable.subscribe(Observable.java:10686) 
                                                                                        at io.reactivex.Observable.subscribe(Observable.java:10589) 
                                                                                        at com.hannesdorfmann.mosby3.mvi.MviBasePresenter.subscribeViewStateConsumerActually(MviBasePresenter.java:374) 
                                                                                        at com.hannesdorfmann.mosby3.mvi.MviBasePresenter.attachView(MviBasePresenter.java:259) 
                                                                                        at com.hannesdorfmann.mosby3.FragmentMviDelegateImpl.onViewCreated(FragmentMviDelegateImpl.java:141) 
                                                                                        at com.hannesdorfmann.mosby3.mvi.MviFragment.onViewCreated(MviFragment.java:101) 
                                                                                        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1314) 
                                                                                        at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528) 
                                                                                        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595) 
                                                                                        at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:2900) 
                                                                                        at android.support.v4.app.FragmentController.dispatchActivityCreated(FragmentController.java:201) 
                                                                                        at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:603) 
                                                                                        at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:178) 
                                                                                        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1163) 
                                                                                        at android.app.Activity.performStart(Activity.java:5018) 
                                                                                        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2032) 
                                                                                        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084) 
                                                                                        at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3512) 
                                                                                        at android.app.ActivityThread.access$700(ActivityThread.java:130) 
                                                                                        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1201) 
                                                                                        at android.os.Handler.dispatchMessage(Handler.java:99) 
                                                                                        at android.os.Looper.loop(Looper.java:137) 
                                                                                        at android.app.ActivityThread.main(ActivityThread.java:4745) 
                                                                                        at java.lang.reflect.Method.invokeNative(Native Method) 
                                                                                        at java.lang.reflect.Method.invoke(Method.java:511) 
                                                                                        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 
                                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
                                                                                        at dalvik.system.NativeStart.main(Native Method)

While loading more items (pagination on home screen) and switch from portrait to landscape. 

Logs:

05-08 16:19:13.859 2754-2754/com.hannesdorfmann.mosby3.sample.mvi D/HomePresenter: intent: load next page
05-08 16:19:13.879 2754-2754/com.hannesdorfmann.mosby3.sample.mvi D/HomeFragment: render HomeViewState{
                                                                                  loadingFirstPage=false,
                                                                                   firstPageError=null,
                                                                                   data=[SectionHeader{name='Home Décor'}, Product{id=1, name='Amethyst Candle Holder', category='Home Décor'}, Product{id=2, name='Christmas Stocking', category='Home Décor'}, Product{id=3, name='home sweet home sign', category='Home Décor'}, AdditionalItemsLoadable{moreItemsAvailableCount=3, groupName='Home Décor', loading=false, loadingError=null}, SectionHeader{name='Cell Phone'}, Product{id=12, name='Game of Thrones Wood Engraved', category='Cell Phone'}, Product{id=13, name='Acoustic Reclaimed Pallet', category='Cell Phone'}, Product{id=14, name='Altoids Amp and Speaker', category='Cell Phone'}, AdditionalItemsLoadable{moreItemsAvailableCount=2, groupName='Cell Phone', loading=false, loadingError=null}, SectionHeader{name='Hats & Caps'}, Product{id=7, name='Women's surgical scrub hats', category='Hats & Caps'}, Product{id=8, name='Trucker Hat', category='Hats & Caps'}, Product{id=9, name='Nasa Meatball', category='Hats & Caps'}, Product{id=10, name='Bunny Hat', category='Hats & Caps'}, Product{id=11, name='Bunny Hat', category='Hats & Caps'}, SectionHeader{name='Camera'}, Product{id=17, name='Personalizable Camera Strap', category='Camera'}, Product{id=18, name='Vintage Polaroid', category='Camera'}, Product{id=19, name='Instax mini Album', category='Camera'}, AdditionalItemsLoadable{moreItemsAvailableCount=3, groupName='Camera', loading=false, loadingError=null}, SectionHeader{name='Music'}, Product{id=23, name='Personalized Drumsticks', category='Music'}, Product{id=24, name='Wooden Guitar Pick', category='Music'}, Product{id=25, name='Electric Guitar Kit', category='Music'}, AdditionalItemsLoadable{moreItemsAvailableCount=4, groupName='Music', loading=false, loadingError=null}, SectionHeader{name='Jewelry'}, Product{id=30, name='Angel wing charm', category='Jewelry'}, Product{id=31, name='Steel Bangle Bracelet', category='Jewelry'}, Product{id=32, name='Crystals flat back stones', category='Jewelry'}, AdditionalItemsLoadable{moreItemsAvailableCount=2, groupName='Jewelry', loading=false, loadingError=null}],
                                                                                   loadingNextPage=true,
                                                                                   nextPageError=null,
                                                                                   loadingPullToRefresh=false,
                                                                                   pullToRefreshError=null
                                                                                  }
05-08 16:19:15.709 2754-2754/com.hannesdorfmann.mosby3.sample.mvi D/MainActivity: Activity onSaveInstanceState()
05-08 16:19:15.709 2754-2754/com.hannesdorfmann.mosby3.sample.mvi D/MainActivity: ------- Destroyed -------
05-08 16:19:15.739 2754-2754/com.hannesdorfmann.mosby3.sample.mvi D/ShoppingCartOverviewFra: Render [] 
05-08 16:19:15.739 2754-2754/com.hannesdorfmann.mosby3.sample.mvi D/HomeFragment: render HomeViewState{
                                                                                  loadingFirstPage=false,
                                                                                   firstPageError=null,
                                                                                   data=[SectionHeader{name='Home Décor'}, Product{id=1, name='Amethyst Candle Holder', category='Home Décor'}, Product{id=2, name='Christmas Stocking', category='Home Décor'}, Product{id=3, name='home sweet home sign', category='Home Décor'}, AdditionalItemsLoadable{moreItemsAvailableCount=3, groupName='Home Décor', loading=false, loadingError=null}, SectionHeader{name='Cell Phone'}, Product{id=12, name='Game of Thrones Wood Engraved', category='Cell Phone'}, Product{id=13, name='Acoustic Reclaimed Pallet', category='Cell Phone'}, Product{id=14, name='Altoids Amp and Speaker', category='Cell Phone'}, AdditionalItemsLoadable{moreItemsAvailableCount=2, groupName='Cell Phone', loading=false, loadingError=null}, SectionHeader{name='Hats & Caps'}, Product{id=7, name='Women's surgical scrub hats', category='Hats & Caps'}, Product{id=8, name='Trucker Hat', category='Hats & Caps'}, Product{id=9, name='Nasa Meatball', category='Hats & Caps'}, Product{id=10, name='Bunny Hat', category='Hats & Caps'}, Product{id=11, name='Bunny Hat', category='Hats & Caps'}, SectionHeader{name='Camera'}, Product{id=17, name='Personalizable Camera Strap', category='Camera'}, Product{id=18, name='Vintage Polaroid', category='Camera'}, Product{id=19, name='Instax mini Album', category='Camera'}, AdditionalItemsLoadable{moreItemsAvailableCount=3, groupName='Camera', loading=false, loadingError=null}, SectionHeader{name='Music'}, Product{id=23, name='Personalized Drumsticks', category='Music'}, Product{id=24, name='Wooden Guitar Pick', category='Music'}, Product{id=25, name='Electric Guitar Kit', category='Music'}, AdditionalItemsLoadable{moreItemsAvailableCount=4, groupName='Music', loading=false, loadingError=null}, SectionHeader{name='Jewelry'}, Product{id=30, name='Angel wing charm', category='Jewelry'}, Product{id=31, name='Steel Bangle Bracelet', category='Jewelry'}, Product{id=32, name='Crystals flat back stones', category='Jewelry'}, AdditionalItemsLoadable{moreItemsAvailableCount=2, groupName='Jewelry', loading=false, loadingError=null}],
                                                                                   loadingNextPage=true,
                                                                                   nextPageError=null,
                                                                                   loadingPullToRefresh=false,
                                                                                   pullToRefreshError=null
                                                                                  }
sockeqwe commented 7 years ago
  private void renderShowData(HomeViewState state) {
    TransitionManager.beginDelayedTransition((ViewGroup) getView());
    loadingView.setVisibility(View.GONE);
    errorView.setVisibility(View.GONE);
    swipeRefreshLayout.setVisibility(View.VISIBLE);
    boolean changed = adapter.setLoadingNextPage(state.isLoadingNextPage()); // TODO: Internally calls items.size() which is null on orientation change!

    if (changed && state.isLoadingNextPage()) {
      // scroll to the end of the list so that the user sees the load more progress bar
      recyclerView.smoothScrollToPosition(adapter.getItemCount());
    }
    adapter.setItems(state.getData()); 
//  TODO: this must be done before setLoading() otherwise error will occure. see https://github.com/sockeqwe/mosby/issues/244