[TIMOB-17089] Android: Activity/Fragment restore can sometimes crash app due to view ID collision
GitHub Issue | n/a |
---|---|
Type | Bug |
Priority | Critical |
Status | Closed |
Resolution | Fixed |
Resolution Date | 2019-04-29T21:22:21.000+0000 |
Affected Version/s | n/a |
Fix Version/s | Release 8.0.1 |
Components | Android |
Labels | android |
Reporter | grebulon |
Assignee | Joshua Quick |
Created | 2014-05-27T06:32:59.000+0000 |
Updated | 2019-05-05T08:17:10.000+0000 |
Description
Occasionally when my app is resumed (clicking on it from the task list), it crashes with the following line:
{noformat}
05-27 09:21:12.394: E/TiApplication(22330): (main) [108,27001] Sending event: exception on thread: main msg:java.lang.RuntimeException: Unable to start activity ComponentInfo{com.pingapp.app/org.appcelerator.titanium.TiTranslucentActivity}: java.lang.IllegalArgumentException: Wrong state class, expecting View State but received class android.widget.AbsListView$SavedState instead. This usually happens when two views of different type have the same id in the same hierarchy. This view's id is id/0x65. Make sure other views do not use the same id.; Titanium 3.2.1,2014/05/26 11:25,84d47ff
{noformat}
The cause is that the
TiTableView
constructor sets a constant id of TI_TABLE_VIEW_ID
(which is 0x65) as the view id. Constant ids should never be used in an application.
This can be easily reproduced like this: build an application with many text views, at least 101. Add one table view. Now to cause the state restore, move the application to the back, enter system settings -> display -> font size, and change the size. Open the task list and select your app to bring it to front. The font size change will cause view state recalculation which will crash the app.
To fix this I added the following method to TiUIView
and used it to set the id:
{noformat}
static public int getUniqueId() {
if (idGenerator == null)
idGenerator = new AtomicInteger(0);
return idGenerator.incrementAndGet();
}
{noformat}
A quick grep on ".setId(" turned up other places in the sdk where you use constant ids - these need to be fixed as well.
Full stack dump of the crash:
{noformat}
05-27 09:21:12.394: E/TiApplication(22330): (main) [108,27001] Sending event: exception on thread: main msg:java.lang.RuntimeException: Unable to start activity ComponentInfo{com.pingapp.app/org.appcelerator.titanium.TiTranslucentActivity}: java.lang.IllegalArgumentException: Wrong state class, expecting View State but received class android.widget.AbsListView$SavedState instead. This usually happens when two views of different type have the same id in the same hierarchy. This view's id is id/0x65. Make sure other views do not use the same id.; Titanium 3.2.1,2014/05/26 11:25,84d47ff
05-27 09:21:12.394: E/TiApplication(22330): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.pingapp.app/org.appcelerator.titanium.TiTranslucentActivity}: java.lang.IllegalArgumentException: Wrong state class, expecting View State but received class android.widget.AbsListView$SavedState instead. This usually happens when two views of different type have the same id in the same hierarchy. This view's id is id/0x65. Make sure other views do not use the same id.
05-27 09:21:12.394: E/TiApplication(22330): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2339)
05-27 09:21:12.394: E/TiApplication(22330): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2389)
05-27 09:21:12.394: E/TiApplication(22330): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3868)
05-27 09:21:12.394: E/TiApplication(22330): at android.app.ActivityThread.access$700(ActivityThread.java:153)
05-27 09:21:12.394: E/TiApplication(22330): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1275)
05-27 09:21:12.394: E/TiApplication(22330): at android.os.Handler.dispatchMessage(Handler.java:99)
05-27 09:21:12.394: E/TiApplication(22330): at android.os.Looper.loop(Looper.java:137)
05-27 09:21:12.394: E/TiApplication(22330): at android.app.ActivityThread.main(ActivityThread.java:5289)
05-27 09:21:12.394: E/TiApplication(22330): at java.lang.reflect.Method.invokeNative(Native Method)
05-27 09:21:12.394: E/TiApplication(22330): at java.lang.reflect.Method.invoke(Method.java:525)
05-27 09:21:12.394: E/TiApplication(22330): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
05-27 09:21:12.394: E/TiApplication(22330): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555)
05-27 09:21:12.394: E/TiApplication(22330): at dalvik.system.NativeStart.main(Native Method)
05-27 09:21:12.394: E/TiApplication(22330): Caused by: java.lang.IllegalArgumentException: Wrong state class, expecting View State but received class android.widget.AbsListView$SavedState instead. This usually happens when two views of different type have the same id in the same hierarchy. This view's id is id/0x65. Make sure other views do not use the same id.
05-27 09:21:12.394: E/TiApplication(22330): at android.view.View.onRestoreInstanceState(View.java:12315)
05-27 09:21:12.394: E/TiApplication(22330): at android.widget.TextView.onRestoreInstanceState(TextView.java:3495)
05-27 09:21:12.394: E/TiApplication(22330): at android.view.View.dispatchRestoreInstanceState(View.java:12291)
05-27 09:21:12.394: E/TiApplication(22330): at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2626)
05-27 09:21:12.394: E/TiApplication(22330): at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2626)
05-27 09:21:12.394: E/TiApplication(22330): at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2626)
05-27 09:21:12.394: E/TiApplication(22330): at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2626)
05-27 09:21:12.394: E/TiApplication(22330): at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2626)
05-27 09:21:12.394: E/TiApplication(22330): at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2626)
05-27 09:21:12.394: E/TiApplication(22330): at android.view.View.restoreHierarchyState(View.java:12269)
05-27 09:21:12.394: E/TiApplication(22330): at com.android.internal.policy.impl.PhoneWindow.restoreHierarchyState(PhoneWindow.java:1700)
05-27 09:21:12.394: E/TiApplication(22330): at android.app.Activity.onRestoreInstanceState(Activity.java:938)
05-27 09:21:12.394: E/TiApplication(22330): at org.appcelerator.titanium.TiBaseActivity.onRestoreInstanceState(TiBaseActivity.java:1316)
05-27 09:21:12.394: E/TiApplication(22330): at android.app.Activity.performRestoreInstanceState(Activity.java:910)
05-27 09:21:12.394: E/TiApplication(22330): at android.app.Instrumentation.callActivityOnRestoreInstanceState(Instrumentation.java:1138)
05-27 09:21:12.394: E/TiApplication(22330): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2307)
{noformat}
\\
----
This often happens with TabGroups as well when a tab's fragment is restored. See...
[ERROR] TiExceptionHandler: (main) [156856,156856] Unable to start activity ComponentInfo{com.miga.app/org.appcelerator.titanium.TiActivity}: java.lang.ClassCastException: ti.modules.titanium.ui.widget.TiUILabel$1 cannot be cast to android.view.ViewGroup
[ERROR] TiExceptionHandler:
[ERROR] TiExceptionHandler: android.support.v4.app.FragmentTransition.configureTransitionsOrdered(FragmentTransition.java:310)
[ERROR] TiExceptionHandler: android.support.v4.app.FragmentTransition.startTransitions(FragmentTransition.java:134)
[ERROR] TiExceptionHandler: android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2380)
[ERROR] TiExceptionHandler: android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2338)
[ERROR] TiExceptionHandler: android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2245)
[ERROR] TiExceptionHandler: android.support.v4.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3248)
[ERROR] TiExceptionHandler: android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3200)
[ERROR] TiExceptionHandler: android.support.v4.app.FragmentController.dispatchActivityCreated(FragmentController.java:195)
[ERROR] TiExceptionHandler: android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:597)
[ERROR] TiExceptionHandler: android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:177)
[ERROR] TiExceptionHandler: org.appcelerator.titanium.TiBaseActivity.onStart(TiBaseActivity.java:1504)
[ERROR] TiExceptionHandler: android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1299)
[ERROR] TiExceptionHandler: android.app.Activity.performStart(Activity.java:6690)
[ERROR] TiExceptionHandler: android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2688)
[ERROR] TiExceptionHandler: android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2786)
[ERROR] TiExceptionHandler: android.app.ActivityThread.-wrap12(ActivityThread.java)
[ERROR] TiExceptionHandler: android.app.ActivityThread$H.handleMessage(ActivityThread.java:1501)
[ERROR] TiExceptionHandler: android.os.Handler.dispatchMessage(Handler.java:102)
[ERROR] TiExceptionHandler: android.os.Looper.loop(Looper.java:173)
[ERROR] TiExceptionHandler: android.app.ActivityThread.main(ActivityThread.java:6459)
[ERROR] TiExceptionHandler: java.lang.reflect.Method.invoke(Native Method)
[ERROR] TiExceptionHandler: com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:938)
[ERROR] TiExceptionHandler: com.android.internal.os.ZygoteInit.main(ZygoteInit.java:828)
I'm having the exact same issue as well. Any progress on this?
Looks like all titanium users are building simple applications with small number of UI elements. Otherwise, there would be a bigger backlash.
I am running 3.5.1 on a lollipop device and this is happening a lot. Same code..same SDK working fine on non-lollipop devices. Any idea?
@Peter Ladis, for a workaround try changing your TableViews to Scroll/List Views where possible and check if the problem still exists
@muhammed - that is a huge change for my app. - is there anything else
@Peter, that's the one thing which seemed to have a visible direct impact on the number of these errors going down (to 0) on the production version of our app
PR (master): https://github.com/appcelerator/titanium_mobile/pull/10829
PR (8.0.x): https://github.com/appcelerator/titanium_mobile/pull/10868
FR passed PR merged.
Closing ticket, fix verified in SDK version 8.0.1.v20190426162041 and SDK version 8.1.0.v20190426222341. Test and other information can be found at: Master : https://github.com/appcelerator/titanium_mobile/pull/10829 8_0_X: https://github.com/appcelerator/titanium_mobile/pull/10868
Took 5 years...