Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-27104] Android: ProgressIndicator logs "WindowLeaked" exception when hiding dialog and closing window at same time as of 8.0.2

GitHub Issuen/a
TypeBug
PriorityHigh
StatusClosed
ResolutionFixed
Resolution Date2019-08-23T04:57:13.000+0000
Affected Version/sRelease 8.0.2
Fix Version/sRelease 8.1.1
ComponentsAndroid
LabelsProgressIndicator, android, close, dialog, engSchedule, exception, hide
ReporterHans Knöchel
AssigneeJoshua Quick
Created2019-05-28T11:41:51.000+0000
Updated2019-08-23T04:57:13.000+0000

Description

*Summary:* As of Titanium 8.0.2, hiding a Ti.UI.Android.ProgressIndicator and closing its parent window at the same time will log a "WindowLeaked" exception. This is not a crash. Nothing harmful occurs. This is merely an unsightly exception stack trace error that occurs in the log. *Steps to reproduce:*

Build and run the below code on Android.

Tap on the "Show Progress Dialog" button.

Wait 2 seconds for the progress dialog and its window to close.

Observe the log.

var progressIndicator = Ti.UI.Android.createProgressIndicator({
	message: "Progressing...",
	location: Ti.UI.Android.PROGRESS_INDICATOR_DIALOG,
	type: Ti.UI.Android.PROGRESS_INDICATOR_INDETERMINANT,
	cancelable: false,
	persistent: true,
});

