[TIMOB-26555] Android: Broadcast receivers should be unregistered when exiting the app
GitHub Issue | n/a |
---|---|
Type | Bug |
Priority | Medium |
Status | Closed |
Resolution | Fixed |
Resolution Date | 2018-11-30T18:46:03.000+0000 |
Affected Version/s | n/a |
Fix Version/s | Release 8.0.0 |
Components | Android |
Labels | android, breaking-change, broadcastReceiver, exit |
Reporter | Joshua Quick |
Assignee | Joshua Quick |
Created | 2018-11-13T23:44:39.000+0000 |
Updated | 2018-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);
});
PR (master): https://github.com/appcelerator/titanium_mobile/pull/10453
FR Passed. Waiting for CR to merge.
PR Merged.
Verified the fix on SDK 8.0.0.v20181203170303. Works fine.