{ "id": "173458", "key": "TIMOB-26978", "fields": { "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [ { "id": "20432", "name": "Release 8.0.1", "archived": false, "released": true, "releaseDate": "2019-05-15" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2019-04-29T14:14:45.000+0000", "created": "2019-04-11T01:49:04.000+0000", "priority": { "name": "None", "id": "6" }, "labels": [ "ProgressIndicator", "android", "dialog", "engSchedule" ], "versions": [], "issuelinks": [ { "id": "57492", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "outwardIssue": { "id": "173214", "key": "TIMOB-26911", "fields": { "summary": "Crash log analysis when the app goes into the background.", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "priority": { "name": "None", "id": "6" }, "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false } } } } ], "assignee": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2019-04-29T14:14:45.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "10202", "name": "Android", "description": "Android Platform" } ], "description": "*Summary:*\r\nShowing or hiding a dialog (alert or progress indicator) from an activity window that is in the middle of being destroy, but not \"finished\", will sometimes cause the following crashes.\r\n\r\nNote that an Android activity can be flagged as \"destroyed\", but not \"finished\", if the Android OS destroys it due to low memory or if system developer option \"Don't keep activities\" is enabled. When this happens, the Android OS intends to restore the activity when the end-user navigates back to it.\r\n\r\n----\r\n*Steps to reproduce dialog \"dismiss\" crash:*\r\n_Unknown._\r\n\r\nTheoretically, this should be possible by calling a dialog's {{hide()}} method via the {{Ti.UI.Window}} object's {{window.activity.onDestroy}} callback, but it doesn't crash for me.\r\n\r\nBelow is the stack trace reported by some app developers when this issue happens\r\n{code}\r\njava.lang.IllegalArgumentException: View=DecorView@1a43283[TiActivity] not attached to window manager\r\nat android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:485)\r\nat android.view.WindowManagerGlobal.removeView(WindowManagerGlobal.java:394)\r\nat android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:124)\r\nat android.app.Dialog.dismissDialog(Dialog.java:375)\r\nat android.app.Dialog.dismiss(Dialog.java:358)\r\nat ti.modules.titanium.ui.widget.TiUIProgressIndicator.handleHide(TiUIProgressIndicator.java:252)\r\nat ti.modules.titanium.ui.widget.TiUIProgressIndicator.handleMessage(TiUIProgressIndicator.java:78)\r\nat android.os.Handler.dispatchMessage(Handler.java:102)\r\nat android.os.Looper.loop(Looper.java:193)\r\nat android.app.ActivityThread.main(ActivityThread.java:6718)\r\nat java.lang.reflect.Method.invoke(Native Method)\r\nat com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)\r\nat com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)\r\n{code}\r\n\r\n----\r\n*Steps to reproduce dialog \"show\" crash:*\r\n# Go to the Android device's main \"Settings\" screen.\r\n# Tap on \"System\" under \"Settings.\r\n# Tap on \"Developer options\" under \"System\" settings.\r\n# Enable \"Don't keep activities\", which should be near the bottom of the list.\r\n# Build and run the below code on the above Android device.\r\n# Press the Android \"Home\" button.\r\n# Resume the app.\r\n# Press the Android \"Back\" button.\r\n# Observe the Android log. You'll see one of the below exception stack traces.\r\n\r\napp.js\r\n{code:javascript}\r\nvar progressIndicator = Ti.UI.Android.createProgressIndicator({\r\n\tmessage: \"Progressing...\",\r\n\tlocation: Ti.UI.Android.PROGRESS_INDICATOR_DIALOG,\r\n\ttype: Ti.UI.Android.PROGRESS_INDICATOR_INDETERMINANT,\r\n\tcancelable: false,\r\n});\r\nvar window = Ti.UI.createWindow();\r\nwindow.add(Ti.UI.createLabel({ text: \"Press Back\" }));\r\nwindow.activity.onDestroy = function() {\r\n\tvar isShowingAlert = true;\r\n\tif (isShowingAlert) {\r\n\t\talert(\"Hello World!\");\r\n\t} else {\r\n\t\tvar progressIndicator = Ti.UI.Android.createProgressIndicator({\r\n\t\t\tmessage: \"Progressing...\",\r\n\t\t\tlocation: Ti.UI.Android.PROGRESS_INDICATOR_DIALOG,\r\n\t\t\ttype: Ti.UI.Android.PROGRESS_INDICATOR_INDETERMINANT,\r\n\t\t\tcancelable: false,\r\n\t\t});\r\n\t\tprogressIndicator.show();\r\n\t}\r\n}\r\nwindow.open();\r\n{code}\r\n\r\nStack trace in 7.5.x...\r\n{code}\r\n[ERROR] TiExceptionHandler: (main) [611,6711] Attempt to invoke virtual method 'java.lang.Object org.appcelerator.kroll.KrollObject.callProperty(java.lang.String, java.lang.Object[])' on a null object reference\r\n[ERROR] TiExceptionHandler:\r\n[ERROR] TiExceptionHandler: org.appcelerator.kroll.KrollProxy.handleMessage(KrollProxy.java:1210)\r\n[ERROR] TiExceptionHandler: org.appcelerator.titanium.proxy.ActivityProxy.handleMessage(ActivityProxy.java:394)\r\n[ERROR] TiExceptionHandler: android.os.Handler.dispatchMessage(Handler.java:102)\r\n[ERROR] TiExceptionHandler: android.os.Looper.loop(Looper.java:193)\r\n[ERROR] TiExceptionHandler: android.app.ActivityThread.main(ActivityThread.java:6669)\r\n[ERROR] TiExceptionHandler: java.lang.reflect.Method.invoke(Native Method)\r\n[ERROR] TiExceptionHandler: com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)\r\n[ERROR] TiExceptionHandler: com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)\r\n[ERROR] TiExceptionHandler: (main) [34,6745] Unable to add window -- token android.os.BinderProxy@b66e705 is not valid; is your activity running?\r\n[ERROR] TiExceptionHandler:\r\n[ERROR] TiExceptionHandler: android.view.ViewRootImpl.setView(ViewRootImpl.java:798)\r\n[ERROR] TiExceptionHandler: android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:356)\r\n[ERROR] TiExceptionHandler: android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)\r\n[ERROR] TiExceptionHandler: android.app.Dialog.show(Dialog.java:329)\r\n[ERROR] TiExceptionHandler: org.appcelerator.titanium.TiExceptionHandler.createDialog(TiExceptionHandler.java:233)\r\n[ERROR] TiExceptionHandler: org.appcelerator.titanium.TiExceptionHandler$1.onCurrentActivityReady(TiExceptionHandler.java:171)\r\n[ERROR] TiExceptionHandler: org.appcelerator.titanium.util.TiUIHelper.waitForCurrentActivity(TiUIHelper.java:193)\r\n[ERROR] TiExceptionHandler: org.appcelerator.titanium.TiApplication.waitForCurrentActivity(TiApplication.java:817)\r\n[ERROR] TiExceptionHandler: org.appcelerator.titanium.TiExceptionHandler.handleOpenErrorDialog(TiExceptionHandler.java:167)\r\n[ERROR] TiExceptionHandler: org.appcelerator.titanium.TiExceptionHandler.openErrorDialog(TiExceptionHandler.java:139)\r\n[ERROR] TiExceptionHandler: org.appcelerator.titanium.TiExceptionHandler.handleException(TiExceptionHandler.java:264)\r\n[ERROR] TiExceptionHandler: org.appcelerator.kroll.KrollRuntime.dispatchException(KrollRuntime.java:540)\r\n[ERROR] TiExceptionHandler: org.appcelerator.titanium.TiApplication$1.uncaughtException(TiApplication.java:362)\r\n[ERROR] TiExceptionHandler: org.appcelerator.kroll.KrollProxy.handleMessage(KrollProxy.java:1225)\r\n[ERROR] TiExceptionHandler: org.appcelerator.titanium.proxy.ActivityProxy.handleMessage(ActivityProxy.java:394)\r\n[ERROR] TiExceptionHandler: android.os.Handler.dispatchMessage(Handler.java:102)\r\n[ERROR] TiExceptionHandler: android.os.Looper.loop(Looper.java:193)\r\n[ERROR] TiExceptionHandler: android.app.ActivityThread.main(ActivityThread.java:6669)\r\n[ERROR] TiExceptionHandler: java.lang.reflect.Method.invoke(Native Method)\r\n[ERROR] TiExceptionHandler: com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)\r\n[ERROR] TiExceptionHandler: com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)\r\n{code}\r\n\r\nStack trace in 8.0.0...\r\n{code}\r\n[ERROR] WindowManager: android.view.WindowLeaked: Activity org.appcelerator.titanium.TiActivity has leaked window DecorView@89a3790[TiActivity] that was originally added here\r\n[ERROR] WindowManager: \tat android.view.ViewRootImpl.(ViewRootImpl.java:511)\r\n[ERROR] WindowManager: \tat android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:346)\r\n[ERROR] WindowManager: \tat android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)\r\n[ERROR] WindowManager: \tat android.app.Dialog.show(Dialog.java:329)\r\n[ERROR] WindowManager: \tat ti.modules.titanium.ui.widget.TiUIProgressIndicator.handleShow(TiUIProgressIndicator.java:231)\r\n[ERROR] WindowManager: \tat ti.modules.titanium.ui.widget.TiUIProgressIndicator.show(TiUIProgressIndicator.java:146)\r\n[ERROR] WindowManager: \tat ti.modules.titanium.ui.android.ProgressIndicatorProxy.handleShow(ProgressIndicatorProxy.java:59)\r\n[ERROR] WindowManager: \tat org.appcelerator.titanium.proxy.TiViewProxy.show(TiViewProxy.java:763)\r\n[ERROR] WindowManager: \tat ti.modules.titanium.ui.TiDialogProxy.access$001(TiDialogProxy.java:29)\r\n[ERROR] WindowManager: \tat ti.modules.titanium.ui.TiDialogProxy$1.onCurrentActivityReady(TiDialogProxy.java:47)\r\n[ERROR] WindowManager: \tat org.appcelerator.titanium.util.TiUIHelper.waitForCurrentActivity(TiUIHelper.java:194)\r\n[ERROR] WindowManager: \tat ti.modules.titanium.ui.TiDialogProxy.show(TiDialogProxy.java:42)\r\n[ERROR] WindowManager: \tat org.appcelerator.kroll.runtime.v8.V8Object.nativeCallProperty(Native Method)\r\n[ERROR] WindowManager: \tat org.appcelerator.kroll.runtime.v8.V8Object.callProperty(V8Object.java:75)\r\n[ERROR] WindowManager: \tat org.appcelerator.kroll.KrollProxy.callPropertySync(KrollProxy.java:753)\r\n[ERROR] WindowManager: \tat org.appcelerator.titanium.TiBaseActivity.dispatchCallback(TiBaseActivity.java:1304)\r\n[ERROR] WindowManager: \tat org.appcelerator.titanium.TiBaseActivity.onDestroy(TiBaseActivity.java:1589)\r\n[ERROR] WindowManager: \tat org.appcelerator.titanium.TiActivity.onDestroy(TiActivity.java:58)\r\n[ERROR] WindowManager: \tat android.app.Activity.performDestroy(Activity.java:7395)\r\n[ERROR] WindowManager: \tat android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1306)\r\n[ERROR] WindowManager: \tat android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4443)\r\n[ERROR] WindowManager: \tat android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:4476)\r\n[ERROR] WindowManager: \tat android.app.servertransaction.DestroyActivityItem.execute(DestroyActivityItem.java:39)\r\n[ERROR] WindowManager: \tat android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:145)\r\n[ERROR] WindowManager: \tat android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)\r\n[ERROR] WindowManager: \tat android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)\r\n[ERROR] WindowManager: \tat android.os.Handler.dispatchMessage(Handler.java:106)\r\n[ERROR] WindowManager: \tat android.os.Looper.loop(Looper.java:193)\r\n[ERROR] WindowManager: \tat android.app.ActivityThread.main(ActivityThread.java:6669)\r\n[ERROR] WindowManager: \tat java.lang.reflect.Method.invoke(Native Method)\r\n[ERROR] WindowManager: \tat com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)\r\n[ERROR] WindowManager: \tat com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)\r\n{code}\r\n\r\n----\r\n*Solution:*\r\nThe dialog handling code will attempt to show a dialog use the top-most activity that is being shown. This activity is fetched via {{TiApplication.getCurrentActivity()}}. This method will checks the top-most activity's {{isFinishing()}} method and ignores skips them knowing that they are in the middle of being destroyed... but this code is also missing an {{isDestroyed()}} check since an activity can be destroyed but not finished for the \"Don't keep activities\" edge-case.\r\n[TiApplication.getCurrentActivity()|https://github.com/appcelerator/titanium_mobile/blob/864d8f10b30b5d4fabb4d235a44e715973750c5a/android/titanium/src/java/org/appcelerator/titanium/TiApplication.java#L252]\r\n\r\nOur dialog dismissing code needs to check if the hosting activity has been destroyed as well, not just finished. We should also wrap a {{dismiss()}} call with a try/catch block just in case since we don't know how to reproduce this issue (might be a bug on Google's end that we need to work-around?).\r\n[TiUIDialog.java|https://github.com/appcelerator/titanium_mobile/blob/864d8f10b30b5d4fabb4d235a44e715973750c5a/android/modules/ui/src/java/ti/modules/titanium/ui/widget/TiUIDialog.java]\r\n[TiUIProgressIndicator.java|https://github.com/appcelerator/titanium_mobile/blob/864d8f10b30b5d4fabb4d235a44e715973750c5a/android/modules/ui/src/java/ti/modules/titanium/ui/widget/TiUIProgressIndicator.java]\r\n", "attachment": [], "flagged": false, "summary": "Android: Showing/hiding dialog while window is being destroyed by \"Don't keep activities\" sometimes crashes", "creator": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "subtasks": [], "reporter": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "environment": null, "closedSprints": [ { "id": 1124, "state": "closed", "name": "2019 Sprint 8", "startDate": "2019-03-31T18:03:00.000Z", "endDate": "2019-04-12T18:03:00.000Z", "completeDate": "2019-04-12T19:04:50.175Z", "originBoardId": 114 }, { "id": 1128, "state": "closed", "name": "2019 Sprint 9", "startDate": "2019-04-14T19:05:00.000Z", "endDate": "2019-04-26T19:05:00.000Z", "completeDate": "2019-04-26T22:05:13.933Z", "originBoardId": 114 }, { "id": 1129, "state": "closed", "name": "2019 Sprint 10", "startDate": "2019-04-28T22:06:00.000Z", "endDate": "2019-05-17T22:06:00.000Z", "completeDate": "2019-05-20T16:48:42.522Z", "originBoardId": 114 } ], "comment": { "comments": [ { "id": "447639", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "PR (master): https://github.com/appcelerator/titanium_mobile/pull/10829", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2019-04-12T02:04:07.000+0000", "updated": "2019-04-12T02:04:07.000+0000" }, { "id": "447997", "author": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "body": "PR (8.0.x): https://github.com/appcelerator/titanium_mobile/pull/10868", "updateAuthor": { "name": "jquick", "key": "jquick", "displayName": "Joshua Quick", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2019-04-26T22:32:15.000+0000", "updated": "2019-04-26T22:32:15.000+0000" }, { "id": "448007", "author": { "name": "lchoudhary", "key": "lchoudhary", "displayName": "Lokesh Choudhary", "active": true, "timeZone": "America/Los_Angeles" }, "body": "FR passed PR merged.", "updateAuthor": { "name": "lchoudhary", "key": "lchoudhary", "displayName": "Lokesh Choudhary", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2019-04-26T23:18:01.000+0000", "updated": "2019-04-26T23:18:01.000+0000" }, { "id": "448035", "author": { "name": "smohammed", "key": "smohammed", "displayName": "Samir Mohammed", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Closing ticket, fix verified in SDK version {{8.0.1.v20190426162041}} and SDK version {{8.1.0.v20190426222341}}\r\n\r\nTest and other information can be found at: \r\nMaster : https://github.com/appcelerator/titanium_mobile/pull/10829\r\n8_0_X: https://github.com/appcelerator/titanium_mobile/pull/10868", "updateAuthor": { "name": "smohammed", "key": "smohammed", "displayName": "Samir Mohammed", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2019-04-29T14:14:36.000+0000", "updated": "2019-04-29T14:14:36.000+0000" } ], "maxResults": 4, "total": 4, "startAt": 0 } } }