GitHub Issue | n/a |
Type | Bug |
Priority | High |
Status | Closed |
Resolution | Fixed |
Resolution Date | 2012-09-04T13:45:49.000+0000 |
Affected Version/s | Release 2.0.2, Release 2.0.1, Release 2.1.2 |
Fix Version/s | Release 2.1.3, Release 3.0.0, Sprint 2012-18 API |
Components | Android |
Labels | SupportTeam, android, api, qe-review, qe-testadded, titanbeta |
Reporter | Shawn Lipscomb |
Assignee | Josh Roesslein |
Created | 2012-04-10T09:14:50.000+0000 |
Updated | 2013-06-10T23:19:29.000+0000 |
Problem
On a window with a TextField, tapping the TextField to bring up the keyboard, then tapping the android:back button closes the window. Doing the same thing on the emulator simply dismisses the keyboard.
Actual Behavior
Clicking the android:back button when the keyboard is displayed closes the window (because the 'android:back' event is fired).
Expected Behavior
Clicking the android:back button when the keyboard is displayed should just dismiss the keyboard, and not fire the 'android:back' event.
Original Testcase
app.js
var win1=Ti.UI.createWindow({
layout:'vertical',
url:'win1.js',
backgroundColor:'gray',
exitOnClose:true,
navBarHidden:true
});
win1.open();
*NOTE*: The "android:back" event is buggy on some devices. It may never fire at all.
You may need to try various devices to reproduce the failure case.
To verify the expected behavior change the event to "androidback" (no colon).
win1.js
var win1=Ti.UI.currentWindow;
var TheLabel=Ti.UI.createLabel({
color:'black',
text:'Click the edit, then hit the back button. Keyboard should be dismissed, but the window should not close.',
width:'auto'
});
win1.add(TheLabel);
var TheTextField=Ti.UI.createTextField(
{color:'black',
width:150
});
win1.add(TheTextField);
function AndroidBackClicked()
{
win1.close();
}
win1.addEventListener('android:back',AndroidBackClicked);
Test case to verify 'androidback' does not fire when dismissing keyboard.
var win = Ti.UI.createWindow();
win.add(Ti.UI.createTextField({width: '75%'}));
win.addEventListener('androidback', function() {
alert('back event fired!');
});
win.open();
1. Run application on a device that uses a soft keyboard.
2. Focus the textfield to bring up the soft keyboard.
3. Hit the "back" button on the device. You should see NO alert.
4. Hit the "back" button again. You SHOULD see an alert.
Fail: You see two alerts (one for each "back" press).
Pass: You only get an alert in step 4.
Test: Closing a series of LWs using the "androidback" event.
function openWindows() {
['blue', 'red', 'white'].forEach(function(color) {
var win = Ti.UI.createWindow({backgroundColor: color});
win.addEventListener('androidback', function() {
alert('closing window');
win.close();
});
win.open();
});
}
var mainWindow = Ti.UI.createWindow();
var button = Ti.UI.createButton({title: 'Open windows'});
button.addEventListener('click', openWindows);
mainWindow.add(button);
mainWindow.open();
1. Run application and click "Open windows".
2. Hit the back button. You should see an alert and the window should close.
3. Repeat step 2 for each window until all of them are closed and you are back to the main window.
This is a very important bug!
Can't reproduce using Android 2.2 emulator. I haven't yet been able to locate an Android 2.2 device that can reproduce this.
Mauro added that he reproduced it on a Galaxy Note and GaGa. In my testing, it happens on an HTC Aria. I would guess that all HTCs would do it, but I haven't tested that guess.
QE doesn't have any of the devices listed to reproduce it, and I haven't been able to locate any of them in engineering either.
I might be willing to ship my HTC Aria to you for testing, if I could get it back relatively quickly and if this would prevent this ticket from being prematurely closed.
I would argue the current behavior is correct. The "android:back" event is low level and is always fired when the button is pressed. Calling close() on the window shouldn't be required if it is hosted by its own activity (aka "heavy weight"). The window/activity should be destroyed by Android automatically.
Can we get some more information on the use case from the customer why they need this "back" button callback? This would allow us to provide the best solution. By the way the "android:" events are marked as deprecated in the implementation. We should avoid their usage and look to non-platform specific solutions if possible.
Josh, the "android:back" event is *not* being fired on the emulator when the Back button is pressed. It *is* being fired on the device in that situation. In testcase code, AndroidBackClicked is calling win1.close() unconditionally, but in the actual app, there's a condition in there that keeps the window from closing if an invalid state is detected (for example, incomplete or inconsistent settings). Please do not judge testcase code for this kind of thing, and remember that testcases have been simplified down significantly. You say that the "android:" events are deprecated, and that we should be using a non-platform specific solution. Is there such a thing for handling the press of the Back button? Anyway, I think the real issue here is that the "android:back" event shouldn't fire on the window when it wasn't pressed on the window...it was pressed to remove the keyboard.
Shawn, Thank you for providing the additional information. Looking at the implementation further is using an older style of intercepting these "back" events. It seems if we use the newer API (onBackPressed) the "expected" behavior is seen. So this might be the solution we end up merging in. As for the deprecation to be more specific the name is deprecated. The name is being changed to "androidback" in the next major release. Both will likely remain working for some time to allow developers to transition their code.
Created [PR #2851](https://github.com/appcelerator/titanium_mobile/pull/2851) to modify the new "androidback" event to use Activity.onBackPressed() to dispatch the event.
Josh, how far back in the Ti mobile SDK does "androidback" work (as opposed to "android:back")? I'm currently using 2.1.0.GA. Can I change all of my "android:back"s to "androidback" now?
Shawn, if we back port this change it will likely introduce the new event into the 2.1.x series. This isn't final yet, but we will give a heads up on our action once we decide.
Updated ticket with another test case which verifies the back event is always fired onto the top window of the current activity.
The fix for this issue causes a crash when pressing back on the root activity. Steps to repro: 1. Run this code:
2. Press back twice. Observe NPE. This looks like a simple NP check. Reopening bug.
Created [PR #2865](https://github.com/appcelerator/titanium_mobile/pull/2865) to resolve regression.
Closing as fixed. Tested and verified on: Titanium Studio, build: 2.1.2.201208301612 Titanium SDK, build: 2.1.3.v20120904163110 OS: Mac OS X Lion 10.7.4 Device: HTC Evo (4.0.3) Original test case: Works fine in 2.0.0.GA and 2.1.3.v20120904163110 if event listener changed from "android:back" to "androidback". Test case to verify 'androidback' does not fire when dismissing keyboard. Fail case in 2.0.0.GA: Alert "Back event fired" does not appear after second click the "back" button. Fixed result in 2.1.3.v20120904163110: Alert appears only after second click the "back" button, as expected. Test: Closing a series of LWs using the "androidback" event. Fail case in 2.0.0.GA: Clicking the android "back" button brings you back to the main window without any alerts. Fixed result in 2.1.3.v20120904163110: Getting an alert every time before all windows are closed. Note: All fails were reproducible only on HTC device.