Observed this very strange behavior with Android application. Approximate scenario:
- Version A installed on the device
- Application works alright
- Version B installed on the device (B > A)
- Application works alright
- Device shuts down due to battery drain
- Device turned on
- Version A of the application runs on the device again
- The application isn’t distributed through Google Play, but installed on-premise via USB connection (NOTE: the application runs in production; it’s not installed through AndroidStudio).
- Android 5.1 (API 22)
I guess I’ve got two questions:
- Why the device cached the older version of the APK (and where did it cache it)?
- Under which circumstances can applications roll back to previous versions like that?
Edit (more information):
- It looks like after the APK is rolled back, the application loses some permissions (maybe even all). Functionality that worked before the roll-back stops working due to SecurityException being thrown from Android’s APIs. This happens even though this version of Android doesn’t have runtime permissions yet!
- After browsing tablet’s filesystem, I indeed see several app’s APKs residing under similar paths:
My current hypothesis is that battery drain causes the tablet to “reset” its state (for example, the clock is also reset), and when it’s powered again it confuses between app’s APKs and loads the wrong one.
However, I have no clue why would it do that, or how to prevent this behavior.
If you are using Android Studio 3.5+, then instead of instant run, you are likely using Apply Changes.
This has a different way of shipping changes to the device, without rewriting the apk, so make a lot of sense that after rebooting, the apk that you will run if you execute your app directly on the device, has nothing to do with the one that was running before
Instant Run and re-architectured and implemented from the ground-up a
more practical approach in Android Studio 3.5 called Apply Changes.
Apply Changes uses platform-specific APIs from Android Oreo and higher
to ensure reliable and consistent behavior; unlike Instant Run, Apply
Changes does not modify your APK.
This lists user installed packages:
adb shell cmd package help pm list packages -f -U -3 --show-versioncode
And then fully uninstall before reinstalling:
adb uninstall com.myapp
With instant run and not applying the patch APK (see the
pm help output), this might run the base APK. This does not roll-back anything, but it’s likely the one APK without the other one APK overloaded (Android Studio might automate the application of the hot-patch, but at boot time this might not be the case). Not using instant run removes these patch update APK; and when there is only one APK, there is nothing else to run.
Why the device cached the older version of the APK (and where did it cache it)?
The trick here is in the version code. When you install a new version, make sure the new version has a different version code. The Android OS uses version codes to differentiate between different versions of the same APK so, this would work.
It’s not really clear why this rollback happens. This is obviously a strange device-specific problem but nonetheless, a ton of factors could be responsible including the device’s default installer, storage/cache settings, device memory, viruses, etc.
I hope this helps. Merry coding!