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アプリバンドルのベータ版が原因ですか?
また、クラッシュするためにリソースがドローアブルであることも発見しました:-
この質問はこれにも関連していると思います:- Android App BundleにSwitchCompatを追加した後、クラスAndroid.support.design.widget.NavigationViewを膨らませるエラー
これは、ほぼ間違いなく、P2P共有プログラムを介してユーザーがアプリを共有(サイドローディング)するか、APKをWebにアップロードし、他のユーザーがWebからダウンロードしてインストールすることです。
Android以外のアプリバンドルアプリを扱っていた人々は、メインAPKを転送して共有するだけです。しかし、アプリバンドルアプリには、リソースなどの「分割APK」がたくさんあるため、サイズの節約が行われます。このプロセスに関するすべてを読むことができます ヘルプページで 。ユーザーが適切な分割APKをインストールせずにメインAPKをインストールすると、アプリがリソースをロードしようとしたときに「リソースが見つかりません」というクラッシュが発生します。
アプリとメインAPKのみをサイドローディングするユーザーをサポートする場合、この状況を検出し、「Google Playからインストールしてください」というメッセージを(リソースを使用せずに)ユーザーに表示できます。または、この方法でAPKを共有するユーザーをサポートしないことを決定することもできます。
長い目で見れば、ウェブサイトとP2P共有プログラムは、そのようなAPKを適切に共有するのに優れていると思われるので、心配するのにそれほど時間はかかりません。
Androidの下位バージョンでこれがはるかに頻繁に発生する場合、これはおそらくAndroidの下位バージョンのバグによるものではありません。代わりに、おそらくユーザーがP2Pを共有するアプリが多い国(インドなど)では、ユーザーが古いバージョンの携帯電話を使用する可能性がはるかに高いためです。
問題は、アプリがサイドロードされている、つまりPlayストア経由でインストールされておらず、それらのデバイスに互換性のないAPKが手動でインストールされていることです。
これは少し遅れていますが、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-
受け入れられた答えは絶対に正しいです- この問題の根本 はAPKファイルのサイドローディングです。
それにもかかわらず、多くの人々は、このケースを正しく処理する方法を尋ねて、まだ回避策を探しています。
私のアプリでは、次のことを行いました。
pixel.png
という名前の1x1イメージを作成し、drawable-mdpi
、drawable-hdpi
、drawable-xhdpi
、drawable-xxhdpi
、drawable-xxxhdpi
のすべてのフォルダーに配置します。
静的メッセージを表示する単純なActivity
を作成します。
このアプリのコピーは破損しており、起動できません。
Google Playからオリジナルバージョンをインストールしてください
次に、try/catch
句でラップされたgetDrawable(R.drawable.pixel)
からActivity.onCreate()
を呼び出します。
例外がキャッチされた場合は、現在のActivity
を終了し、ステップ2から別の例外を開始します。
できた!
このソリューションはうまく機能し、今では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;
}
}
これは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に移行した後のアプリのクラッシュは、多くのユーザーが定期的に行うため、アプリの安定性に確実に影響します。
ユーザー共有(sideloading)からアプリを確認できます プレイコンソール ログインプレイコンソールアプリバンドルを公開するアプリを選択しますapkの代わりに。
Android Vital-> ANRs and crashesを選択し、クラッシュタブをクリックします。
プレイからインストールを選択
上記のリンクから、アプリで使用されるアイコンはドロアブルリソースフォルダーにあるべきであり、起動アイコンはミップマップリソースフォルダーにあるべきであることを学びました。私はアイコンを転送し、それは私のために働いた。