I'm working on a custom AOSP 8.1 based OS. I have a system app (in /system/priv-app) with an exported broadcast receiver. This means it can accept Intents from outside the application. If I refactor the broadcast receiver, e.g. change its package location or class name and install the updated APK with "adb install -r ...", everything works great and the broadcast receiver receives the intent.
However if I produce an OTP image with the new app (APK + VDEX + ODEX) and flash it from the recovery, the app crashes as Android is still trying to reference the old broadcast receiver class:
AndroidRuntime: java.lang.RuntimeException: Unable to instantiate receiver com.example.app.receiver.ExampleReceiver: java.lang.ClassNotFoundException: Didn't find class "com.example.app.receiver.ExampleReceiver" on path: DexPathList[[zip file "/system/priv-app/ExampleApp/ExampleApp.apk"],nativeLibraryDirectories=[/system/priv-app/ExampleApp/lib/arm, /system/lib, /vendor/lib, /system/lib, /vendor/lib]]
It tries to reference com.example.app.receiver.ExampleReceiver
, but the new class is com.example.app.receiver.NewReceiver
. The old one is "cached" somewhere.
I can simulate the same problem by remounting the /system partition RW and using adb push ...
to replace the new APK, ODEX and VDEX files. Strange enough if I delete the ODEX and VDEX files from /system, everything works great as apparently this act forces Android to parse again the APK.
As I understand the PackageManager
system app should be able to detect when an app is updated and parse the exported parts (like classes for broadcast receivers and activities). Unfortunately this doesn't happen.
I also guess that's what happens after OTA when Android shows "Optimizing app xxx/xxx", but this doesn't happen here. How is this process supposed to be triggered?
Relevant information: http://www.programmersought.com/article/8031444654/