Sometimes calling
activity.getSupportFragmentManager().popBackStackImmediate()
results in an error in particular:
Fatal Exception: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
What check will prevent this error from occurring? is it enough to check
!activity.isFinishing()
Or should one check also that activity is not stopped?
Related
I have read a lot of similar questions, but still couldn't find the answer.
I have an app deployed to the market, and I receive some IllegalStateException crash reports through BugSnag. But I can't reproduce it on my end, all the information I have for this problem is from BugSnag.
The stack trace for my problem is
java.lang.IllegalStateExceptionSplashScreenActivity
Can not perform this action after onSaveInstanceState
java.lang.IllegalStateException · Can not perform this action after onSaveInstanceState
FragmentManager.java:2044android.support.v4.app.FragmentManagerImpl.checkStateLoss
FragmentManager.java:2067android.support.v4.app.FragmentManagerImpl.enqueueAction
BackStackRecord.java:680android.support.v4.app.BackStackRecord.commitInternal
BackStackRecord.java:634android.support.v4.app.BackStackRecord.commit
FragmentTabHost.java:288android.support.v4.app.FragmentTabHost.onAttachedToWindow
View.java:20011android.view.View.dispatchAttachedToWindow
ViewGroup.java:3589android.view.ViewGroup.dispatchAttachedToWindow
ViewGroup.java:3596android.view.ViewGroup.dispatchAttachedToWindow
ViewGroup.java:3596android.view.ViewGroup.dispatchAttachedToWindow
ViewGroup.java:3596android.view.ViewGroup.dispatchAttachedToWindow
ViewGroup.java:3596android.view.ViewGroup.dispatchAttachedToWindow
ViewGroup.java:3596android.view.ViewGroup.dispatchAttachedToWindow
ViewGroup.java:3596android.view.ViewGroup.dispatchAttachedToWindow
ViewRootImpl.java:2262android.view.ViewRootImpl.performTraversals
ViewRootImpl.java:1927android.view.ViewRootImpl.doTraversal
ViewRootImpl.java:8558android.view.ViewRootImpl$TraversalRunnable.run
Choreographer.java:949android.view.Choreographer$CallbackRecord.run
Choreographer.java:761android.view.Choreographer.doCallbacks
Choreographer.java:696android.view.Choreographer.doFrame
Choreographer.java:935android.view.Choreographer$FrameDisplayEventReceiver.run
Handler.java:873android.os.Handler.handleCallback
Handler.java:99android.os.Handler.dispatchMessage
Looper.java:214android.os.Looper.loop
ActivityThread.java:7124android.app.ActivityThread.main
Method.java:-2java.lang.reflect.Method.invoke
RuntimeInit.java:494com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run
ZygoteInit.java:975com.android.internal.os.ZygoteInit.main
The following is my program logic. The FragmentTabHost is only used in HomeActivity. Its setup is done entirely in onCreate, and it is not touched in other lifecycle callbacks.
From the bugsnag, I get the following breadcrumb. From the breadcrumb I can see the exception happens when the user press home_key or recent_app right after launch and in early phase of HomeActivity.
My questions are:
Why the Exception is registered under the SplashScreenActivity, shouldn't that activity finish long before the HomeActivity?
I see that TabHost tries to commit fragment transaction after onSaveInstanceState(), but any methods that involve committing fragments are executed in onCreate, why those commit events are scheduled after onPause?
I want my Application to show Custom Dialog When an Uncatch Exception occur.
For that reason, I am implementing Thread.setDefaultUncaughtExceptionHandler.
I am successfully able to handle all my uncatch Exceptions.
And Try to show the Toast.
But My Toast is not Displayed because my Main Looper (i.e My Main Thread) is being stopped and My Whole Application get blocked.
I tried to create a Alternate Main Looper when Main Looper is being stopped. But for some reason my Alternate Main Looper does not get Any Message in MessageQueue.
Is there any other way to do that.
What I need is to Show the Error to User and Close the Erroneous Activity, Not my Whole Application.
Or Else is there any way that I can Handle all the uncatch Exception in an Activity.
I would think if the error reached this point your application would be kill (thus no context to display your dialog) - I'm not certain on that however.
You could try catching the error yourself, then displaying your dialog and then throwing the UncaughtExceptionHandler exception on the dialog's closing.
I have an app with a long running action. I am using AsyncTask. In its onPostExecute() I call a function that modifies some views. I am getting this error on calling setEnabled on the 5th view of 10 views being modified. And it happens very seldom, getting the odd error report from users.
Obviously a multithreading issue. But I thought onPostExecute() always runs on the UI thread? Could it be that the UI thread suddenly gets changed to another thread??
Stack Trace:
generated the following exception:
android.view.ViewRoot$CalledFromWrongThreadException: Only the original
thread that created a view hierarchy can touch its views.
--------- Instruction Stack trace ---------
android.view.ViewRoot.checkThread(ViewRoot.java:3041)
android.view.ViewRoot.invalidateChild(ViewRoot.java:647)
android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:673)
android.view.ViewGroup.invalidateChild(ViewGroup.java:2511)
android.view.View.invalidate(View.java:5255)
android.view.View.invalidateDrawable(View.java:7293)
android.graphics.drawable.Drawable.invalidateSelf(Drawable.java:300)
8.
android.graphics.drawable.DrawableContainer.selectDrawable(DrawableContainer.java:227)
9.
android.graphics.drawable.StateListDrawable.onStateChange(StateListDrawable.java:99)
android.graphics.drawable.Drawable.setState(Drawable.java:400)
android.view.View.drawableStateChanged(View.java:7374)
android.view.ViewGroup.drawableStateChanged(ViewGroup.java:3357)
android.widget.FrameLayout.drawableStateChanged(FrameLayout.java:164)
android.view.View.refreshDrawableState(View.java:7388)
android.view.View.setEnabled(View.java:3147)
com.voltup.powermax.ac.a(ActivityAppUiProxy.java:383)
com.voltup.powermax.cp.onPostExecute(ModeChange.java:1)
android.os.AsyncTask.finish(AsyncTask.java:417)
But I thought onPostExecute() always runs on the UI thread?
Yes, it does. Per Selvin's comment, AFAIK, if you try to create an AsyncTask from another thread, it fails.
Could it be that the UI thread suddenly gets changed to another thread??
No. More likely, you are accidentally going down a code path in doInBackground() that is updating the UI.
If you have a full stack trace showing that you are getting this exception from logic executed in onPostExecute(), please edit your question and paste in that stack trace.
I have an activity that is triggered by a notification (when the user clicks).
1) When there is no other activity (from my app) alive, the activity does not rotate when the orientation changes. OnCreate() does not get called
2) When another activity is running (below), then when I rotate the device onCreate() gets called once but the activity dies immediately. No error logged
I can't see anything special in my activity but the fact that it is triggered by a notification and that it has a broadcast receiver in it (private class).
Thank you for your thoughts
EDIT: Please discard this question. I had a finish() in onStop().
Add a log statement in the Activity.onCreate() method that is dying. More likely is your activity is being recreated and something is tossing an exception. If you see the onCreate() statement in the logs twice then you know you likely having an exception being thrown. Even without it you can trace down which line its dying on by adding more log statements.
On orientation changes you're activity will be torn down and rebuilt unless you fixed the orientation in the manifest. If a service or broadcast receiver has a reference to it after it's torn down then any call to it will likely cause it to die as you're seeing. This is where Android's lifecycle is more hassle than its worth, but it is what it is.
More than likely something is throwing an exception and you're not seeing it or its being masked by another one being thrown. Make sure you're not filtering your logcat output by tag.
I found some CTS errors which are given below:
Compatibility Test Case: CtsAppTestCases
Package Name: android.app.cts.DialogTest
Error:
-- testContextMenu fail junit.framework.AssertionFailedError
at android.app.cts.DialogTest.testContextMenu(DialogTest.java:971)`
-- testTabScreen fail java.lang.RuntimeException: Intent {
act=Activity lifecycle incorrect: received
onResume but expected onStop at 5 }
at android.app.cts.ActivityTestsBase.waitForResultOrThrow(ActivityTestsBase.java:149)
-- testTabScreen fail java.lang.RuntimeException: Intent {
act=Activity lifecycle incorrect: received
onResume but expected onStop at 5 }
at android.app.cts.ActivityTestsBase.waitForResultOrThrow(ActivityTestsBase.java:149)
-- testScreen fail java.lang.RuntimeException: Intent { act=Activity
lifecycle incorrect: received onResume but expected onStop
at 5 }
at android.app.cts.ActivityTestsBase.waitForResultOrThrow(ActivityTestsBase.java:149)`
This Test is expecting the lifecycle as onPause() then onStop(), but onResme() was called rather than onStop().
According to Android Activity Docs – “After receiving this call you will usually receive a following call to onStop() (after the next activity has been resumed and displayed), however in some cases there will be a direct call back to onResume() without going through the stopped state.”
So, it is not mandatory to get desired sequence.