Приложение иногда вылетает с ресурсом $ NotFoundException после переключения на дистрибутив Android-приложений.

Приложение имеет более 20000 активных пользователей в месяц. Он был доступен в Google Play в течение нескольких месяцев. После того, как я недавно переключился с дистрибутива с .apk на дистрибутив с .aab, я начал получать случайные сбои на crashlytics и магазине Google Play. Других существенных изменений в сборке, которая привела к сбоям, не было.

Сбой происходит на самом первом экране приложения при надувании макета XML. Рассматриваемый макет xml представляет собой простой экран-заставку, который содержит только одно представление изображения и одно представление текста. Imageview - это android.widget.ImageView, а не версия для сравнения, и оно отображает PNG-изображение, а не векторное изображение. Изображение присутствует во всех доступных для рисования папках: drawable, drawable-mdpi, ..., drawable-xxxhdpi.

Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.company/com.company.ui.splash.SplashActivity}: android.view.InflateException: Binary XML file line #14: Binary XML file line #14: Error inflating class ImageView
          at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
          at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
          at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
          at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
          at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
          at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
          at android.os.Handler.dispatchMessage(Handler.java:106)
          at android.os.Looper.loop(Looper.java:193)
          at android.app.ActivityThread.main(ActivityThread.java:6669)
          at java.lang.reflect.Method.invoke(Method.java)
          at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:495)
          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

   Caused by android.view.InflateException: Binary XML file line #14: Binary XML file line #14: Error inflating class ImageView


   Caused by android.view.InflateException: Binary XML file line #14: Error inflating class ImageView


   Caused by android.content.res.Resources$NotFoundException: Drawable (missing name) with resource ID #0x7f0800b2


   Caused by android.content.res.Resources$NotFoundException: Unable to find resource ID #0x7f0800b2
          at android.content.res.ResourcesImpl.getResourceName(ResourcesImpl.java:255)
          at android.content.res.ResourcesImpl.loadDrawableForCookie(ResourcesImpl.java:785)
          at android.content.res.ResourcesImpl.loadDrawable(ResourcesImpl.java:631)
          at android.content.res.Resources.loadDrawable(Resources.java:897)
          at android.content.res.TypedArray.getDrawableForDensity(TypedArray.java:955)
          at android.content.res.TypedArray.getDrawable(TypedArray.java:930)
          at android.widget.ImageView.(ImageView.java:189)
          at android.widget.ImageView.(ImageView.java:172)
          at android.support.v7.widget.AppCompatImageView.(AppCompatImageView.java:71)
          at android.support.v7.widget.AppCompatImageView.(AppCompatImageView.java:67)
          at android.support.v7.app.AppCompatViewInflater.createImageView(AppCompatViewInflater.java:181)
          at android.support.v7.app.AppCompatViewInflater.createView(AppCompatViewInflater.java:105)
          at android.support.v7.app.AppCompatDelegateImplV9.createView(AppCompatDelegateImplV9.java:1035)
          at android.support.v7.app.AppCompatDelegateImplV9.onCreateView(AppCompatDelegateImplV9.java:1092)
          at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:772)
          at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730)
          at android.view.LayoutInflater.rInflate(LayoutInflater.java:863)
          at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
          at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
          at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
          at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
          at android.support.v7.app.AppCompatDelegateImplV9.setContentView(AppCompatDelegateImplV9.java:287)
          at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:139)
          at com.company.ui.splash.SplashActivity.onCreate(SplashActivity.java:58)
          at android.app.Activity.performCreate(Activity.java:7136)
          at android.app.Activity.performCreate(Activity.java:7127)
          at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
          at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
          at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
          at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
          at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
          at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
          at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
          at android.os.Handler.dispatchMessage(Handler.java:106)
          at android.os.Looper.loop(Looper.java:193)
          at android.app.ActivityThread.main(ActivityThread.java:6669)
          at java.lang.reflect.Method.invoke(Method.java)
          at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:495)
          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

Часть XML-файла, которая вызывает сбой:


Сбой происходит на всех версиях Android, от 4.1.2 до 9.0.

Помимо других устройств, я также получил сбои от Google Pixel и Nexus 5X, оба без рута. Мне довелось владеть обоими устройствами. Я пытался установить на них свое приложение из Google Play и из сторонних сервисов, таких как pureapk, но я не смог воспроизвести сбой.

Вопрос похож на . В Android App Bundle вводится сбой Resource Not found в приложении Android , но в этом вопросе автору удалось решить свои проблемы с помощью векторного рисованного компата. Это не мой случай.

Похоже, что вся папка ресурса отсутствует в apk, хотя проверить это предположение сложно. Я не могу воспроизвести проблему, поэтому мне придется перераспределить приложение и подождать пару дней, чтобы увидеть, как изменился сбой, и я бы не хотел проводить тестирование на живых пользователях.

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

Итак, подведем итог:
1. Crash начал появляться сразу после перехода на распределение пакетов приложений для Android в Google Play
2. Приложение аварийно завершает свою работу при первой попытке восстановить нарисованное ресурс - простое изображение в формате png
3. Авария не зависит от версии Android; это происходит как на рутованных, так и на некорневых устройствах
4. Если пользователь получает эту ошибку, он, вероятно, застрянет навсегда

Что является причиной этого сбоя? Есть ли обходной путь?

==========

Обновление: Прочитав ответ ниже, я пришел к выводу, что единственный обходной путь - это обнаружите установку с боковой загрузкой, а затем откройте активность без каких-либо доступных ресурсов или стилей со ссылками на Google Play и официальный сайт с файлом старой школы apk. Затем пользователь может повторно загрузить приложение из другого источника.

Это код, который я использую, чтобы определить, было ли загружено приложение (вам может потребоваться удалить часть nativeLibrariesPresent, если в вашем приложении нет собственных библиотек):

private fun isValidInstallation(): Boolean {
    var resourcesPresent: Boolean
    try {
        // Any drawable id will suffice
        val logo = ResourcesCompat.getDrawable(resources, R.drawable.logo_white, null)
        resourcesPresent = logo != null
    } catch (e: Exception) {
        resourcesPresent = false
    }

    if (!resourcesPresent) {
        Timber.e("No drawable resources detected inside app")
    }

    var nativeLibrariesPresent: Boolean
    try {
        val nativeLibraryDir = File(applicationInfo.nativeLibraryDir)
        val primaryNativeLibraries = nativeLibraryDir.list()
        nativeLibrariesPresent = primaryNativeLibraries.isNotEmpty()
    } catch (e: Exception) {
        nativeLibrariesPresent = false
    }

    if (!nativeLibrariesPresent) {
        Timber.e("No native libraries detected inside app")
    }

    return resourcesPresent && nativeLibrariesPresent
}

Вы захотите Запустите альтернативное действие, прежде чем что-то делать внутри основного действия:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    if (!isValidInstallation()) {
        val intent = Intent(this, InvalidInstallationActivity::class.java)
        startActivity(intent)
        finish()
        return
    }

    setContentView(R.layout.activity_main)
    ...

InvalidInstallationActivity может использовать XML-макет и может использовать строковые ресурсы, если вы не разделяете свой aab по языку (language { enableSplit = false }), но это не может использовать никакие доступные ресурсы.

25
задан Alexey 1 July 2019 в 10:10
поделиться