アプリが機能要件を満たしていることを確認するテストの作成に加えて、lint ツールでコードを実行して、コードに構造上の問題がないことを確認することも重要です。lint ツールは、Android アプリの信頼性と効率に影響を与え、コードの保守を困難にする可能性のある、構造化されていないコードの検出に役立ちます。アプリを公開する前に、lint が検出したエラーをすべて修正することを強くおすすめします。
たとえば、XML リソース ファイルに未使用の名前空間が含まれていると、容量を消費し、不要な処理が必要になります。非推奨になった要素や、ターゲットの API バージョンでサポートされていない API 呼び出しといった構造上の問題があると、コードが適切に実行されなくなることがあります。lint はこうした問題を除去するのに役立ちます。
lint チェックのパフォーマンスを改善するために、コードにアノテーションを追加することもできます。
概要
Android Studio には、lint と呼ばれるコードスキャン ツールが用意されています。このツールを使用すると、アプリの実行やテストケースの作成を行わずに、コードの構造上の品質に関する問題を特定して修正できます。ツールによって検出された問題は、説明メッセージと重大度とともに報告されるため、必要な重要な改善に優先順位を付けることができます。また、問題の重大度レベルを下げてプロジェクトに関係のない問題を無視したり、重大度レベルを上げて特定の問題を明らかにしたりできます。
lint ツールは、Android プロジェクトのソースファイルをチェックして潜在的なバグを探し、正確性、セキュリティ、パフォーマンス、ユーザビリティ、ユーザー補助、国際化機能を最適化するための改善点を検出します。Android Studio を使用する場合、設定済みの lint と IDE のインスペクションは、アプリのビルド時に実行されます。ただし、このページで説明しているように、インスペクションを手動で実行したり、コマンドラインから lint を実行したりすることもできます。
Android Studio の使用中は、組み込みの lint ツールによってコードがチェックされます。次の 2 つの方法で警告とエラーを表示できます。
- エディタ ウィンドウのポップアップ テキスト。lint は問題を検出すると、問題のあるコードを黄色でハイライト表示します。より重大な問題の場合は、コードに赤色の下線が表示されます。
- lint の [Inspection Results] ウィンドウで、[Code] > [Inspect Code] をクリックします。
注: Android Studio でコードをコンパイルすると、追加の IntelliJ コード インスペクションが実行されるため、効率的にコードレビューを実施できます。
図 1 は、lint ツールがアプリのソースファイルを処理する方法を示しています。
- アプリのソースファイル
- ソースファイルは、Kotlin、Java、XML などのファイル、アイコン、ProGuard 構成ファイルなど、Android プロジェクトを構成するファイルで構成されます。
lint.xml
ファイル- 除外する lint チェックの指定と、問題の重大度のカスタマイズに使用できる構成ファイル。
- lint ツール
- コマンドラインまたは Android Studio から Android プロジェクトに対して実行できる静的コードスキャン ツールです。lint ツールは、Android アプリの品質とパフォーマンスに影響する可能性があるコードの構造上の問題をチェックします。
- lint チェックの結果
- lint の結果は、コンソール、または Android Studio の [Inspection Results] ウィンドウで確認できます。コマンドラインから
lint
を実行すると、結果はbuild/
フォルダに書き込まれます。詳しくは、手動で検査を実行するをご覧ください。
コマンドラインから lint を実行する
Android Studio または Gradle を使用している場合は、プロジェクトのルート ディレクトリから次のいずれかのコマンドを入力して、Gradle ラッパーを使用してプロジェクトの lint
タスクを呼び出します。
- Windows の場合:
gradlew lint
- Linux または macOS の場合:
./gradlew lint
出力は次のようになります。
> Task :app:lintDebug Wrote HTML report to file:<path-to-project>/app/build/reports/lint-results-debug.html
lint ツールによるチェックが完了すると、lint レポートの XML バージョンおよび HTML バージョンのパスが表示されます。図 2 に示すように、HTML レポートに移動してブラウザで開くことができます。
プロジェクトにビルド バリアントが含まれている場合、lint はデフォルトのバリアントのみをチェックします。別のバリアントで lint を実行する場合は、バリアント名を大文字にして、先頭に lint
を付ける必要があります。
./gradlew lintRelease
コマンドラインから Gradle タスクを実行する方法については、コマンドラインからアプリをビルドするをご覧ください。
スタンドアロン ツールで lint を実行する
Android Studio または Gradle を使用していない場合は、Android SDK コマンドライン ツールをインストールして、スタンドアロンの lint ツールを使用します。lint ツールは android_sdk/cmdline-tools/version/bin/lint
にあります。
注: Gradle プロジェクトでスタンドアロン ツールを実行しようとすると、エラーが発生します。Gradle プロジェクトで lint を実行するには、常に gradle lint
(Windows の場合)または ./gradlew
lint
(macOS または Linux の場合)を使用する必要があります。
プロジェクト ディレクトリにあるファイルのリストに対して lint を実行するには、次のコマンドを使用します。
lint [flags] <project directory>
たとえば、myproject
ディレクトリとそのサブディレクトリにあるファイルをスキャンするには、下記のコマンドを実行します。問題 ID MissingPrefix
は、Android 名前空間接頭辞が不足している XML 属性のみをスキャンするよう lint に指示します。
lint --check MissingPrefix myproject
このツールでサポートされているフラグとコマンドライン引数の一覧は、次のコマンドで確認できます。
lint --help
次の例は、Earthquake というプロジェクトに対して lint コマンドを実行したときのコンソール出力を示しています。
$ lint Earthquake Scanning Earthquake: ............................................................................................................................... Scanning Earthquake (Phase 2): ....... AndroidManifest.xml:23: Warning: <uses-sdk> tag appears after <application> tag [ManifestOrder] <uses-sdk android:minSdkVersion="7" /> ^ AndroidManifest.xml:23: Warning: <uses-sdk> tag should specify a target API level (the highest verified version; when running on later versions, compatibility behaviors may be enabled) with android:targetSdkVersion="?" [UsesMinSdkAttributes] <uses-sdk android:minSdkVersion="7" /> ^ res/layout/preferences.xml: Warning: The resource R.layout.preferences appears to be unused [UnusedResources] res: Warning: Missing density variation folders in res: drawable-xhdpi [IconMissingDensityFolder] 0 errors, 4 warnings
出力例には、4 つの警告が表示され、エラーはありません。
プロジェクトの AndroidManifest.xml
ファイルに関連する警告は 2 つあります。
ManifestOrder
UsesMinSdkAttributes
Preferences.xml
レイアウト ファイル UnusedResources
に関するものです。
警告の 1 つは、res
ディレクトリ(IconMissingDensityFolder
)に関連するものです。
警告を抑制するように lint を設定する
デフォルトでは、lint スキャンを実行すると、lint がサポートするすべての問題が確認されます。また、lint でチェックする問題を制限したり、問題の重大度を割り当てたりすることもできます。たとえば、プロジェクトに関係のない特定の問題に対する lint チェックを抑制したり、重大でない問題を低い重大度で報告するように lint を構成したりできます。
重大度は次のとおりです。
enable
disable
またはignore
informational
warning
error
fatal
次に示すさまざまなレベルで lint チェックを設定できます。
- グローバル(プロジェクト全体)
- プロジェクト モジュール
- 製品版モジュール
- テスト モジュール
- 開いているファイル
- クラス階層
- バージョン管理システム(VCS)のスコープ
lint ファイルを設定する
lint チェックの設定は、lint.xml
ファイルで指定できます。このファイルを手動で作成する場合は、Android プロジェクトのルート ディレクトリに配置してください。
lint.xml
ファイルは、1 つ以上の <issue>
子要素を囲む <lint>
親タグで構成されます。lint は、<issue>
ごとに一意の id
属性値を定義します。
<?xml version="1.0" encoding="UTF-8"?> <lint> <!-- list of issues to configure --> </lint>
問題の重大度を変更する、または問題の lint チェックを無効にするには、<issue>
タグで重大度属性を設定します。
ヒント: lint がサポートする問題と、それに対応する問題 ID の完全なリストを表示するには、lint --list
コマンドを実行します。
サンプル lint.xml ファイル
次の例は、lint.xml
ファイルの内容を示しています。
<?xml version="1.0" encoding="UTF-8"?> <lint> <!-- Disable the IconMissingDensityFolder check in this project --> <issue id="IconMissingDensityFolder" severity="ignore" /> <!-- Ignore the ObsoleteLayoutParam issue in the specified files --> <issue id="ObsoleteLayoutParam"> <ignore path="res/layout/activation.xml" /> <ignore path="res/layout-xlarge/activation.xml" /> </issue> <!-- Ignore the UselessLeaf issue in the specified file --> <issue id="UselessLeaf"> <ignore path="res/layout/main.xml" /> </issue> <!-- Change the severity of hardcoded strings to "error" --> <issue id="HardcodedText" severity="error" /> </lint>
次の例は、さまざまな種類の問題がどのように報告されるかを示しています。IconMissingDensityFolder
チェックは完全に無効になり、ObsoleteLayoutParam
チェックは内部の <ignore ... />
宣言で指定されたファイルでのみ無効になります。
Kotlin、Java、XML ソースファイルの lint チェックを設定する
Kotlin、Java、XML ソースファイルの lint チェックは、[Preferences] ダイアログで無効にできます。
- Windows の場合は [File] > [Settings]、macOS または Linux では [Android Studio] > [Preferences] を選択します。
- [Editor] > [Inspections] の順に選択します。
- 無効にするには、該当するソースファイルの選択を解除します。
適切なプロファイルを選択することで、IDE または個々のプロジェクトに対してこれらを設定できます。
Java または Kotlin で lint チェックを構成する
Android プロジェクトのクラスまたはメソッドに対する lint チェックのみを無効にするには、そのコードに @SuppressLint
アノテーションを追加します。
次の例は、onCreate
メソッドで NewApi
問題の lint チェックをオフにする方法を示しています。lint ツールは、このクラスの他のメソッドでは引き続き NewApi
問題をチェックします。
Kotlin
@SuppressLint("NewApi") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main)
Java
@SuppressLint("NewApi") @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main);
どのコンポーザブルでも同じことができます。次のコード スニペットは、任意のコンポーザブルで NewApi
チェックをオフにする方法を示しています。
Kotlin
@SuppressLint("NewApi") @Composable fun MyComposable{ ... }
次の例は、FeedProvider
クラスで ParserError
問題の lint チェックをオフにする方法を示しています。
Kotlin
@SuppressLint("ParserError") class FeedProvider : ContentProvider() {
Java
@SuppressLint("ParserError") public class FeedProvider extends ContentProvider {
ファイル内のすべての lint 問題のチェックを抑制するには、all
キーワードを使用します。
Kotlin
@SuppressLint("all")
Java
@SuppressLint("all")
同じアノテーションを使用して、コンポーズ可能な関数に対する lint チェックを抑制できます。
XML で lint チェックを構成する
XML ファイルの特定のセクションに対する lint チェックをオフにするには、tools:ignore
属性を使用します。lint.xml
ファイルに次の名前空間値を挿入すると、lint ツールによって属性が認識されます。
namespace xmlns:tools="http://schemas.android.com/tools"
次の例は、XML レイアウト ファイルの <LinearLayout>
要素で UnusedResources
問題の lint チェックをオフにする方法を示しています。ignore
属性は、属性が宣言されている親要素の子要素に継承されます。この例では、子 <TextView>
要素の lint チェックも無効になります。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:ignore="UnusedResources" > <TextView android:text="@string/auto_update_prompt" /> </LinearLayout>
複数の問題に対するチェックを無効にするには、無効にする問題のリストをカンマ区切り文字列で指定します。たとえば、以下の場合です。
tools:ignore="NewApi,StringFormatInvalid"
XML 要素内のすべての lint 問題のチェックを抑制するには、all
キーワードを使用します。
tools:ignore="all"
Gradle で lint オプションを設定する
Android Plugin for Gradle では、モジュール レベルの build.gradle
ファイルで
lint{}
ブロックを使用して、特定の lint オプション(どのチェックを実行または無視するかなど)を設定できます。
次のコード スニペットは、構成可能なプロパティの一部を示しています。
Kotlin
android { ... lint { // Turns off checks for the issue IDs you specify. disable += "TypographyFractions" + "TypographyQuotes" // Turns on checks for the issue IDs you specify. These checks are in // addition to the default lint checks. enable += "RtlHardcoded" + "RtlCompat" + "RtlEnabled" // To enable checks for only a subset of issue IDs and ignore all others, // list the issue IDs with the 'check' property instead. This property overrides // any issue IDs you enable or disable using the properties above. checkOnly += "NewApi" + "InlinedApi" // If set to true, turns off analysis progress reporting by lint. quiet = true // If set to true (default), stops the build if errors are found. abortOnError = false // If set to true, lint only reports errors. ignoreWarnings = true // If set to true, lint also checks all dependencies as part of its analysis. // Recommended for projects consisting of an app with library dependencies. checkDependencies = true } } ...
Groovy
android { ... lint { // Turns off checks for the issue IDs you specify. disable 'TypographyFractions','TypographyQuotes' // Turns on checks for the issue IDs you specify. These checks are in // addition to the default lint checks. enable 'RtlHardcoded','RtlCompat', 'RtlEnabled' // To enable checks for only a subset of issue IDs and ignore all others, // list the issue IDs with the 'check' property instead. This property overrides // any issue IDs you enable or disable using the properties above. checkOnly 'NewApi', 'InlinedApi' // If set to true, turns off analysis progress reporting by lint. quiet true // If set to true (default), stops the build if errors are found. abortOnError false // If set to true, lint only reports errors. ignoreWarnings true // If set to true, lint also checks all dependencies as part of its analysis. // Recommended for projects consisting of an app with library dependencies. checkDependencies true } } ...
問題の特定の重大度をオーバーライドするすべての lint メソッドは、設定の順序に従います。たとえば、finalizeDsl()
で問題を fatal に設定すると、メイン DSL での問題の無効化よりも優先されます。
警告ベースラインを作成する
プロジェクトの現在の警告セットのスナップショットを作成し、将来の検査実行のベースラインとしてスナップショットを使用して、新しい問題のみが報告されるようにできます。ベースライン スナップショットを使用すると、すべての既存の問題に戻って対処する手間をかけずに、lint でビルドエラーをチェックできます。
ベースライン スナップショットを作成するには、プロジェクトの build.gradle
ファイルを次のように変更します。
Kotlin
android { lint { baseline = file("lint-baseline.xml") } }
Groovy
android { lintOptions { baseline file("lint-baseline.xml") } }
初めてこの行を追加したとき、ベースラインを確立するために lint-baseline.xml
ファイルが作成されます。それ以降、ツールはベースラインを確認するためにファイルの読み取りのみを行います。新しいベースラインを作成する場合は、ファイルを手動で削除し、lint を再度実行して再作成します。
次に、IDE から [Code] > [Inspect Code] を選択するか、次のようにコマンドラインから lint を実行します。出力に、lint-baseline.xml
ファイルの場所が表示されます。設定用のファイルの場所は、ここに示されているものと異なる場合があります。
$ ./gradlew lintDebug -Dlint.baselines.continue=true ... Wrote XML report to file:///app/lint-baseline.xml Created baseline file /app/lint-baseline.xml
lint
を実行すると、lint-baseline.xml
ファイルに現在の問題がすべて記録されます。現在発生している一連の問題をベースラインといいます。他のユーザーと共有する場合は、lint-baseline.xml
ファイルをバージョン管理にチェックインします。
ベースラインをカスタマイズする
特定の問題タイプのみをベースラインに追加する場合は、プロジェクトの build.gradle
ファイルを次のように編集して、追加する問題を指定します。
Kotlin
android { lint { checkOnly += "NewApi" + "HandlerLeak" baseline = file("lint-baseline.xml") } }
Groovy
android { lintOptions { checkOnly 'NewApi', 'HandlerLeak' baseline file("lint-baseline.xml") } }
ベースラインの作成後にコードベースに新しい警告を追加すると、lint は新しく導入されたバグのみを一覧表示します。
ベースライン警告
ベースラインが有効になっている場合、1 つ以上の問題がベースラインに含まれているために除外されたことを示す情報警告が表示されます。この警告は、ベースラインを構成したことと、どこかの時点ですべての問題を修正する必要があることを思い出すのに役立ちます。
この情報警告には、報告されなくなった問題も追跡されます。この情報により、実際に問題が修正されたかどうかがわかります。必要に応じてベースラインを再作成して、エラーが検出されずに再発しないようにすることもできます。
注: ベースラインは、IDE でインスペクションをバッチモードで実行するときは有効になりますが、ファイルの編集時にバックグラウンドで実行されるエディタ内チェックでは無視されます。ベースラインは、コードベースに既存の警告が多数あるが、コードの編集時にローカルで問題を修正する場合を想定しているためです。
検査を手動で実行する
設定済みの lint とその他の IDE インスペクションを手動で実行するには、[Code] > [Inspect Code] を選択します。インスペクションの結果は [Inspection Results] ウィンドウに表示されます。
インスペクションのスコープとプロファイルを設定する
分析するファイル(インスペクション スコープ)と実行するインスペクション(インスペクション プロファイル)を次のように選択します。
- [Android] ビューでプロジェクトを開き、分析するプロジェクト、フォルダ、またはファイルを選択します。
- メニューバーで、[Code] > [Inspect Code] を選択します。
[Specify Inspection Scope] ダイアログで、設定を確認します。
[Define Inspection Scope] ダイアログに表示されるオプションは、プロジェクト、フォルダ、ファイルのどれを選択したかによって異なります。
- プロジェクト、ファイル、またはディレクトリを 1 つ選択すると、選択したプロジェクト、ファイル、またはディレクトリへのパスが [インスペクション スコープの指定] ダイアログに表示されます。
- 複数のプロジェクト、ファイル、またはディレクトリを選択すると、[Choose Inspection Scope] ダイアログに [Selected files] に対して選択されているラジオボタンが表示されます。
検査対象を変更するには、他のいずれかのラジオボタンを選択します。[Customize Inspection Scope] ダイアログに表示されるすべてのフィールドについては、[Define Inspection Scope] ダイアログをご覧ください。
- [Inspection profile] で、使用するプロファイルを選択します。
[OK] をクリックして検査を実行します。
図 4 は、[Inspect Code] を実行した場合の lint とその他の IDE インスペクションの結果を示しています。
-
[Inspection Results] ペインで、エラーのカテゴリ、タイプ、または問題を開いて選択し、検査結果を表示します。
[Inspection Report] ペインには、[Inspection Results] ペインで選択したエラーのカテゴリ、タイプ、または問題のインスペクション レポートが表示され、エラーの名前と場所が表示されます。必要に応じて、検査レポートには問題の概要など、問題の解決に役立つその他の情報が表示されます。
[Inspection Results] ペインのツリービューで、カテゴリ、タイプ、または問題を右クリックして、コンテキスト メニューを表示します。
状況に応じて、次のことができます。
- ソースに移動。
- 選択したアイテムを除外して含める。
- 問題を抑制する。
- 設定を編集します。
- 検査アラートを管理します。
- 検査を再実行します。
ツールバー ボタン、コンテキスト メニュー項目、検査レポートのフィールドの説明については、 検査結果ツール ウィンドウをご覧ください。
カスタム スコープを使用する
Android Studio に用意されているカスタム スコープのいずれかを、次のように使用します。
- [specified Inspection Scope] ダイアログで、[Custom scope] を選択します。
[Custom scope] リストをクリックして、オプションを表示します。
- すべての場所: すべてのファイル。
- Project Files: 現在のプロジェクト内のすべてのファイル。
- Project Source Files: 現在のプロジェクト内のソースファイルのみ。
- [Project Production Files]: 現在のプロジェクト内の製品版ファイルのみ。
- [Project Test Files]: 現在のプロジェクト内のテストファイルのみ。
- スクラッチとコンソール: 現在のプロジェクトで開いているスクラッチ ファイルとコンソールのみ。
- 最近表示したファイル: 現在のプロジェクトで最近表示したファイルのみ。
- [Current File]: 現在のプロジェクト内の現在のファイルのみ。ファイルまたはフォルダを選択している場合に表示されます。
- Selected Directory: 現在のプロジェクト内の現在のフォルダのみ。フォルダを選択している場合に表示されます。
- Class Hierarchy: このオプションを選択して [OK] をクリックすると、現在のプロジェクト内のすべてのクラスを示すダイアログが表示されます。ダイアログで、[Search by Name] フィールドを使用して、検査するクラスをフィルタリングして選択します。クラスリストをフィルタしない場合、コード インスペクションはすべてのクラスを検査します。
プロジェクトに VCS が構成されている場合は、変更されたファイルのみに検索を制限するオプションもあります。
- [OK] をクリックします。
カスタム スコープを作成する
現在使用可能なカスタム スコープのいずれにも該当しないファイルとディレクトリのセレクションを検査する場合は、カスタム スコープを作成します。
- [Specify Inspection Scope] ダイアログで、[Custom scope] を選択します。
[Custom Scope] リストの横にあるその他アイコンをクリックします。
[スコープ] ダイアログが表示されます。
- ダイアログの左上にある ボタンをクリックして、新しいスコープを定義します。
- 表示された [スコープを追加] リストで、[ローカル] を選択します。
プロジェクト内では、ローカル スコープと共有スコープの両方がコード インスペクション機能に使用されます。共有スコープは、スコープ フィールドを含む他のプロジェクト機能でも使用できます。たとえば、[Find Usages] の設定を変更するために [Edit Settings] をクリックすると表示されるダイアログには、共有スコープを選択できる [Scope] フィールドがあります。
- スコープに名前を付けて、[OK] をクリックします。
[Scopes] ダイアログの右側のペインには、カスタム スコープを定義するためのオプションが表示されます。
- リストから [Project] を選択します。
使用可能なプロジェクトのリストが表示されます。
注: プロジェクトまたはパッケージのカスタム スコープを作成できます。手順は同じです。
プロジェクト フォルダを開き、カスタム スコープに追加するものを選択して、それを含めるか除外するかを選択します。
- [Include]: このフォルダとその中のファイルを追加しますが、サブフォルダは追加しません。
- Include Recursically: このフォルダとその中のファイル、さらにそのサブフォルダとその中のファイルを含めます。
- [Exclude]: このフォルダとその中のファイルを除外しますが、サブフォルダは除外しません。
- [Exclude Recursically]: このフォルダとその中のファイル、さらにそのサブフォルダとその中のファイルを除外します。
図 10 は、main フォルダが含まれ、java フォルダと res フォルダが再帰的に含まれていることを示しています。青色は部分的に含まれているフォルダを示し、緑色は再帰的に含まれているフォルダとファイルを示します。
- java フォルダを選択して [Exclude Recursably] をクリックすると、java フォルダとその下のすべてのフォルダとファイルが緑色でハイライト表示されなくなります。
- 緑色でハイライト表示された MainActivity.kt ファイルを選択して [除外] をクリックすると、MainActivity.kt は緑色でハイライト表示されなくなりますが、java フォルダの下の他のものはすべて緑色のままです。
- [OK] をクリックします。カスタム スコープがリストの一番下に表示されます。
インスペクション プロファイルを確認、編集する
Android Studio には、Android のアップデートによって更新される lint などのインスペクション プロファイルがあります。これらのプロファイルは、そのまま使用することも、名前、説明、重大度、スコープを編集することもできます。プロファイルのグループ全体またはグループ内の個々のプロファイルを有効化または無効化することも可能です。
[Inspections] の設定にアクセスするには:
- [File] > [Settings] を選択します。(Windows の場合)または [Android Studio] > [Preferences](macOS または Linux の場合)を選択します。
- [Editor] > [Inspections] の順に選択します。
[Profile] リストを選択して、[Default](Android Studio)と [Project Default](アクティブなプロジェクト)のインスペクションを切り替えます。
詳細については、IntelliJ のプロファイルの管理ページをご覧ください。
左側のペインの [Inspections] リストで、最上位のプロファイル カテゴリを選択するか、グループを開いて特定のプロファイルを選択します。
プロファイル カテゴリを選択すると、そのカテゴリ内のすべてのインスペクションを 1 つのインスペクションとして編集できます。
- インスペクションのコピー、名前の変更、説明の追加、エクスポート、インポートを行うには、[Show Schema Actions] リストを選択します。
- 完了したら、[OK] をクリックします。
[Inspections] ペインに、サポートされているインスペクションとその説明のリストが表示されます。