Android пытается сослаться на старое имя пакета получателя Broadcast после обновления приложения OTA - PullRequest
4 голосов
/ 09 марта 2020

Я работаю над пользовательской ОС на базе AOSP 8.1. У меня есть системное приложение (в / system / priv-app) с экспортированным широковещательным приемником. Это означает, что он может принимать Интенты за пределами приложения. Если я произвожу рефакторинг широковещательного получателя, например, поменяю его местоположение пакета или имя класса и установлю обновленный APK с помощью "adb install -r ...", все отлично работает, и широковещательный получатель получит намерение.

Однако если Я создаю OTP-изображение с новым приложением (APK + VDEX + ODEX) и запускаю его sh из восстановления, приложение вылетает, поскольку Android все еще пытается сослаться на старый класс приемника вещания:

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]]

Он пытается сослаться на com.example.app.receiver.ExampleReceiver, но новый класс - com.example.app.receiver.NewReceiver. Старый где-то «кэшируется».

Я могу смоделировать ту же проблему, перемонтировав раздел / system RW и используя adb push ... для замены новых файлов APK, ODEX и VDEX. Как ни странно, если я удаляю файлы ODEX и VDEX из / system, все прекрасно работает, так как, очевидно, этот акт заставляет Android снова проанализировать APK.

Как я понимаю PackageManager Системное приложение должно иметь возможность определять, когда приложение обновляется, и анализировать экспортированные части (например, классы для широковещательных приемников и действий). К сожалению, этого не происходит.

Я также предполагаю, что это происходит после OTA, когда Android показывает «Оптимизация приложения xxx / xxx», но здесь этого не происходит. Как этот процесс должен запускаться?

Соответствующая информация: http://www.programmersought.com/article/8031444654/

1 Ответ

0 голосов
/ 24 апреля 2020

Android исходный код PackageManagerService имеет следующие строки:

mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
... some other code

if (mIsUpgrade && !onlyCore) {
                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
                ... cache clearing logic
                ver.fingerprint = Build.FINGERPRINT;
}

То есть, кеши кода будут очищаться при изменении отпечатка сборки. Эта проблема может возникнуть из-за того, что ваш OTA-пакет имеет тот же отпечаток, что и система, в которой он установлен.

Проверьте ваш make-файл и убедитесь, что вы генерируете уникальный отпечаток для каждой сборки.

Значение Fingerprint может находится в файле "system / buildprops". Так что вы можете проверить, в этом ли проблема.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...