web-dev-qa-db-ja.com

Androidアプリバンドルにより、AndroidアプリでResource Not foundクラッシュが発生する

Android新しいAndroidアプリバンドルを使用して、2つのgoogle PlayストアアプリでResource Not Foundクラッシュが見つかりました:-

アプリのいずれかのファブリックからのスタックトレースは次のとおりです。

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 {
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'}

もう1つ、Android 4のオペレーティングシステムでのみ発生しています。Androidの新しいバージョンではありません。他のアプリには、使用前には存在しなかったResource Not Foundという同じ問題がありますAndroidアプリバンドル。ライブラリまたはコードに問題があるか、Androidアプリバンドルのベータ版が原因ですか?

enter image description here

また、クラッシュするためにリソースがドローアブルであることも発見しました:- enter image description here

この質問はこれにも関連していると思います:- Android App BundleにSwitchCompatを追加した後、クラスAndroid.support.design.widget.NavigationViewを膨らませるエラー

39
gautam kumar

これは、ほぼ間違いなく、P2P共有プログラムを介してユーザーがアプリを共有(サイドローディング)するか、APKをWebにアップロードし、他のユーザーがWebからダウンロードしてインストールすることです。

Android以外のアプリバンドルアプリを扱っていた人々は、メインAPKを転送して共有するだけです。しかし、アプリバンドルアプリには、リソースなどの「分割APK」がたくさんあるため、サイズの節約が行われます。このプロセスに関するすべてを読むことができます ヘルプページで 。ユーザーが適切な分割APKをインストールせずにメインAPKをインストールすると、アプリがリソースをロードしようとしたときに「リソースが見つかりません」というクラッシュが発生します。

アプリとメインAPKのみをサイドローディングするユーザーをサポートする場合、この状況を検出し、「Google Playからインストールしてください」というメッセージを(リソースを使用せずに)ユーザーに表示できます。または、この方法でAPKを共有するユーザーをサポートしないことを決定することもできます。

長い目で見れば、ウェブサイトとP2P共有プログラムは、そのようなAPKを適切に共有するのに優れていると思われるので、心配するのにそれほど時間はかかりません。

Androidの下位バージョンでこれがはるかに頻繁に発生する場合、これはおそらくAndroidの下位バージョンのバグによるものではありません。代わりに、おそらくユーザーがP2Pを共有するアプリが多い国(インドなど)では、ユーザーが古いバージョンの携帯電話を使用する可能性がはるかに高いためです。

29
Nick Fortescue

問題は、アプリがサイドロードされている、つまりPlayストア経由でインストールされておらず、それらのデバイスに互換性のないAPKが手動でインストールされていることです。

11
Pierre

これは少し遅れていますが、GoogleはAndroid App Bundleを使用してビルドされたアプリの不完全なインストールを検出できるSideloading crash preventionの新しいAPIを導入しました。

たとえば、Android App Bundlesを使用して、分割APKを使用してアプリのダウンロードサイズを最適化するアプリを考えます。ユーザーがGoogle Playストアからアプリをダウンロードすると、デバイスはその特定のデバイスでそのアプリを実行するために必要な分割APKの完全なセットをダウンロードしてインストールします。 Google Playをバイパスしてアプリをサイドロードすると、プラットフォームにはアプリのインストールを検証するための十分なデータがなく、アプリの適切な機能が保証されません。

まず、プロジェクトに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つを使用できます

1)マニフェストを介してチェックを登録する

<?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)カスタムアプリケーションクラスにチェックを適用する

public class MyCustomApplication extends Application {
    @Override
    public void onCreate() {

        if (MissingSplitsManagerFactory.create(this).disableAppIfMissingRequiredSplits()) {
            // Skip app initialization.
            return;
        }

        super.onCreate();
        ...
    }
}

3)チェックをコンテンツプロバイダーに適用する

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-

7
EAK TEAM

受け入れられた答えは絶対に正しいです- この問題の根本 はAPKファイルのサイドローディングです。

それにもかかわらず、多くの人々は、このケースを正しく処理する方法を尋ねて、まだ回避策を探しています。

私のアプリでは、次のことを行いました。

  1. pixel.pngという名前の1x1イメージを作成し、drawable-mdpidrawable-hdpidrawable-xhdpidrawable-xxhdpidrawable-xxxhdpiのすべてのフォルダーに配置します。

  2. 静的メッセージを表示する単純なActivityを作成します。

    このアプリのコピーは破損しており、起動できません。

    Google Playからオリジナルバージョンをインストールしてください

  3. 次に、try/catch句でラップされたgetDrawable(R.drawable.pixel)からActivity.onCreate()を呼び出します。

  4. 例外がキャッチされた場合は、現在のActivityを終了し、ステップ2から別の例外を開始します。

できた!

 Screenshot 

このソリューションはうまく機能し、今ではFirebase Analyticsからこれを確認するデータもあります。

46kの新しいユーザー(イベントfirst_open)から266人のユーザーがこのエラー(キャッチ)を受け取り、221人のユーザーがGoogle Playにつながるボタンをクリックしました。

これが私のソースコードです(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;
    }
}
6
Oleksii K.

これはAndroid App Bundleに移行した後のAndroid 4デバイスでのみ発生するため、追加後にこの方法を見つけました:-

public class App extends Application {

static {
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); }

そして、build.gradleで:-

Android {
  defaultConfig {
    vectorDrawables.useSupportLibrary = true
  }
}

この投稿で説明されているように:- Lollipopのクラッシュ前にAndroid vector Drawablesを使用

2番目の質問について: Resource Not Foundエラーres/drawable/abc_switch_thumb_material.xmlにSwitchCompatをAndroid App Bundleに追加した後

これはすべてのAndroidバージョンで発生しているためです。私はApkをサイドロードし、logcatで同じエラーを再現することができますので、これは私のプロジェクトからSwitchCompatを削除することによってのみ修正できます、私はその一時的な修正を知っていますapkをサイドロードした後、おそらくPlayストアにリダイレクトする方が適切なオプションです。ただし、Android App Bundleに移行した後のアプリのクラッシュは、多くのユーザーが定期的に行うため、アプリの安定性に確実に影響します。

3
gautam kumar

ユーザー共有(sideloading)からアプリを確認できます プレイコンソール ログインプレイコンソールアプリバンドルを公開するアプリを選択しますapkの代わりに。

Android Vital-> ANRs and crashesを選択し、クラッシュタブをクリックします。

プレイからインストールを選択

enter image description here

0
Ashish Singh

https://ourcodeworld.com/articles/read/331/Android-error-no-resource-found-that-matches-the-given-name-at-icon-with-value-drawable-icon

上記のリンクから、アプリで使用されるアイコンはドロアブルリソースフォルダーにあるべきであり、起動アイコンはミップマップリソースフォルダーにあるべきであることを学びました。私はアイコンを転送し、それは私のために働いた。

0