Unity ゲームで ANR を解決する手順は次のとおりです。
レポート サービスを統合する
Android Vitals、Firebase Crashlytics、Backtrace(Unity の認定パートナー)などのレポート サービスは、ゲームのエラーログと分析を大規模に提供します。開発サイクルの早い段階でレポート サービス SDK をゲームに統合します。ゲームのニーズと予算に最適なレポート サービスを分析します。
レポート サービスによって、ANR のキャプチャ方法が異なります。ANR の修正に関する意思決定をサポートする有効なデータを取得する可能性を高めるために、2 つ目のレポート サービスを含めます。
レポート SDK を統合しても、ゲームのパフォーマンスや APK サイズに影響はありません。
シンボルを分析する
レポート サービスからのレポートを分析し、スタック トレースが人間が読める形式になっているかどうかを確認します。詳しくは、Android のクラッシュと ANR をシンボリケートするをご覧ください。
libil2cpp.so シンボルが表示されています。シンボルのビルド ID を確認する方法
レポート システムにビルド ID が欠落していると表示されても、ビルド シンボルがビルドマシンのストレージにまだ存在する場合は、シンボルのビルド ID を確認してレポート サービスにアップロードできます。それ以外の場合は、シンボル ファイルをアップロードするために新しいビルドが必要です。
Windows または macOS の場合:
-
スクリプト バックエンドに基づいてシンボル フォルダに移動します(解決策 を参照)。
- 次のコマンドを使用します(Windows の場合は、Cygwin を使用して
readelfユーティリティを実行します)。 - Grep の使用は、テキスト出力をフィルタする場合に任意で使用します。
- ビルド ID を探します。
- 次のコマンドを使用します(Windows の場合は、Cygwin を使用して
readelf -n libil2cpp.so | grep 'Build ID'
Build ID: b42473fb7449e44e0182dd1f580c99bab0cd8a95
ゲームコードを検査する
スタック トレースに libil2cpp.so ライブラリの関数が表示されている場合、
エラーは C# コードで発生しています。このコードは C++ に変換されます。
libil2cpp.so ライブラリには、ゲームコードだけでなく、プラグインやパッケージも含まれています。
C++ のファイル名は、Unity プロジェクトで定義されているアセンブリ名に従います。
それ以外の場合、ファイル名にはデフォルトの Assembly-C# 名が使用されます。たとえば、図 3 は、Assembly Definition ファイルで定義された名前であるファイル Game.cpp(青色でハイライト表示)のエラーを示しています。Logger は、C# スクリプトのクラス名(赤色でハイライト表示)で、その後に関数名(緑色でハイライト表示)が続きます。最後に、IL2CPP コンバータが生成した完全な名前(オレンジ色でハイライト表示)が表示されます。
ゲームコードを検査するには、次の操作を行います。
- C# プロジェクトで不審なコードがないか確認します。通常、C# の未処理の例外が ANR やアプリのクラッシュを引き起こすことはありません。それでも、さまざまな状況でコードが適切に実行されるようにしてください。コードでサードパーティ エンジン モジュールが使用されているかどうかを確認し、最近のリリースでエラーが発生したかどうかを分析します。また、最近 Unity を更新したかどうか、または特定デバイスでのみエラーが発生するかどうかを確認します。
- ゲームを Android Studio プロジェクトとしてエクスポートします。ゲームの変換された C# ソースコードに完全にアクセスできるため、ANR の原因となっている関数を見つけることができます。C++ コードは C# コードとは大きく異なり、コード変換で問題が発生することはほとんどありません。何か見つかった場合は、Unity にサポート チケットを送信してください。
- ゲームのソースコードを確認し、
OnApplicationFocus() コールバックと OnApplicationPause()
コールバックで実行されているロジックが適切にクリーンアップされていることを確認します。
- Unity エンジンには実行を一時停止するタイムアウトがあります。これらのコールバックのワークロードが過剰になると、ANR が発生する可能性があります。
- コードの一部にログまたはブレッドクラムを追加して、データ分析を強化します。
- Unity Profiler を使用して、ゲームの パフォーマンスを調査します。アプリのプロファイリングは、ANR の原因となっている可能性のある ボトルネックを特定するのに役立ちます。
- メインスレッドでの長い I/O オペレーションを特定する優れた方法は、 厳格モード を使用することです。
- Android Vitals または別のレポート サービスの履歴を分析し、エラーが最も多く発生しているゲームのリリース バージョンを確認します。バージョン管理履歴でソースコードを確認し、リリース間のコード変更を比較します。不審な点が見つかった場合は、各変更または潜在的な修正を個別に試してください。
- 最も多くの ANR を受信しているデバイスと Android バージョンの Google Play ANR レポート履歴を確認します。デバイスまたはバージョンが古い場合は、ゲームの収益に影響しない限り、無視しても問題ありません。特定のユーザー グループがゲームをプレイできなくなるため、データを慎重に確認してください。詳しくは、配信 ダッシュボードをご覧ください。
- ゲームのソースコードを確認し、問題を引き起こす可能性のあるコードを 呼び出していないことを確認します。たとえば、finish は正しく使用しないと 破壊的になる可能性があります。Android 開発について詳しくは、Android デベロッパー ガイド をご覧ください。
- データを確認してゲームビルドを Android Studio にエクスポートすると、 C と C++ のコードを扱うことになるため、 Android Memory Profiler、Android CPU Profiler、perfetto など、 Unity の標準ソリューション以外のツールを最大限に活用できます。
Unity エンジン コード
ANR が Unity エンジン側で発生しているかどうかを確認するには、スタック トレースで libUnity.so または libMain.so を確認します。見つかった場合は、次の手順を行います。
- まず、コミュニティ チャネル(Unity フォーラム、Unity Discussions、Stackoverflow)を検索します。
- 何も見つからない場合は、バグを報告して問題を解決してください。エンジンのエンジニアがエラーをよりよく理解して解決できるように、シンボリケートされたスタック トレースを提供してください。
- 最新の Unity LTS で問題に関連する改善が行われているかどうかを確認します。改善が行われている場合は、そのバージョンを使用するようにゲームをアップグレードします (この解決策は一部のデベロッパーのみが利用できる場合があります)。
- コードでデフォルトの
Activityではなくカスタムのを使用している場合は、 Java コードを確認して、アクティビティが問題を引き起こしていないことを確認します。
サードパーティ SDK
- すべてのサードパーティ ライブラリが最新の状態であり、最新バージョンの Android でクラッシュや ANR のレポートがないことを確認します。
- Unity フォーラムにアクセスして、後のバージョンでエラーがすでに 解決されているかどうか、または Unity またはコミュニティ メンバーが回避策を提供しているかどうかを確認します。
- Google Play ANR レポートを確認し、エラーが Google によってすでに特定されていないことを確認します。Google は一部の ANR を認識しており、修正に積極的に取り組んでいます。
システム ライブラリ
システム ライブラリは通常、デベロッパーが制御することはできませんが、ANR の割合はそれほど高くありません。ライブラリ デベロッパーに連絡したり、ログを追加して問題を絞り込んだりする以外に、システム ライブラリの ANR を解決するのは困難です。
終了理由
ApplicationExitInfo は、ANR の原因を把握するための Android API です。
ゲームで Unity 6 以降を使用している場合は、ApplicationExitInfo
を直接呼び出すことができます。古い Unity バージョンの場合は、Unity から ApplicationExitInfo 呼び出しを有効にするために独自のプラグインを実装する必要があります。
Crashlytics でも ApplicationExitInfo が使用されますが、独自の
実装ではより細かく制御でき、より関連性の高い情報を含めることができます
。