アプリが機能要件を満たしていることを確認するテストを作成することに加えて、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
レイアウト ファイルに関する警告が 1 件あります: 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] ダイアログでオフにできます。
- [File] > [Settings](Windows の場合)または [Android Studio] > [Preferences](macOS または Linux の場合)を選択します。
- [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()
で問題を致命的に設定すると、メイン 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] ダイアログで、設定を確認します。
[Specific Inspection Scope] ダイアログに表示されるオプションは、プロジェクト、フォルダ、ファイルのどれを選択したかによって異なります。
- プロジェクト、ファイル、またはディレクトリを 1 つ選択すると、選択したプロジェクト、ファイル、またはディレクトリのパスが [Specific Inspection Scope] ダイアログに表示されます。
- 複数のプロジェクト、ファイル、またはディレクトリを選択すると、[Require Inspection Scope] ダイアログには、[Selected files] に対して選択したラジオボタンが表示されます。
検査対象を変更するには、他のいずれかのラジオボタンを選択します。[Specific Inspection Scope] ダイアログに表示されるすべてのフィールドの説明については、[Specific Inspection Scope] ダイアログをご覧ください。
- [Inspection profile] で、使用するプロファイルを選択します。
[OK] をクリックして検査を実行します。
図 4 は、[Inspect Code] の実行による lint とその他の IDE インスペクションの結果を示しています。
-
[Inspection Results] ペインで、エラーのカテゴリ、タイプ、または問題を開いて選択し、検査結果を表示します。
[Inspection Report] ペインには、[Inspection Results] ペインで選択したエラーのカテゴリ、タイプ、または問題のインスペクション レポートが表示され、エラーの名前と場所が表示されます。必要に応じて、問題の概要など、問題の解決に役立つその他の情報が検査レポートに表示されます。
[Inspection Results] ペインのツリービューで、カテゴリ、タイプ、または問題を右クリックして、コンテキスト メニューを表示します。
コンテキストに応じて、次のことができます。
- ソースに移動。
- 選択したアイテムを除外または含めます。
- 問題を抑制する。
- 設定を編集します。
- 検査アラートを管理します。
- 検査を再実行します。
ツールバー ボタン、コンテキスト メニュー項目、検査レポートのフィールドの説明については、 検査結果ツール ウィンドウをご覧ください。
カスタム スコープを使用する
次のように、Android Studio に用意されているカスタム スコープのいずれかを使用します。
- [Specific Inspection 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] を選択します。
[カスタム スコープ] リストの隣にあるその他アイコンをクリックします。
[Scopes] ダイアログが表示されます。
- ダイアログの左上隅にある ボタンをクリックして、新しいスコープを定義します。
- 表示された [Add Scope] リストで、[Local] を選択します。
プロジェクト内では、ローカル スコープと共有スコープの両方がコード インスペクション機能に使用されます。共有スコープは、スコープ フィールドを含む他のプロジェクト機能でも使用できます。たとえば、[Find Usages] の設定を変更するために [Edit Settings] をクリックすると表示されるダイアログには、共有スコープを選択できる [Scope] フィールドがあります。
- スコープに名前を付けて、[OK] をクリックします。
[Scopes] ダイアログの右ペインに、カスタム スコープを定義するためのオプションが表示されます。
- リストから [プロジェクト] を選択します。
使用可能なプロジェクトのリストが表示されます。
注: プロジェクトまたはパッケージのカスタム スコープを作成できます。手順は同じです。
プロジェクト フォルダを開き、カスタム スコープに追加するものを選択し、そのフォルダを含めるか除外するかを選択します。
- [Include]: このフォルダとその中のファイルを追加しますが、サブフォルダは追加しません。
- Include Recursively: このフォルダとそのファイル、さらにサブフォルダとそのファイルを含めます。
- [Exclude]: このフォルダとその中のファイルを除外しますが、サブフォルダは除外しません。
- [Exclude Recursively]: このフォルダとそのファイル、およびサブフォルダとそのファイルを除外します。
図 10 は、main フォルダと、java フォルダと res フォルダが再帰的に含まれていることを示しています。青色は部分的に含まれているフォルダを示し、緑色は再帰的に含まれているフォルダとファイルを示します。
- java フォルダを選択して [Exclude Recursively] をクリックすると、java フォルダとその下のすべてのフォルダとファイルが緑色でハイライト表示されなくなります。
- 緑色でハイライト表示された MainActivity.kt ファイルを選択して [除外] をクリックすると、MainActivity.kt は緑色でハイライト表示されなくなりますが、java フォルダの下のその他はすべて緑色のままです。
- [OK] をクリックします。リストの一番下にカスタム スコープが表示されます。
インスペクション プロファイルを確認、編集する
Android Studio には、lint とその他のインスペクション プロファイルがいくつか用意されています。これらのプロファイルは Android のアップデートによって更新されます。これらのプロファイルはそのまま使用することも、名前、説明、重大度、スコープを編集することもできます。プロファイルのグループ全体またはグループ内の個々のプロファイルを有効化または無効化することも可能です。
[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] ペインに、サポートされているインスペクションとその説明のリストが表示されます。