[TIMOB-26778] Android: Default "configChanges" settings are lost when overriding root activity in "tiapp.xml"
GitHub Issue | n/a |
---|---|
Type | Bug |
Priority | High |
Status | Closed |
Resolution | Fixed |
Resolution Date | 2019-05-23T20:14:30.000+0000 |
Affected Version/s | n/a |
Fix Version/s | Release 8.0.2 |
Components | Android |
Labels | activity, android, engSchedule, manifest, tiapp.xml |
Reporter | Joshua Quick |
Assignee | Joshua Quick |
Created | 2019-01-29T23:57:50.000+0000 |
Updated | 2019-05-23T20:14:30.000+0000 |
Description
*Summary:*
Titanium generates an "AndroidManifest.xml" when building an Android app. By default, the root activity will be assigned the following "android:configChanges" settings:
* keyboardHidden
* orientation
* fontScale
* screenSize
* smallestScreenSize
* screenLayout
* density
But if you override the root activity in the "tiapp.xml" without setting the "android:configChanges" yourself, then most of the above settings will be lost in the generated "AndroidManifest.xml". Only the below will be remaining.
* screenSize
* density
*Why is this a problem:*
By default, the Android OS will destroy and recreate the window activity when a system event such as an "orientation" change occurs. Since "android:configChanges" such as "orientation" is lost in this case, rotating the app while its loading at the splash screen will cause the app to reload every time you change orientation.
Also note that app developers often do override the root activity in the "tiapp.xml" in order to set up their own custom intent-filters or to apply their own theme to the splash screen (such as a translucent status bar). So, this is a commonly done.
*Steps to reproduce:*
1. Create a Titanium app with project name "MyApp".
2. Insert the below XML into your "tiapp.xml".
3. Set up the "app.js" as shown below. It should be blank.
4. Build and run the app.
5. Verify the following gets logged on startup:
MyApp 1.0 (Powered By Titanium ...)
6. Rotate the app from portrait to landscape or vice-versa.
7. Notice the MyApp 1.0 (Powered By Titanium ...)
gets logged again. _(This means the app restarted. This is bad.)_
8. Go to app project folder: ./build/android
9. Open the "AndroidManifest.xml" file.
10. Look for an XML <activity/>
element with name ".MyappActivity".
11. Notice that the "android:configChanges" attribute only has settings "screenSize|density"
defined. _(This is the issue.)_
app.js
// Keep this file blank.
tiapp.xml
<?xml version="1.0" encoding="UTF-8"?>
<ti:app xmlns:ti="http://ti.appcelerator.org">
<android xmlns:android="http://schemas.android.com/apk/res/android">
<manifest>
<application>
<activity android:name=".MyappActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
</android>
</ti:app>
*Expected Result:*
Titanium's default "android:configChanges" listed up above should always be included when overriding the root activity... *unless* the app developer sets the "android:configChanges" themselves, in which case we should honor the developer's settings.
*Note:*
This used to be a bigger issue in Titanium 7.4.1 and below since the "app.js" would have been re-executed every time you change orientation on startup.
In 7.5.0 and above, Titanium loads "ti.main.js" instead which is lighter-weight and its call to require("app.js")
would have no-op'ed upon re-execution of "ti.main.js" since the "app.js" was already cached.
PR (master): https://github.com/appcelerator/titanium_mobile/pull/10884
PR (8.0.x): https://github.com/appcelerator/titanium_mobile/pull/10900
FR passed. jenkin is failing test. waiting for resolving jenkin failure to merge
Verified the fix on SDK 8.1.0.v20190523084559 and 8.0.2.v20190522031334. Works as expected.