Updated Information: A RELATED ISSUE CAN also effect ALL normal android applications that are just a simple upgrade in that your newly upgraded app WON'T be upgraded properly on the device. The client running your app, will revert to the prior version and/or prior data.
This doesn't normally crash the app, like the original issue (discussed below)-- but your client will be wondering why your upgrade didn't change anything... So my recommendation is to apply the application backup disabling fix listed below so you don't run into either of these issues.
This new issue effects:
- Android 6 and up devices.
- Any application upgrade/update.
- Does not affect a brand new installs on a device that has never had your application. Will affect devices that deletes your app and later re-installs. So this is doesn't affect a new customer, but will effect any exist customers.
The issue described below has been patched in v3.01 of the Android Runtimes, technically it should be fixed. However as I suspected and we have confirmed recently; the root issue actually can cause other related issues, and it is unpatched and with no eta for its solution, hence this updated blog post with a work around...
For those who don't want to read the hows; the information you need is:
- This is an Android only issue; iOS doesn't have this issues.
- This is an Android 6.0 and higher issue.
- Fresh new installs will not have this issue, only devices that have had a old version on it.
- The main issue only occurs when you are upgrading from 2.x to 3.0 application. (See update info above, related issue is different) So new apps that started as 3.0 won't have this issue; and apps that stay 2.x won't have issues. Only apps upgrading from 2.x to 3.x will have this issue on clients that are upgrading.
- This is a conflict between a file (in 2.5) that was changed into a folder (in 3.0).
- This is in the cases I've seen are caused by Google Auto-Backup auto restoring files/settings on the application installation.
If your app is a upgrade from 2.x to 3.x and you are wanting to release it to the Amazon or Google play store; don't do it -- for you and your customers sanity. The app will crash on startup and you will be left scratching your head as to why it works (new customers) sometimes and why it doesn't (existing customers).
Progress is aware of the issue and how critical it is; so I would guess we should see a patch shortly (released in 3.01 ), however if you are under the gun and must release today; I have a fix that should also work, see end of blog post. 😉
The longer story; Brad Martin pinged me late last week because he ran into this issue. He is one of the awesome members of the nStudio team, along with myself and Nathan Walker. So I stopped what I was doing and began to help him out. By the time we finished a couple hours of debugging (it was LATE Friday night) we had determined a number of things, but not the underlying issue.
We figured out that on what appeared to be a fully clean device it would still crash.
What we knew
- It didn't matter if it was Android @ release or Android @ next runtimes. (Wasn't runtime dependent. Included cleaning this multiple times)
- We knew his tns-core-modules was 100% correct and it wasn't related to 3.00 or 3.01
- We knew his his tns-core-modules & widgets matched 100% a clean version on another machine (no npm corruption)
- We knew the .APK generated worked on all the emulators fine.
- We were pretty sure LiveSync couldn't be causing the problem (we nuked it several times and installed via a couple different methods)
- The platforms / src did NOT have that file in it, so no way the built APK could even get it.
Alexander Vakrilov (from the NS team) noticed the call stack was pointing to the old 2.5 style.js file. I knew the 2.5 style.js file couldn't be coming from the freshly built apk and it wasn't in the LiveSync folder; so I actually thought that maybe there must be two different ways this error could appear, one of them would be someone upgrading and having the extra style.js in the node_modules/tns-core-modules, the other would be what Brad was running into.
Then Brad confirmed today that the style.js file was present in his stack trace. That actually confused me quite a bit, because with the data we had above, that didn't make any real sense. We had a fully clean APK without that file in it. How was the device getting it? We had manually deleted the livesync folder and even verified it was empty before we ran the app. But the app would still crash with that call stack. Color me confused...
So I took some time to scan the NativeScript android runtime source code for its livesync stuff. I had seen the code before, but I wanted to make sure nothing major changed in 3.0. I couldn't find anything other than what I expected to see. No "other" LiveSync folders, so I was still confused...
So how is the device getting this file on it???
So I thought for a few minutes; in my best Sherlock Holmes voice; "When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth"
- Appears to be primarily happening on Real Android devices.
- Clear Data, works if done after the install.
- Doesn't matter how the app is installed.
- LiveSync doesn't appear to be responsible
- The generated APK is 100% correct.
If finally hit me; some sort of external force is causing the issue. I was so focused on NativeScript; I didn't think about the other items on a REAL DEVICE. It hit me like a 2x4... What is one thing that Real devices typically have over emulators??? A Google account is normally setup and syncing... So I told Brad...
- De-install app (again)
- Nuke the LiveSync Folder (just to make sure)
- Turn on Airplane Mode (What a trouper he is, didn't even ask me why!)
- do a TNS run
App worked! I'm like AWESOME, Brad is like WTF! I don't blame him, I didn't tell him what the test was for, and so he had no idea what I was testing for. And the poor guy has been not only doing my tests, but he had also put in a lot of time himself testing things... He just had the surprising fact that it actually worked on his phone when in Airplane mode. Me, I'm like I know what it is...
Android 6.0 Introduced a cool features called Auto-Backup; this nice feature backs up your data and files from your app. Well unfortunately for us NativeScript users; NativeScript stores its .JS files in the /files/app folder. Guess what one of the folders that is AUTO BACKED UP? /files folder...
What is happening is there is a cool setting with your device, that will Automatically restore application settings when you re-install a application.
When you install app; it detects the name is the same, it restores the /files/
folder (adding any MISSING files) which then puts the old 2.5 styles.js file into the folder. And then NativeScript attempts to load this file, and crashes...
My fix:
- Open your app/App_Resources/Android/AndroidManifest.xml file change or set/add the key
allowBackup
in your <Application> tag to "false" and thetools:replace
. So it should look like:
<application android:name="com.tns.NativeScriptApplication" android:icon="@drawable/icon" android:label="@string/app_name" android:theme="@style/AppTheme" android:allowBackup="false" tools:replace="android:allowBackup" >
Then in the Manifest section you need to add the
xmlns:tools
namespace entry:<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="__PACKAGE__" android:versionCode="1" android:versionName="1.0">
By disabled the backup; you also disable the auto-restore of just this app's setting and files... (Thanks Brad for confirming this works!)
Hello,
i think this happend before too from 2.2 version to 2.4/2.5 version but couldn't find problem so most likely there was similar change between those versions, after upgrade app was crashing but couldn't replicate it after some install/reinstall newer version, it was working normally :/
It is possible, now that we understand what is going on. Most devs won't see it because their emulator isn't hooked up to the backup service. And I know I'm one of the weird ones that has their backup disabled on the phone, so I never would have seen it. I'm just glad that we have visibility of the issue now, and Progress can fix it.
I was able to reproduce this on 7.0 android by manually making google backup on adb shell.
When I changed AndroidManifest.xml allowBackup="false", I got this error message:
Manifest merger failed : Attribute application@allowBackup value=(false) from AndroidManifest.xml:24:3-30
is also present at [:Common-2017.1.504-dev-release:] AndroidManifest.xml:11:18-44 value=(true).
Suggestion: add 'tools:replace="android:allowBackup"' to element at AndroidManifest.xml:6:5-15:19 to override.
By adding this xmlns:tools="http://schemas.android.com/tools" to manifest tag and this tools:replace="android:allowBackup" to application tag. It fixed error mentioned above and application starts correctly.
Hello,
Can you be more specific how exaclty are you setting the android:allowBackup="false" since I'm not able to `tns build android` or `npm run start-android-bundle` with that change. I'm getting
"Manifest merger failed : Attribute application@allowBackup value=(false) from AndroidManifest.xml:25:3-30
is also present at [:Chart-2017.1.504-dev-release:] AndroidManifest.xml:11:18-44 value=(true).
Suggestion: add 'tools:replace="android:allowBackup"' to element at AndroidManifest.xml:6:5-10:19 to overri
de."
Thanks
Yeah, if any of the other plugins has an `android:allowBackup` then you have to the tools:replace to override other manifests. Your error message is telling you that the Chart-2017 (probably from Telerik-UI) has that setting.
This happens also on android 5, luckily the fix works as a charm.
However, if the app was already installed before the `android:allowBackup="false"` fix it won't help.
If you didn't deploy to the public (in my case) you can change the app id.
This works only if you don't have NativeScript-Telerik-UI or Pro-UI. Pro-UI unfortunately breaks the ability to override the android:allowBackup fix. (At this moment, there might be more plugins that break it... Instead the solution is to change the directories allowed to be backed up.
Actually, my app uses NativeScript-Pro-UI (3.1.4), and it works.