Подтвердить что ты не робот

Сбой при самообновлении APK (класс компонента не существует)

Я работаю над системным приложением, которое обновляет его, загружая apk и устанавливая его с помощью метода PackageManager installPackage().

Я получаю следующее исключение:

Fatal Exception: java.lang.IllegalArgumentException: Component class com.myapp.package.receivers.SomeOldReceiver does not exist in com.myapp.package
           at android.os.Parcel.readException(Parcel.java:1544)
           at android.os.Parcel.readException(Parcel.java:1493)
           at android.content.pm.IPackageManager$Stub$Proxy.setComponentEnabledSetting(IPackageManager.java:3420)
           at android.app.ApplicationPackageManager.setComponentEnabledSetting(ApplicationPackageManager.java:1492)
           at com.myapp.package.utils.AndroidUtils.enableDisableComponent(SourceFile:113)
           at ...

Компонент "SomeOldReceiver" не существует в обновленном apk.

Кажется, что выполняется "старый" код из существующего APK (вызывается его приложение onCreate()), пытающееся получить доступ к "новому" манифесту, который существует в обновленном APK, и не может найти "старый" приемник (возможно ли это?).

Мое приложение также прослушивает PACAKGE_ADDED и PACKAGE_REMOVED намерения.

Этот сбой происходит на относительно большом проценте пользователей.

Любое предложение или подсказка о том, почему эта ошибка происходит и как ее исправить, будет очень признательна.

4b9b3361

Ответ 1

Существуют различные способы обновления APK. Я не уверен, какой из них вы используете. Я столкнулся с подобной проблемой.. и это было связано с тем, что приложение имеет несколько экземпляров во время обновления. Вы можете сделать приложение одним экземпляром или просто убедитесь, что не запущены старые экземпляры. Надеюсь, это поможет.

Ответ 2

Начиная с версии JELLY_BEAN: Вызовы PackageManager.setComponentEnabledSetting теперь будут вызывать IllegalArgumentException, если данное имя класса компонента не существует в манифесте приложения.

Это объясняет, почему этот сбой происходит у большого процента пользователей.

Ответ 3

Извините, я не могу подтвердить, будет ли это какой-либо помощи, так как я сам ее не тестировал.

Возможно, вы можете попробовать отключить свой "SomeOldReceiver" (или любые другие компоненты, которые могут быть вызваны установкой нового пакета), сделав вызов setComponentEnabledSetting() перед вызовом installPackage()?

Логически, это может потребовать от вас создать промежуточную версию вашего приложения (которая добавила вызов setComponentEnabledSetting() до installPackage() и все еще должна иметь "SomeOldReceiver" в своем манифесте), чтобы сначала обновить старую версию. Затем вы можете обновить эту версию до вашей реальной обновленной версии с удаленным "SomeOldReceiver" .