Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-26555] Android: Broadcast receivers should be unregistered when exiting the app

GitHub Issuen/a
TypeBug
PriorityMedium
StatusClosed
ResolutionFixed
Resolution Date2018-11-30T18:46:03.000+0000
Affected Version/sn/a
Fix Version/sRelease 8.0.0
ComponentsAndroid
Labelsandroid, breaking-change, broadcastReceiver, exit
ReporterJoshua Quick
AssigneeJoshua Quick
Created2018-11-13T23:44:39.000+0000
Updated2018-12-04T15:33:25.000+0000

Description

*Summary:* If you register a BroadcastReceiver and then back out of the app, the JavaScript runtime is kept alive due to the change we've made via [TIMOB-9831] so that the BroadcastReceiver JavaScript code can still function after exiting the app. The problem with this is if you re-launch the app after doing the above, you'll be stuck at the splash screen and the "app.js" won't be re-executed. The reason is because Titanium only supports running 1 JavaScript runtime at a time. You currently have to unregister the BroadcastReceiver before exiting the app to avoid this re-launch issue. This is a design issue and needs to change. We should revert the change made by [TIMOB-9831] and automatically unregister all broadcast receivers that were registered in JavaScript when backing out of the app. If an app developer wants a broadcast receiver to keep running when backing out, then they should set up the root window's [exitOnClose](https://docs.appcelerator.com/platform/latest/#!/api/Titanium.UI.Window-property-exitOnClose) property to false so that the UI and broadcast receiver will continue to run in the background as shown in "Work-Around 1" down below (or alternatively use "Work-Around 2" solution). This also makes the app work more like iOS. *Note:* Android services has this same problem. See: [TIMOB-26538] *Steps to reproduce:* 1. Build and run the below code on Android. 2. Back out of the app. 3. Re-launch the app. 4. Notice that you're stuck on the splash screen. _(This is the issue.)_
// Create a window with label displaying current headset state.
var window = Ti.UI.createWindow();
var label = Ti.UI.createLabel();
window.add(label);
window.open();

// Register a headset broadcast receiver.
var receiver = Ti.Android.createBroadcastReceiver({
	onReceived: function(e) {
		// Headset has been connected/disconnected. Display current state via label.
		if (e.intent.action === Ti.Android.ACTION_HEADSET_PLUG) {
			var isPluggedIn = (e.intent.getIntExtra("state", 0) != 0);
			label.text = "Headset is " + (isPluggedIn ? "Connected" : "Disconnected");
		}
	},
});
Ti.Android.registerBroadcastReceiver(receiver, [Ti.Android.ACTION_HEADSET_PLUG]);
*Work-Around 1:* For the 1st window you open, set it's [exitOnClose](https://docs.appcelerator.com/platform/latest/#!/api/Titanium.UI.Window-property-exitOnClose) property to false like the below. This prevents the back button from closing your root window and makes the app work more like iOS. It also allows the broadcast receiver to operate in the background without issue. This is the best solution.
var window = Ti.UI.createWindow({
	exitOnClose: false,
});
window.open();
*Work-Around 2:* Override the root window's "androidback" event and use an intent to home-out of the app. This is similar to the work-around 1 solution where the root window is not closed and the broadcast receiver will continue to run in the background. Again, this makes your app effectively work like iOS.
var window = Ti.UI.createWindow();
window.addEventListener("androidback", function(e) {
	// If the back key was press, cancel it and go to the home-screen instead.
	var intent = Ti.Android.createIntent({
		action: Ti.Android.ACTION_MAIN,
	});
	intent.addCategory(Ti.Android.CATEGORY_HOME);
	intent.setFlags(Ti.Android.FLAG_ACTIVITY_NEW_TASK);
	Ti.Android.currentActivity.startActivity(intent);
});
window.open();
*Work-Around 3:* Unregister the broadcast receiver when the root window is being closed. This is best if you don't need to run it while in the background.
window.addEventListener("close", function(e) {
	Ti.Android.unregisterBroadcastReceiver(receiver);
});

Comments

  1. Joshua Quick 2018-11-14

    PR (master): https://github.com/appcelerator/titanium_mobile/pull/10453
  2. Lokesh Choudhary 2018-11-16

    FR Passed. Waiting for CR to merge.
  3. Lokesh Choudhary 2018-11-30

    PR Merged.
  4. Keerthi Mahalingam 2018-12-04

    Verified the fix on SDK 8.0.0.v20181203170303. Works fine.
       Operating System
         Name                        = Mac OS X
         Version                     = 10.13.6
         Architecture                = 64bit
       Node.js
         Node.js Version             = 8.12.0
         npm Version                 = 6.4.1
       Titanium CLI
         CLI Version                 = 5.1.1
       Studio			=5.1.2.201810301430
        SDK version          = 8.0.0.v20181203170303
       Device                    = Samsung s5 android 6, 
       Emulator                = Nexus 6p android 7
       

JSON Source