该应用每月有超过20000名活跃用户。
在我最近从.apk的发行版切换到.aab的发行版之后,我开始在crashlytics和googleplay商店上收到随机崩溃的消息。在导致崩溃的构建中没有进行其他重大更改。
崩溃发生在应用程序的第一个屏幕上,同时膨胀xml布局。所讨论的xml布局是一个简单的启动屏幕,它只包含一个图像视图和一个文本视图。imageview是android.widget.imageview,不是compat版本,它显示png图像,而不是矢量图像。图像存在于所有可绘制文件夹变体中:可绘制、可绘制mdpi、…、可绘制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.<init>(ImageView.java:189)
at android.widget.ImageView.<init>(ImageView.java:172)
at android.support.v7.widget.AppCompatImageView.<init>(AppCompatImageView.java:71)
at android.support.v7.widget.AppCompatImageView.<init>(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)
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/center"
android:layout_centerHorizontal="true"
android:src="@drawable/logo" />
崩溃发生在所有android版本上,从4.1.2到9.0。
Android App Bundle introduces Resource Not found crash in Android app
但在这个问题上,作者使用了向量绘制的compat来解决自己的问题。这不是我的案子。
似乎整个资源文件夹不知何故从apk中丢失了,尽管测试这个假设很困难。我无法重现这个问题,所以我必须重新分发应用程序,并等待几天,看看崩溃发生了什么变化,我宁愿不做现场用户测试。
当这个错误发生时,它通常会在同一个设备上连续发生好几次,这让我相信,得到这个错误的用户永远无法启动这个应用程序。另外,我知道一些以前使用过该应用程序的用户已经不能再使用它了。
所以,总结一下:
2应用程序在第一次尝试恢复可绘制资源(一个简单的png图像)时崩溃
三。崩溃不是特定于android版本的;它发生在根设备和非根设备上
是什么导致了这次车祸?有解决办法吗?
==========
在阅读了下面的答案后,我得出结论,唯一的解决方法是检测侧载安装,然后打开活动,没有任何可绘制的资源或风格的链接到谷歌播放和官方网站与旧的学校apk文件。然后用户可以从另一个来源重新下载应用程序。
这是我用来检测应用程序是否被侧载的代码(您可能需要删除)
nativeLibrariesPresent
部分(如果应用程序中没有本机库):
private fun isValidInstallation(): Boolean {
var resourcesPresent: Boolean
try {
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 }
),但它不能使用任何可提取的资源。