mosby
mosby copied to clipboard
Mosby 3.1.0 NPEs in Activity#onDestroy()
After upgrading app to Mosby 3.1.0 crash analytics have started displaying crashes like:
java.lang.RuntimeException: Unable to destroy activity {p/p.a}: java.lang.NullPointerException: Attempt to invoke interface method 'void com.hannesdorfmann.mosby3.mvp.MvpPresenter.detachView()' on a null object reference
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4299)
at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:4317)
at android.app.ActivityThread.-wrap6(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1569)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:241)
at android.app.ActivityThread.main(ActivityThread.java:6274)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'void com.hannesdorfmann.mosby3.mvp.MvpPresenter.detachView()' on a null object reference
at com.hannesdorfmann.mosby3.mvp.delegate.ViewGroupMvpDelegateImpl.detachPresenterIfNotDoneYet(ViewGroupMvpDelegateImpl.java:301)
at com.hannesdorfmann.mosby3.mvp.delegate.ViewGroupMvpDelegateImpl.onActivityDestroyed(ViewGroupMvpDelegateImpl.java:255)
at android.app.Application.dispatchActivityDestroyed(Application.java:253)
at android.app.Activity.onDestroy(Activity.java:1851)
at android.support.v4.app.FragmentActivity.onDestroy(FragmentActivity.java:358)
at android.support.v7.app.AppCompatActivity.onDestroy(AppCompatActivity.java:209)
at p.a.onDestroy(a.java:)
at android.app.Activity.performDestroy(Activity.java:6922)
at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1154)
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4286)
... 9 more
Do not have the specific repro steps available yet, but reading the source in ViewGroupMvpDelegateImpl
:
private void destroyPresenterIfnotDoneYet() {
if (!presenterDestroeyed) {
P presenter = delegateCallback.getPresenter();
presenter.destroy();
To me this looks like the code is assuming too much about the fragment/activity lifecycle - the fragment lifecycle has not reached MvpFragment#onCreate()
where the presenter is created but the the activity gets destroyed for some other reason, and presenterDestroeyed
defaults to false
.
For what it's worth, there's also a typo in presenterDestroeyed
.
Hey thanks for reporting. How do you use your ViewGroup, do you remove that one manually? How can I reproduce this bug? Did it work in 3.0.4?
So far only seen this is crash reports sent via automated tooling, no repro cases reported. I'll try to cook up one in near future.
Didn't receive such crash reports before Mosby 3.1.0 update and that lead me to believe it's related as there were lifecycle-related changes (such as MvpFragment
createPresenter()
getting invoked in onCreate()
rather than onViewCreated()
fragment lifecycle phase).
The app itself is large with tens of developers contributing. In most places the UI is based on MvpFragment
with MvpNullObjectBasePresenter
. But now that you mention it, I cannot exclude that there is somewhere e.g. MvpView
-based approaches (with potential lifecycle-related bugs). Have to recheck when back at work and not busy with something else.
Also noting that I posted the wrong code snippet. It does have a typo, but the crash is in the next private method. Sorry about that.
Ok, finally got some time to debug this deeper. No original repro steps known but here's something that produces similar stacktraces:
- The app has a bottom navigation bar that is-a
MvpFrameLayout
(and henceViewGroupMvpDelegateImpl
seen in stacktrace) - Each post-login activity in the app checks for a valid session in
onResume()
and if the session is stale, callsfinish()
to go back to login activity -
ViewGroupMvpDelegateImpl
starts listening for activity lifecycle changes once instantiated but only inits the presenter inonAttachedToWindow()
which runs after activityonResume()
Here's a sample activity that demonstrates the above:
public class MosbyBug290Activity extends AppCompatActivity {
static class BottomNaviPresenter extends MvpBasePresenter<MvpView> {
}
static class BottomNavi extends MvpFrameLayout<MvpView, BottomNaviPresenter> {
public BottomNavi(Context ctx) {
super(ctx);
}
@Override
public BottomNaviPresenter createPresenter() {
return new BottomNaviPresenter();
}
// override to extend visibility from protected to public
@Override
public Parcelable onSaveInstanceState() {
return super.onSaveInstanceState();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
BottomNavi navi = new BottomNavi(this);
setContentView(navi);
// Do something that forces ViewGroupMvpDelegateImpl to be constructed
// and register itself to listen for activity lifecycle changes
navi.onSaveInstanceState();
}
@Override
protected void onResume() {
super.onResume();
// Simulate a session timeout that throws the user back to login activity
finish();
// onAttachedToWindow() where the presenter is initialized only runs after activity onResume()
// and hence receiving a crash here
}
}
I see, thanks for the detailed report
Anything new regarding this issue? I think that I just hit the same bug in v 3.1.0, but with MviPresenter and the Conductor library:
java.lang.NullPointerException: Attempt to invoke interface method 'void com.hannesdorfmann.mosby3.mvi.MviPresenter.destroy()' on a null object reference
at com.hannesdorfmann.mosby3.MviConductorLifecycleListener.postDestroy(MviConductorLifecycleListener.java:133)
My app has a complex routing with several nested routers in Conductor and this crash happens when the app is resumed after a long time in background into state with backstack bigger then one. Then after tapping the back it does not pop the backstack but crashes.
It can be reproduced with the "Don't keep activities" enabled in the debug options in the phone's settings. Then navigating to some screen where the backstack grows and minimizing the app (i.e. press home) will crash the app, sometimes :/
A similar error happens when you call finish
for an activity in onCreate
, it tries to delete a null presenter in onDestroy
and crashes.
I will work on this kind of issues this weekend
Daniel Rampelt [email protected] schrieb am Do., 29. März 2018, 20:55:
A similar error happens when you call finish for an activity in onCreate, it tries to delete a null presenter in onDestroy and crashes.
— You are receiving this because you commented.
Reply to this email directly, view it on GitHub https://github.com/sockeqwe/mosby/issues/290#issuecomment-377337195, or mute the thread https://github.com/notifications/unsubscribe-auth/AAjnrhB-LFSwnhhJPZdgshgXm7IZqH9gks5tjS4pgaJpZM4Q9cib .
when the new update will be released? I am also getting this exception on crashlytics on some users:
Caused by java.lang.NullPointerException at com.hannesdorfmann.mosby3.mvp.delegate.ViewGroupMvpDelegateImpl.detachPresenterIfNotDoneYet(ViewGroupMvpDelegateImpl.java:301) at com.hannesdorfmann.mosby3.mvp.delegate.ViewGroupMvpDelegateImpl.onActivityDestroyed(ViewGroupMvpDelegateImpl.java:255) at android.app.Application.dispatchActivityDestroyed(Application.java:265) at android.app.Activity.onDestroy(Activity.java:1541) at android.support.v4.app.FragmentActivity.onDestroy(FragmentActivity.java:358) at android.support.v7.app.AppCompatActivity.onDestroy(AppCompatActivity.java:209) ...
I'm also detecting this crash from time to time and on Crashlytics. @sockeqwe Are going to release a new update anytime soon? Thanks!
Working on it, along migrating to android x
Is there a chance to get this fixed without tying it to the conversion to androidx? We are seeing crashes as well.
Use latest snapshot 3.1.1-SNAPSHOT (see README)
Keith Naas [email protected] schrieb am Fr., 16. Nov. 2018, 16:41:
Is there a chance to get this fixed without tying it to the conversion to androidx? We are seeing crashes as well.
— You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub https://github.com/sockeqwe/mosby/issues/290#issuecomment-439433162, or mute the thread https://github.com/notifications/unsubscribe-auth/AAjnruqdbBGcIrU_o0r_zNj1bVOaW75Uks5uvtyygaJpZM4Q9cib .
Version 3.1.1-SNAPSHOT still fails
Reproducable on 3.1.1 release. ViewGroupMviDelegateImpl I've call finish() in onResume and onActivityResult
Thanks for reporting. Will check this later this week. Just to be clear: it causes to crash in both cases:
- calling finish() in
onResume()
- calling finish() in
onActivityResult()
I don't know actually. Stacktrace do not include either:
Caused by java.lang.NullPointerExceptionAttempt to invoke interface method 'void com.hannesdorfmann.mosby3.mvp.MvpPresenter.detachView()' on a null object reference Raw Text
--
| com.hannesdorfmann.mosby3.ViewGroupMviDelegateImpl.detachPresenterIfNotDoneYet (ViewGroupMviDelegateImpl.java:275)
| com.hannesdorfmann.mosby3.ViewGroupMviDelegateImpl.onActivityDestroyed (ViewGroupMviDelegateImpl.java:251)
| android.app.Application.dispatchActivityDestroyed (Application.java:253)
| android.app.Activity.onDestroy (Activity.java:1995)
| android.support.v4.app.FragmentActivity.onDestroy (FragmentActivity.java:413)
| android.support.v7.app.AppCompatActivity.onDestroy (AppCompatActivity.java:210)
| android.app.Activity.performDestroy (Activity.java:7297)
| android.app.Instrumentation.callActivityOnDestroy (Instrumentation.java:1250)
| android.app.ActivityThread.performDestroyActivity (ActivityThread.java:4437)
| android.app.ActivityThread.handleDestroyActivity (ActivityThread.java:4468)
| android.app.ActivityThread.-wrap5 (Unknown Source)
| android.app.ActivityThread$H.handleMessage (ActivityThread.java:1678)
| android.os.Handler.dispatchMessage (Handler.java:106)
| android.os.Looper.loop (Looper.java:171)
| android.app.ActivityThread.main (ActivityThread.java:6651)
| java.lang.reflect.Method.invoke (Method.java)
| com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:547)
| com.android.internal.os.ZygoteInit.main (ZygoteInit.java:824)