Android App Bundle 在 Android 应用程序中引入资源未找到崩溃
Android App Bundle introduces Resource Not found crash in Android app
通过使用 Android 的新 Android App Bundle,我的 Google Play 商店应用中的 2 个收到 Resource Not Found
错误。
这是其中一个应用程序的 fabric 堆栈跟踪:
Unable to start activity ComponentInfo{/com.Lastyear.MainActivity}: android.content.res.Resources$NotFoundException: File res/drawable/abc_item_background_holo_dark.xml from drawable resource ID #0x7f08002c
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2377)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2429)
at android.app.ActivityThread.access0(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1342)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5363)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:828)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:644)
at dalvik.system.NativeStart.main(NativeStart.java)
build.gradle
依赖关系:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
testImplementation 'junit:junit:4.12'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:customtabs:27.1.1'
implementation 'com.android.support:cardview-v7:27.1.1'
implementation 'com.squareup.picasso:picasso:2.5.2'
implementation 'com.android.support:palette-v7:27.1.1'
implementation 'com.afollestad.material-dialogs:core:0.9.6.0'
implementation 'com.jakewharton:butterknife:8.8.1'
implementation 'com.github.bumptech.glide:glide:3.7.0'
implementation 'com.android.support:design:27.1.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
implementation 'com.github.hotchemi:android-rate:1.0.1'
implementation 'com.hannesdorfmann.smoothprogressbar:library:1.0.0'
implementation 'com.android.support:palette-v7:27.1.1'
implementation 'com.google.android.gms:play-services-ads:15.0.1'
implementation 'com.muddzdev:styleabletoast:1.0.9'
implementation 'com.github.GrenderG:Toasty:1.2.5'
implementation 'com.hannesdorfmann.smoothprogressbar:library:1.0.0'
implementation 'com.wang.avi:library:2.1.3'
implementation 'com.github.medyo:fancybuttons:1.8.4'
implementation 'com.irozon.sneaker:sneaker:1.0.1'
implementation 'com.sdsmdg.tastytoast:tastytoast:0.1.1'
implementation 'de.hdodenhof:circleimageview:2.2.0'
implementation 'com.github.barteksc:android-pdf-viewer:2.8.2'
implementation 'com.getkeepsafe.taptargetview:taptargetview:1.11.0'
implementation('com.crashlytics.sdk.android:crashlytics:2.6.8@aar') {
transitive = true;
}
implementation 'petrov.kristiyan:colorpicker-library:1.1.8'}
还有一件事,它只发生在 Android 4 操作系统上,而不发生在较新版本的 Android 上。我发现其他应用程序也有与 Resource Not Found
相同的问题,在使用 Android 的应用程序包之前不存在。库或代码中是否存在问题,或者是因为 Android 的应用程序包的测试版?
我还发现了导致崩溃的可绘制资源:-
我觉得这个问题也和这个问题有关:Resource Not Found error res/drawable/abc_switch_thumb_material.xml after adding SwitchCompat in Android App Bundle
问题可能是您的应用已被旁加载,即未通过 Play 商店安装,并且在这些设备上手动安装了不兼容的 APK。
由于迁移到 Android App Bundle 后仅在 Android 4 台设备上发生这种情况,我在添加后发现了一种方法:-
public class App extends Application {
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); }
在build.gradle中:-
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
如本 post 中所述:-
关于第二个问题:-
Resource Not Found error res/drawable/abc_switch_thumb_material.xml after adding SwitchCompat in Android App Bundle
因为所有 Android 版本都发生了这种情况。我旁加载了 Apk 并且能够在 logcat 中重现相同的错误,所以这只能通过从我的项目中删除 SwitchCompat 来修复,我知道它是一个临时修复并且 Google 肯定应该对此做些什么这样至少在旁加载 apk 后不会发生崩溃,也许重定向到 Play 商店会是更好的选择。但是迁移到 Android App Bundle 后应用程序崩溃肯定会影响应用程序的稳定性,因为许多用户经常这样做。
这几乎可以肯定是用户通过 P2P 共享程序共享(旁加载)应用程序,或者将 APK 上传到网络,然后其他用户从网络下载和安装。
人们习惯于处理非 Android App Bundle 应用程序只是传输和共享主 APK。但是您的 App bundle 应用程序有很多 "split APKs" 用于资源之类的东西,这就是节省大小的方式。您可以阅读有关此过程的全部内容 on the help page。如果用户安装了主 APK 而没有安装正确的拆分 APK,那么应用程序第一次尝试加载资源时会发生 "Resources Not found" 崩溃。
如果你想支持用户侧载你的应用程序和主 APK,你可以尝试检测这种情况并向用户显示一条消息(不使用任何资源),内容为 "Please install from Google Play"。或者您可以决定不支持以这种方式共享 APK 的用户。
我怀疑从长远来看 运行 网站和 P2P 共享程序会更好地正确共享此类 APK,所以我不会花太长时间担心它。
如果您发现这种情况在较低的 Android 版本上更频繁地发生,这可能不是由于较低的 Android 版本中的错误。相反,这可能是因为在用户通常使用 P2P 共享应用程序的国家(例如印度),用户也更有可能使用旧版手机。
接受的答案绝对正确 - root of this issue 是 APK 文件的旁加载。
尽管如此,很多人仍在寻找解决方法,询问如何正确处理这种情况。
在我的应用程序中,我执行了以下操作:
创建名为 pixel.png
的 1x1 图像并将其放入以下所有文件夹:drawable-mdpi
、drawable-hdpi
、drawable-xhdpi
、drawable-xxhdpi
, drawable-xxxhdpi
.
创建显示静态消息的简单 Activity
,例如
This copy of app is corrupted and can't be launched.
Please, install original version from Google Play
然后简单地从包裹在 try/catch
子句中的 Activity.onCreate()
调用 getDrawable(R.drawable.pixel)
。
如果捕获到异常,只需完成当前 Activity
并从步骤 #2 开始另一个。
完成!
这个解决方案效果很好,现在我什至有来自 Firebase Analytics 的数据证实了这一点。
从 46k 的新用户(事件 first_open
)中,有 266 位用户收到此错误(已被捕获),221 位用户单击了导致 Google 播放的按钮。
这是我的源代码(也可用on GitHub):
DrawablesValidator.java
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Space;
import android.widget.TextView;
import android.widget.Toast;
public class DrawablesValidator extends Activity {
public static void ensureDrawablesValid(@NonNull Activity activity) {
try {
// IMPORTANT create 1x1 image named pixel.png and put it to all folders
// drawable-mdpi
// drawable-hdpi
// drawable-xhdpi
// drawable-xxhdpi
// drawable-xxxhdpi
activity.getDrawable(R.drawable.pixel);
} catch (Resources.NotFoundException ex) {
// NOTE optionally, report exception to Crashlytics or just an event to Analytics
activity.finish();
activity.startActivity(new Intent(activity, DrawablesValidator.class));
}
}
// NOTE don't care about translations of text messages here, don't put them to strings.xml
// we assume, that if user is smart enough to get APK from outside and install it,
// then user will definitely understand few messages in English :)
@SuppressLint("SetTextI18n")
@Override
protected void onCreate(Bundle state) {
super.onCreate(state);
int dp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics());
int dp8 = dp * 8;
int dp16 = dp * 16;
int dp80 = dp * 80;
LinearLayout root = new LinearLayout(this);
root.setOrientation(LinearLayout.VERTICAL);
root.setGravity(Gravity.CENTER_HORIZONTAL);
root.setPadding(dp80, dp16, dp80, dp16);
Space spaceTop = new Space(this);
TextView title = new TextView(this);
title.setPadding(0, dp8, 0, dp8);
title.setTextSize(20);
title.setText("Re-install app");
TextView message = new TextView(this);
message.setPadding(0, dp8, 0, dp8);
message.setTextSize(16);
message.setText("This copy of app is corrupted and can't be launched." +
"\n\n" +
"Please, install original version from Google Play");
Button button = new Button(this);
button.setPadding(dp16, dp8, dp16, dp8);
button.setText("Continue");
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + getPackageName())));
} catch (Exception ex) {
Toast.makeText(getApplicationContext(), "Can't open Google Play", Toast.LENGTH_SHORT).show();
}
}
});
Space spaceBottom = new Space(this);
int wc = ViewGroup.LayoutParams.WRAP_CONTENT;
int mp = ViewGroup.LayoutParams.MATCH_PARENT;
root.addView(spaceTop, lp(0, 0, 1, -1));
root.addView(title, lp(wc, wc, 0, -1));
root.addView(message, lp(mp, wc, 0, -1));
root.addView(button, lp(wc, wc, 0, Gravity.END));
root.addView(spaceBottom, lp(mp, wc, 1, -1));
setContentView(root);
}
private LinearLayout.LayoutParams lp(int width, int height, int weight, int gravity) {
LinearLayout.LayoutParams result = new LinearLayout.LayoutParams(width, height);
result.weight = weight;
result.gravity = gravity;
return result;
}
}
您可以查看 用户共享(侧载)来自 play console 的应用程序
登录播放控制台 select 您发布应用程序包而不是 apk 的应用程序。
Select Android Vital -> ANRs & crashes 然后点击 crashes 选项卡。
select 从播放安装
这有点晚了,但是 Google 为 Sideloading crash prevention
引入了新的 API,它允许您检测使用 Android 构建的应用程序的不完整安装应用程序包。
For example, consider an app that uses Android App Bundles to optimize
app download size using split APKs. When a user downloads the app from
the Google Play store, it ensures that the device downloads and
installs the complete set of split APKs required to run that app on
that particular device. When you bypass Google Play to sideload an
app, the platform does not have sufficient data to validate the app
install, and proper functionality of the app is not guaranteed.
首先在您的项目中包含 Play Core 库 1.6.0 或更高版本。
在您的应用项目的 build.gradle 文件中包含以下内容:
buildscript {
dependencies {
...
// Use bundletool 0.9.0 or higher when building with the
// Android Gradle plugin.
classpath 'com.android.tools.build:bundletool:0.9.0'
}
}
您可以使用以下 3 种方法中的一种
1) Register checks through the manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapplication" >
<application
...
android:name="com.google.android.play.core.missingsplits.MissingSplitsDetectingApplication" >
</application>
...
</manifest>
2) Apply checks in a custom Application class
public class MyCustomApplication extends Application {
@Override
public void onCreate() {
if (MissingSplitsManagerFactory.create(this).disableAppIfMissingRequiredSplits()) {
// Skip app initialization.
return;
}
super.onCreate();
...
}
}
3) Apply checks to content providers
public class ExampleProvider extends ContentProvider {
@Override
public boolean onCreate() {
if (MissingSplitsManagerFactory.create(getContext()).isMissingRequiredSplits()) {
// Skip provider initialization.
return false;
}
super.onCreate();
...
}
}
阅读更多:https://developer.android.com/reference/com/google/android/play/core/release-notes?hl=en-419#1-6-0
对于内部测试,我们无法加载 aab 文件 apks。在发布到生产环境之前,只有两种方法可以为用户提供 apk。
1) 我们必须给出 universal.apk 文件检查目的
java -jar bundletool-all-0.12.0.jar build-apks --bundle=(构建路径)debug.aab --output=(输出路径)debug.apks --模式=通用
2) 我们必须将 aab 文件上传到 playstore,然后首先发布内部测试,如果一切正常,然后发布它。
我遇到了同样的问题,我的应用程序因无法从资源中找到字体和音频文件而崩溃。问题是我在 Gradle-wrapper.properties 中将 Gradle URL 从 4.10.1 更新到 5.6.4 但没有更新库。当我恢复到 4.10.1 时,它开始正常工作。
通过使用 Android 的新 Android App Bundle,我的 Google Play 商店应用中的 2 个收到 Resource Not Found
错误。
这是其中一个应用程序的 fabric 堆栈跟踪:
Unable to start activity ComponentInfo{/com.Lastyear.MainActivity}: android.content.res.Resources$NotFoundException: File res/drawable/abc_item_background_holo_dark.xml from drawable resource ID #0x7f08002c
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2377)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2429)
at android.app.ActivityThread.access0(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1342)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5363)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:828)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:644)
at dalvik.system.NativeStart.main(NativeStart.java)
build.gradle
依赖关系:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
testImplementation 'junit:junit:4.12'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:customtabs:27.1.1'
implementation 'com.android.support:cardview-v7:27.1.1'
implementation 'com.squareup.picasso:picasso:2.5.2'
implementation 'com.android.support:palette-v7:27.1.1'
implementation 'com.afollestad.material-dialogs:core:0.9.6.0'
implementation 'com.jakewharton:butterknife:8.8.1'
implementation 'com.github.bumptech.glide:glide:3.7.0'
implementation 'com.android.support:design:27.1.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
implementation 'com.github.hotchemi:android-rate:1.0.1'
implementation 'com.hannesdorfmann.smoothprogressbar:library:1.0.0'
implementation 'com.android.support:palette-v7:27.1.1'
implementation 'com.google.android.gms:play-services-ads:15.0.1'
implementation 'com.muddzdev:styleabletoast:1.0.9'
implementation 'com.github.GrenderG:Toasty:1.2.5'
implementation 'com.hannesdorfmann.smoothprogressbar:library:1.0.0'
implementation 'com.wang.avi:library:2.1.3'
implementation 'com.github.medyo:fancybuttons:1.8.4'
implementation 'com.irozon.sneaker:sneaker:1.0.1'
implementation 'com.sdsmdg.tastytoast:tastytoast:0.1.1'
implementation 'de.hdodenhof:circleimageview:2.2.0'
implementation 'com.github.barteksc:android-pdf-viewer:2.8.2'
implementation 'com.getkeepsafe.taptargetview:taptargetview:1.11.0'
implementation('com.crashlytics.sdk.android:crashlytics:2.6.8@aar') {
transitive = true;
}
implementation 'petrov.kristiyan:colorpicker-library:1.1.8'}
还有一件事,它只发生在 Android 4 操作系统上,而不发生在较新版本的 Android 上。我发现其他应用程序也有与 Resource Not Found
相同的问题,在使用 Android 的应用程序包之前不存在。库或代码中是否存在问题,或者是因为 Android 的应用程序包的测试版?
我还发现了导致崩溃的可绘制资源:-
我觉得这个问题也和这个问题有关:Resource Not Found error res/drawable/abc_switch_thumb_material.xml after adding SwitchCompat in Android App Bundle
问题可能是您的应用已被旁加载,即未通过 Play 商店安装,并且在这些设备上手动安装了不兼容的 APK。
由于迁移到 Android App Bundle 后仅在 Android 4 台设备上发生这种情况,我在添加后发现了一种方法:-
public class App extends Application {
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); }
在build.gradle中:-
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
如本 post 中所述:-
关于第二个问题:- Resource Not Found error res/drawable/abc_switch_thumb_material.xml after adding SwitchCompat in Android App Bundle
因为所有 Android 版本都发生了这种情况。我旁加载了 Apk 并且能够在 logcat 中重现相同的错误,所以这只能通过从我的项目中删除 SwitchCompat 来修复,我知道它是一个临时修复并且 Google 肯定应该对此做些什么这样至少在旁加载 apk 后不会发生崩溃,也许重定向到 Play 商店会是更好的选择。但是迁移到 Android App Bundle 后应用程序崩溃肯定会影响应用程序的稳定性,因为许多用户经常这样做。
这几乎可以肯定是用户通过 P2P 共享程序共享(旁加载)应用程序,或者将 APK 上传到网络,然后其他用户从网络下载和安装。
人们习惯于处理非 Android App Bundle 应用程序只是传输和共享主 APK。但是您的 App bundle 应用程序有很多 "split APKs" 用于资源之类的东西,这就是节省大小的方式。您可以阅读有关此过程的全部内容 on the help page。如果用户安装了主 APK 而没有安装正确的拆分 APK,那么应用程序第一次尝试加载资源时会发生 "Resources Not found" 崩溃。
如果你想支持用户侧载你的应用程序和主 APK,你可以尝试检测这种情况并向用户显示一条消息(不使用任何资源),内容为 "Please install from Google Play"。或者您可以决定不支持以这种方式共享 APK 的用户。
我怀疑从长远来看 运行 网站和 P2P 共享程序会更好地正确共享此类 APK,所以我不会花太长时间担心它。
如果您发现这种情况在较低的 Android 版本上更频繁地发生,这可能不是由于较低的 Android 版本中的错误。相反,这可能是因为在用户通常使用 P2P 共享应用程序的国家(例如印度),用户也更有可能使用旧版手机。
接受的答案绝对正确 - root of this issue 是 APK 文件的旁加载。
尽管如此,很多人仍在寻找解决方法,询问如何正确处理这种情况。
在我的应用程序中,我执行了以下操作:
创建名为
pixel.png
的 1x1 图像并将其放入以下所有文件夹:drawable-mdpi
、drawable-hdpi
、drawable-xhdpi
、drawable-xxhdpi
,drawable-xxxhdpi
.创建显示静态消息的简单
Activity
,例如This copy of app is corrupted and can't be launched.
Please, install original version from Google Play
然后简单地从包裹在
try/catch
子句中的Activity.onCreate()
调用getDrawable(R.drawable.pixel)
。如果捕获到异常,只需完成当前
Activity
并从步骤 #2 开始另一个。
完成!
这个解决方案效果很好,现在我什至有来自 Firebase Analytics 的数据证实了这一点。
从 46k 的新用户(事件 first_open
)中,有 266 位用户收到此错误(已被捕获),221 位用户单击了导致 Google 播放的按钮。
这是我的源代码(也可用on GitHub):
DrawablesValidator.java
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Space;
import android.widget.TextView;
import android.widget.Toast;
public class DrawablesValidator extends Activity {
public static void ensureDrawablesValid(@NonNull Activity activity) {
try {
// IMPORTANT create 1x1 image named pixel.png and put it to all folders
// drawable-mdpi
// drawable-hdpi
// drawable-xhdpi
// drawable-xxhdpi
// drawable-xxxhdpi
activity.getDrawable(R.drawable.pixel);
} catch (Resources.NotFoundException ex) {
// NOTE optionally, report exception to Crashlytics or just an event to Analytics
activity.finish();
activity.startActivity(new Intent(activity, DrawablesValidator.class));
}
}
// NOTE don't care about translations of text messages here, don't put them to strings.xml
// we assume, that if user is smart enough to get APK from outside and install it,
// then user will definitely understand few messages in English :)
@SuppressLint("SetTextI18n")
@Override
protected void onCreate(Bundle state) {
super.onCreate(state);
int dp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics());
int dp8 = dp * 8;
int dp16 = dp * 16;
int dp80 = dp * 80;
LinearLayout root = new LinearLayout(this);
root.setOrientation(LinearLayout.VERTICAL);
root.setGravity(Gravity.CENTER_HORIZONTAL);
root.setPadding(dp80, dp16, dp80, dp16);
Space spaceTop = new Space(this);
TextView title = new TextView(this);
title.setPadding(0, dp8, 0, dp8);
title.setTextSize(20);
title.setText("Re-install app");
TextView message = new TextView(this);
message.setPadding(0, dp8, 0, dp8);
message.setTextSize(16);
message.setText("This copy of app is corrupted and can't be launched." +
"\n\n" +
"Please, install original version from Google Play");
Button button = new Button(this);
button.setPadding(dp16, dp8, dp16, dp8);
button.setText("Continue");
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + getPackageName())));
} catch (Exception ex) {
Toast.makeText(getApplicationContext(), "Can't open Google Play", Toast.LENGTH_SHORT).show();
}
}
});
Space spaceBottom = new Space(this);
int wc = ViewGroup.LayoutParams.WRAP_CONTENT;
int mp = ViewGroup.LayoutParams.MATCH_PARENT;
root.addView(spaceTop, lp(0, 0, 1, -1));
root.addView(title, lp(wc, wc, 0, -1));
root.addView(message, lp(mp, wc, 0, -1));
root.addView(button, lp(wc, wc, 0, Gravity.END));
root.addView(spaceBottom, lp(mp, wc, 1, -1));
setContentView(root);
}
private LinearLayout.LayoutParams lp(int width, int height, int weight, int gravity) {
LinearLayout.LayoutParams result = new LinearLayout.LayoutParams(width, height);
result.weight = weight;
result.gravity = gravity;
return result;
}
}
您可以查看 用户共享(侧载)来自 play console 的应用程序 登录播放控制台 select 您发布应用程序包而不是 apk 的应用程序。
Select Android Vital -> ANRs & crashes 然后点击 crashes 选项卡。
select 从播放安装
这有点晚了,但是 Google 为 Sideloading crash prevention
引入了新的 API,它允许您检测使用 Android 构建的应用程序的不完整安装应用程序包。
For example, consider an app that uses Android App Bundles to optimize app download size using split APKs. When a user downloads the app from the Google Play store, it ensures that the device downloads and installs the complete set of split APKs required to run that app on that particular device. When you bypass Google Play to sideload an app, the platform does not have sufficient data to validate the app install, and proper functionality of the app is not guaranteed.
首先在您的项目中包含 Play Core 库 1.6.0 或更高版本。
在您的应用项目的 build.gradle 文件中包含以下内容:
buildscript {
dependencies {
...
// Use bundletool 0.9.0 or higher when building with the
// Android Gradle plugin.
classpath 'com.android.tools.build:bundletool:0.9.0'
}
}
您可以使用以下 3 种方法中的一种
1) Register checks through the manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapplication" >
<application
...
android:name="com.google.android.play.core.missingsplits.MissingSplitsDetectingApplication" >
</application>
...
</manifest>
2) Apply checks in a custom Application class
public class MyCustomApplication extends Application {
@Override
public void onCreate() {
if (MissingSplitsManagerFactory.create(this).disableAppIfMissingRequiredSplits()) {
// Skip app initialization.
return;
}
super.onCreate();
...
}
}
3) Apply checks to content providers
public class ExampleProvider extends ContentProvider {
@Override
public boolean onCreate() {
if (MissingSplitsManagerFactory.create(getContext()).isMissingRequiredSplits()) {
// Skip provider initialization.
return false;
}
super.onCreate();
...
}
}
阅读更多:https://developer.android.com/reference/com/google/android/play/core/release-notes?hl=en-419#1-6-0
对于内部测试,我们无法加载 aab 文件 apks。在发布到生产环境之前,只有两种方法可以为用户提供 apk。
1) 我们必须给出 universal.apk 文件检查目的
java -jar bundletool-all-0.12.0.jar build-apks --bundle=(构建路径)debug.aab --output=(输出路径)debug.apks --模式=通用
2) 我们必须将 aab 文件上传到 playstore,然后首先发布内部测试,如果一切正常,然后发布它。
我遇到了同样的问题,我的应用程序因无法从资源中找到字体和音频文件而崩溃。问题是我在 Gradle-wrapper.properties 中将 Gradle URL 从 4.10.1 更新到 5.6.4 但没有更新库。当我恢复到 4.10.1 时,它开始正常工作。