Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-26850] Android: Activity callbacks onStop/onDestroy not invoked on main thread as of 7.5.0

GitHub Issuen/a
TypeBug
PriorityMedium
StatusClosed
ResolutionFixed
Resolution Date2019-03-04T10:21:38.000+0000
Affected Version/sRelease 7.5.0
Fix Version/sRelease 8.0.0
ComponentsAndroid
Labelsactivity, android, callback, qe-testadded, regression
ReporterAminul Islam
AssigneeJoshua Quick
Created2019-02-22T17:09:58.000+0000
Updated2019-04-30T22:41:02.000+0000

Description

*Summary:* If "tiapp.xml" property "run-on-main-thread" is set to true, then the activity's onStop and onDestroy callbacks are not invoked upon app exit. This is a regression as of 7.5.0. *Steps to reproduce:*

Set "tiapp.xml" property "run-on-main-thread" to true as shown below.

Use the below "app.js" code.

Build and run on Android.

Wait for the app to launch.

Notice in the log that "onStart()" and "onResume()" were successfully called.

Back out of the app to exit.

Notice in the log that "TopActivity.onStop()", "TopActivity.onDestroy()", and "RootActivity.onDesroy()" did *+not+* get called.

*tiapp.xml*
<?xml version="1.0" encoding="UTF-8"?>
<ti:app xmlns:ti="http://ti.appcelerator.org">
	<property name="run-on-main-thread" type="bool">true</property>
</ti:app>
*app.js*
function addActivityListenersTo(activity, name) {
	if (!activity) {
		return;
	}
	if (!name) {
		name = "Activity";
	}
	activity.onCreate = function() {
		Ti.API.info("@@@ " + name + ".onCreate() called.");
	};
	activity.onRestart = function() {
		Ti.API.info("@@@ " + name + ".onRestart() called.");
	};
	activity.onStart = function() {
		Ti.API.info("@@@ " + name + ".onStart() called.");
	};
	activity.onResume = function() {
		Ti.API.info("@@@ " + name + ".onResume() called.");
	};
	activity.onPause = function() {
		Ti.API.info("@@@ " + name + ".onPause() called.");
	};
	activity.onStop = function() {
		Ti.API.info("@@@ " + name + ".onStop() called.");
	};
	activity.onDestroy = function() {
		Ti.API.info("@@@ " + name + ".onDestroy() called.");
	};
}

addActivityListenersTo(Ti.Android.currentActivity, "RootActivity");

var window = Ti.UI.createWindow();
window.add(Ti.UI.createLabel({ text: "Activity Callback Test" }));
window.addEventListener("open", function() {
	Ti.API.info("@@@ Window 'open' event fired.");
});
addActivityListenersTo(window.activity, "TopActivity");
window.open();
*Work-Around 1:* If you are building with Titanium 7.5.x, then setting "run-on-main-thread" to false then the onStop() and onDestroy() callbacks will be successfully invoked. *Work-Around 2:* Add a listener to the Ti.UI.Window object's "close" event instead. This event is supported on both Android and iOS, making it a portable solution.

Comments

  1. Joshua Quick 2019-02-28

    PR (master): https://github.com/appcelerator/titanium_mobile/pull/10733 PR (8.0.x): https://github.com/appcelerator/titanium_mobile/pull/10734
  2. Joshua Quick 2019-02-28

    I see. Then an alternative solution that will work *+today+* is to use the Ti.UI.Window "focus" and "blur" events. These events will be fired in the same manner as onStop and onStart. And these events are definitely not fired when displaying an alert or tapping on a TextField. You can test out these events with my code below. https://docs.appcelerator.com/platform/latest/#!/api/Titanium.UI.Window-event-focus https://docs.appcelerator.com/platform/latest/#!/api/Titanium.UI.Window-event-blur
       var window = Ti.UI.createWindow({
       	layout: "vertical",
       	fullscreen: true,
       });
       var alertButton = Ti.UI.createButton({
       	title: "Show Alert",
       	top: "20%",
       });
       alertButton.addEventListener("click", function(e) {
       	// An alert dialog does not trigger window focus/blur events.
       	alert("Alert!");
       });
       window.add(alertButton);
       var windowButton = Ti.UI.createButton({
       	title: "Show Child Window",
       	top: "20%",
       });
       windowButton.addEventListener("click", function(e) {
       	// Displaying a child window does trigger parent window's focus/blur events.
       	var childWindow = Ti.UI.createWindow({ backgroundColor: "orange" });
       	var closeButton = Ti.UI.createButton({ title: "Close Me" });
       	closeButton.addEventListener("click", function(e) {
       		childWindow.close();
       	});
       	childWindow.add(closeButton);
       	childWindow.open();
       });
       window.add(windowButton);
       window.addEventListener("focus", function(e) {
       	Ti.API.info("@@@ Window 'focus' event received.");
       });
       window.addEventListener("blur", function(e) {
       	Ti.API.info("@@@ Window 'blur' event received.");
       });
       window.open();
       
    We also have a Ti.App "userinteraction" event that we've added to 7.5.0 that was intended to be used by apps that want to implement an auto-logout feature. This event will be fired any time the end-user taps on the app's screen or enters input. The idea is that you would reset a timer every time a "userinteraction" event is received, but if the timer elapses, then go ahead and trigger the auto-logout. https://docs.appcelerator.com/platform/latest/#!/api/Titanium.App-event-userinteraction Also note that in Titanium 8.0.1, we plan on modifying Android's Ti.App "pause" and "resume" events to match iOS' behavior. Where the "pause" event is fired when the app is put into the background and the "resume" event happens when the app is put into the foreground. This would mean that you no longer have to track Android activities anymore. See: [TIMOB-26746]
  3. Lokesh Choudhary 2019-02-28

    FR Passed. Waiting for Merge to be enabled.
  4. Lokesh Choudhary 2019-03-01

    PR's merged.
  5. Samir Mohammed 2019-03-04

    Closing ticket, fix verified in SDK Version 8.1.0.v20190301155716 and SDK Version 8.0.0.v20190301145350. Test and other information can be found at: PR (master): https://github.com/appcelerator/titanium_mobile/pull/10733 PR (8.0.x): https://github.com/appcelerator/titanium_mobile/pull/10734

JSON Source