By using Android's new Android App Bundle, I have received a Resource Not Found
error in 2 of my Google Play Store apps.
Here is the stacktrace from fabric for one of the apps:
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.access$800(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:
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'}
One more thing, it is happening only on Android 4 operating system, not on newer versions of Android. I have found that other apps are having the same problem of Resource Not Found
, which was not existing before using Android's app bundle. Is there some problem in the library or code or it is because of the beta version of Android's app bundle?
I have also found the resource drawable due to which it crashes:-
I think this question is also related to this one: Resource Not Found error res/drawable/abc_switch_thumb_material.xml after adding SwitchCompat in Android App Bundle
This is almost certainly users sharing (sideloading) the app, either via P2P sharing programs, or uploading the APK to the web then other users downloading and installing from the web.
People used to dealing with non Android App Bundle apps just transfer and share the main APK. But your App bundle app has lots of "split APKs" for things like the resources, that is how the size saving happens. You can read all about this process on the help page. If a user installs the main APK without installing the right split APKs, then a "Resources Not found" crash will occur the first time the app tries to load a resource.
If you want to support users sideloading your app and just the main APK you could try to detect this situation and display a message to the user (without using any resources) that says "Please install from Google Play". Or you could just decide you aren't going to support users who share APKs in this way.
I suspect in the long run the websites and P2P sharing programs will get better at sharing such APKs properly, so I wouldn't spend too long worrying about it.
If you see this happening far more frequently on lower Android versions, this isn't probably due to a bug in lower Android versions. Instead, it is probably because in countries where users commonly P2P share apps (eg India) users also are far more likely to be on older version phones.
This is a little late but Google has introduced new API for Sideloading crash prevention
, which allows you to detect incomplete installation of apps that are built using an Android App Bundle.
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.
First off include the Play Core library 1.6.0 or higher in your project.
Include the following in your app project’s build.gradle file:
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' } }
You can use 1 of those 3 below methods
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(); ... } }
Read More : https://developer.android.com/reference/com/google/android/play/core/release-notes?hl=en-419#1-6-0
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With