var window = Ti.UI.createWindow();
var button = Ti.UI.createButton({ title: "Show Progress Dialog" });
button.addEventListener("click", function(e) {
	var childWindow = Ti.UI.createWindow({ title: "Child Window" });
	childWindow.addEventListener("open", function() {
		progressIndicator.show();
		setTimeout(function() {
			progressIndicator.hide();
			childWindow.close();
// This works-around the problem.
//			setTimeout(function() { childWindow.close(); }, 1);
		}, 2000);
	});
	childWindow.open();
});
window.add(button);
window.open();
*Result:* The following gets logged when the progress dialog closes.
[ERROR] WindowManager: android.view.WindowLeaked: Activity org.appcelerator.titanium.TiActivity has leaked window DecorView@e74eabe[TiActivity] that was originally added here
[ERROR] WindowManager: 	at android.view.ViewRootImpl.<init>(ViewRootImpl.java:518)
[ERROR] WindowManager: 	at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:346)
[ERROR] WindowManager: 	at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:94)
[ERROR] WindowManager: 	at android.app.Dialog.show(Dialog.java:329)
[ERROR] WindowManager: 	at ti.modules.titanium.ui.widget.TiUIProgressIndicator.handleShow(TiUIProgressIndicator.java:236)
[ERROR] WindowManager: 	at ti.modules.titanium.ui.widget.TiUIProgressIndicator.show(TiUIProgressIndicator.java:146)
[ERROR] WindowManager: 	at ti.modules.titanium.ui.android.ProgressIndicatorProxy.handleShow(ProgressIndicatorProxy.java:59)
[ERROR] WindowManager: 	at org.appcelerator.titanium.proxy.TiViewProxy.show(TiViewProxy.java:765)
[ERROR] WindowManager: 	at ti.modules.titanium.ui.TiDialogProxy.access$001(TiDialogProxy.java:29)
[ERROR] WindowManager: 	at ti.modules.titanium.ui.TiDialogProxy$1.onCurrentActivityReady(TiDialogProxy.java:47)
[ERROR] WindowManager: 	at org.appcelerator.titanium.util.TiUIHelper.waitForCurrentActivity(TiUIHelper.java:195)
[ERROR] WindowManager: 	at ti.modules.titanium.ui.TiDialogProxy.show(TiDialogProxy.java:42)
[ERROR] WindowManager: 	at org.appcelerator.kroll.runtime.v8.V8Object.nativeFireEvent(Native Method)
[ERROR] WindowManager: 	at org.appcelerator.kroll.runtime.v8.V8Object.fireEvent(V8Object.java:63)
[ERROR] WindowManager: 	at org.appcelerator.kroll.KrollProxy.doFireEvent(KrollProxy.java:978)
[ERROR] WindowManager: 	at org.appcelerator.kroll.KrollProxy.handleMessage(KrollProxy.java:1207)
[ERROR] WindowManager: 	at org.appcelerator.titanium.proxy.TiViewProxy.handleMessage(TiViewProxy.java:266)
[ERROR] WindowManager: 	at android.os.Handler.dispatchMessage(Handler.java:102)
[ERROR] WindowManager: 	at android.os.Looper.loop(Looper.java:193)
[ERROR] WindowManager: 	at android.app.ActivityThread.main(ActivityThread.java:6694)
[ERROR] WindowManager: 	at java.lang.reflect.Method.invoke(Native Method)
[ERROR] WindowManager: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
[ERROR] WindowManager: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
*Note:* The error appears to be harmless. The exception is being caught and logged. The reason it is happening is because the dialog is being shown again in a destroyed activity window. Why the code is automatically calling its show() method again after hiding/closing is what we need to track down (this is the real bug; but our safety mechanisms are catching it). *Comment from Hans Knöchel:* We suspect it being related to showing our [loader class](https://gist.github.com/hansemannn/20297e983e2b8c898975b600e7ab8418) that uses a Ti.UI.ActivityIndicator. This did not happen on earlier versions of the SDK. *Work-around:* Instead of hiding the dialog and closing its parent window back-to-back like this...
progressIndicator.hide();
childWindow.close();
Delay closing the window after hiding the dialog like this...
progressIndicator.hide();
setTimeout(function() { childWindow.close(); }, 1);

Comments

  1. Hans Knöchel 2019-05-28

    [~jquick] This may be a regression of TIMOB-26978.
  2. Joshua Quick 2019-06-29

    [~hknoechel], I suspect you can work-around this issue by changing the following code in your "loader.js" from this...
       this.activityIndicator.hide();
       resolve();
       
    ...to this...
       this.activityIndicator.hide();
       setTimeout(() => {
       	resolve();
       }, 1);
       
  3. Joshua Quick 2019-06-29

    I've confirmed that this issue was introduced in Titanium 8.0.2. Titanium 8.01 does *NOT* have this issue. This is curious since 8.0.1 has dialog code changes while 8.0.2 does not.
  4. Hans Knöchel 2019-07-15

    Thanks for the workaround Josh, I just saw it now. *EDIT*: Working fine for now, although every new timeout makes me a bit sad :P.
  5. Joshua Quick 2019-07-15

    I believe this issue has always been happening. The difference is that we're logging it now. But I do agree that it is unsightly and should be corrected.
  6. Joshua Quick 2019-08-13

    PR (master): https://github.com/appcelerator/titanium_mobile/pull/11115 PR (8.1.x): https://github.com/appcelerator/titanium_mobile/pull/11142 PR (8.3.x): https://github.com/appcelerator/titanium_mobile/pull/11143
  7. Satyam Sekhri 2019-08-20

    FR Passed on master, 8_1_X and 8_3_X. The progress indicator works as expected. Waiting for builds to pass.
  8. Christopher Williams 2019-08-22

    Merged to master, 8_3_X. (had already been merged to 8_1_X)
  9. Keerthi Mahalingam 2019-08-23

    Verified the fix on sdk 8.3.0.v20190822115908,8.2.0.v20190822114913 and 8.1.1.v20190822103134.Progress indicator works as expected. Closing *Test Enviornment:* Operating System Name = Mac OS X Version = 10.14.5 Architecture = 64bit Memory = 17179869184 Node.js Node.js Version = 10.16.2 npm Version = 6.9.0 Titanium CLI CLI Version = 5.2.1 Titanium SDK SDK Version = 8.2.0.v20190822114913 Device = One plus 5T android 9,samsung s5 android 6 Emulator= pixel android 9,nexus android 8

JSON Source