Lint によるコードの改善

機能要件を満たしていることを確認するために Android アプリをテストすることに加えて、コードに構造上の問題がないか確認することが重要です。コードの構造が適切でないと、Android アプリの信頼性と効率性に影響が生じて、コードの保守が困難になることがあります。たとえば、XML リソース ファイルに未使用の名前空間が含まれていると、スペースを必要とし、不要な処理が発生します。サポートを終了した要素またはターゲットの API バージョンでサポートされていない API 呼び出しなど、構造に関するその他の問題があると、コードが正しく実行されなくなることがあります。

概要

Android Studio には lint と呼ばれるコード検査ツールがあり、これを利用するとアプリを実行したりテストケースを作成したりしなくても、コード構造の品質に関する問題を特定して修正することができます。このツールでは、検出された問題に加えて、それぞれの問題の内容を説明するメッセージと重要度も報告されるため、重要度の高い改善項目を迅速に特定して、優先的に実施することができます。プロジェクトと関係のない問題は重要度を下げて無視したり、特定の問題に注目するために重要度を上げたりすることもできます。

lint ツールでは、Android プロジェクトのソースファイルをチェックして、潜在的なバグを検出するほか、正確性、セキュリティ、パフォーマンス、ユーザビリティ、アクセシビリティ、国際化について最適化するための改善点を特定します。Android Studio を使用すると、アプリをビルドするたびに、設定済みの lint および IDE インスペクションが実行されます。ただし、手動によるインスペクションの実行コマンドラインからの lint の実行も可能です。

注: Android Studio でコードをコンパイルすると、追加で IntelliJ コード インスペクションが実行されるため、より効率的にコードのレビューができます。

図 1 に lint ツールでアプリケーションのソース ファイルを処理する方法を示します。

図 1. lint ツールを使用したコード検査のワークフロー

アプリケーション ソース ファイル
Android プロジェクトを構成するソースファイルで、Java や XML のファイル、アイコン、ProGuard 設定ファイルなどが含まれます。
lint.xml ファイル
実行する lint チェックの指定、および問題の重要度をカスタマイズするために使用する設定ファイルです。
lint ツール
Android プロジェクトに対して実行可能な静的コード スキャン ツールです。コマンドラインから、または Android Studio から利用できます(手動によるインスペクションの実行をご覧ください)。lint ツールでは、Android アプリの品質とパフォーマンスに影響するおそれのあるコードの構造上の問題をチェックします。lint で検出されたエラーをすべて修正してからアプリを公開することを強くお勧めします。
lint チェックの結果
lint チェックの結果は、コンソール上、または Android Studio の [Inspection Results] ウィンドウで確認できます。手動によるインスペクションの実行をご覧ください。

コマンドラインからの lint の実行

プロジェクト ディレクトリにあるファイルのリストに対して lint を実行するには、次のコマンドを使用します。

lint [flags] <project directory>

たとえば、次のコマンドを実行すると、myproject ディレクトリとそのサブディレクトリにあるファイルを検査できます。問題 ID MissingPrefix は、Android 名前空間接頭辞のない XML 属性のみをスキャンするように lint に指定します。

lint --check MissingPrefix myproject 

このツールでサポートされているフラグとコマンドライン引数の一覧は、次のコマンドで確認できます。

lint --help

lint の出力例

次の例は、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 つ含まれており、エラーはありません。警告のうち 3 つ(ManifestOrderUsesMinSdkAttributesUnusedResources)はプロジェクトの AndroidManifest.xml ファイルに関するもので、1 つ(IconMissingDensityFolder)は Preferences.xml レイアウト ファイルに関するものです。

Gradle を使用した lint の実行

プロジェクトにビルド バリアントが含まれている場合は、Gradle ラッパーを使用してプロジェクトのルート ディレクトリから次のいずれかのコマンドを実行することにより、すべてのバリアントに対して lint タスクを呼び出すことができます。

  • Windows の場合:
    gradlew lint
    
  • Linux または Mac の場合:
    ./gradlew lint
    

代わりに特定のビルド バリアントに対してのみ lint タスクを実行するには、バリアント名の頭文字を大文字にして、lint 接頭辞を付ける必要があります。

gradlew lintDebug

lint ツールによるチェックが完了すると、XML バージョンと HTML バージョンの 2 種類の lint レポートのパスが表示されます。コマンドラインから Gradle タスクを実行するための詳しい方法については、コマンドラインからのアプリ作成をご覧ください。

lint の設定

デフォルトでは、lint スキャンを実行すると、lint でサポートしているすべての問題がチェックされます。lint でチェックする問題を限定したり、それらの問題の重要度を指定することもできます。たとえば、プロジェクトに関係のない特定の問題に対する lint チェックを無効にしたり、重要でない問題を低い重要度で報告するように lint を設定したりできます。

lint チェックはさまざまなレベルに対して設定できます。

  • グローバル(プロジェクト全体)
  • プロジェクト モジュール
  • プロダクション モジュール
  • テスト モジュール
  • 開いているファイル
  • クラス階層
  • バージョン管理システム(VCS)のスコープ

Android Studio での lint の設定

Android Studio の使用中に、ビルトイン lint ツールによってコードがチェックされます。警告とエラーは以下の 2 通りの方法で表示できます。

  • コードエディタ内のポップアップ テキスト。lint で問題が検出されると、問題のあるコードが黄色でハイライト表示されます。さらに重大な問題の場合は、コードに赤い下線が表示されます。
  • lint で [Analyze] > [Inspect Code] の順にクリックして表示される [Inspection Results] ウィンドウ。手動によるインスペクションの実行をご覧ください。

lint ファイルの設定

lint チェックの優先度を lint.xml ファイルで指定できます。このファイルを手動で作成する場合は、Android プロジェクトのルート ディレクトリに置いてください。

lint.xml ファイルは 1 つの <lint> 親タグで構成され、親タグで囲まれた範囲には 1 つ以上の <issue> 子要素があります。lint では、<issue> ごとに一意の id 属性値が定義されます。

<?xml version="1.0" encoding="UTF-8"?>
    <lint>
        <!-- list of issues to configure -->
</lint>

<issue> タグ内で重要度属性を設定することにより、問題の重要度を変更したり、問題に対する lint チェックを無効にしたりできます。

ヒント: lint でサポートしている問題と、対応する問題 ID の一覧を確認するには、lint --list コマンドを実行します。

サンプル lint.xml ファイル

次の例は、lint.xml ファイルの内容を示しています。

<?xml version="1.0" encoding="UTF-8"?>
<lint>
    <!-- Disable the given 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>

Java および XML ソースファイルの lint チェックの設定

Java および XML のソースファイルの lint チェックは無効にすることができます。

ヒント: Java または XML のソースファイルの lint チェック機能は、[Default Preferences] ダイアログで管理できます。[File] > [Other Settings]、[Default Settings] の順に選択し、[Default Preferences] ダイアログの左のパネルから [Editor] > [Inspections] の順に選択します。

Java での lint チェックの設定

Android プロジェクトで特定の Java クラスまたはメソッドに対する lint チェックを無効にするには、@SuppressLint アノテーションを対象の Java コードに追加します。

次の例では、onCreate メソッドに対する NewApi 問題の lint チェックを無効にしています。このクラスにある他のメソッドに対しては、引き続き NewApi 問題の lint チェックが行われます。

@SuppressLint("NewApi")
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

次の例では、FeedProvider クラスに対する ParserError 問題の lint チェックを無効にしています。

@SuppressLint("ParserError")
public class FeedProvider extends ContentProvider {

Java ファイルで、すべての問題に関する lint チェックを行わないようにするには、次のように all キーワードを使用します。

@SuppressLint("all")

XML での lint チェックの設定

tools:ignore 属性を使用すると、XML ファイルの特定のセクションに対する lint チェックを無効にできます。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 ファイル内で lintOptions {} ブロックを使用すると、実行するチェック、無視するチェックなどの特定の lint オプションを設定できます。次のコード スニペットは、設定可能なプロパティの一部を示しています。

android {
  ...
  lintOptions {
    // 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.
    check '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 true, only report errors.
    ignoreWarnings true
  }
}
...

手動によるインスペクションの実行

[Inspect Code] > [Analyze] の順に選択することで、設定済みの lint およびその他の IDE インスペクションを手動で実行できます。インスペクションの結果は [Inspection Results] ウィンドウに表示されます。

インスペクションのスコープとプロファイルの設定

分析するファイル(インスペクション スコープ)と実行するインスペクション(インスペクション プロファイル)を次のように選択します。

  1. [Android] ビューで、プロジェクトを開き、分析するプロジェクト、フォルダ、またはファイルを選択します。
  2. メニューバーから [Analyze] > [Inspect Code] の順に選択します。
  3. [Specify Inspection Scope] ダイアログで、設定を確認します。 インスペクション スコープの指定

    図 2. インスペクション スコープ設定を確認

    [Specify Inspection Scope] ダイアログに表示されるオプションの組み合わせは、プロジェクト、フォルダ、ファイルのどれを選択したのかによって異なります。他のラジオボタンを選択すると、インスペクションの対象を変更できます。[Specify Inspection Scope] ダイアログに表示される可能性のあるすべてのフィールドついては、[Specify Inspection Scope] ダイアログの説明をご覧ください。

    • プロジェクト、ファイル、またはディレクトリを 1 つ選択すると、選択したプロジェクトファイル、またはディレクトリのパスが [Specify Inspection Scope] ダイアログに表示されます。
    • 複数のプロジェクト、ファイル、またはディレクトリを選択すると、[Specify Inspection Scope] ダイアログには、選択したファイルに対してオンになったラジオボタンが表示されます。
  4. [Inspection profile] は、既定のプロファイル([Project Default])のままにします。
  5. [OK] をクリックしてインスペクションを実行します。図 3 に [Inspect Code] から実行した lint とその他の IDE インスペクションの結果を示します。

    図 3. 問題を選択して解決策を確認

  6. 左側のパネルのツリービューで、エラーのカテゴリ、タイプ、問題を展開して選択し、インスペクションの結果を表示します。

    右側のパネルには、選択したカテゴリ、タイプ、または問題のインスペクション レポートが表示され、エラーの名前と場所が示されます。場合によっては、問題修正に役立つ問題の概要説明などの情報もインスペクション レポートに表示されます。

  7. 左側のパネルのツリービューで、カテゴリ、タイプ、または問題を右クリックしてコンテキスト メニューを表示します。

    コンテキストに応じて、ソースへの移動、選択したアイテムの除外または追加、問題の除外、設定の編集、インスペクション アラートの管理、インスペクションの再実行のすべてまたは一部を実施できます。

左側のツールバー ボタン、コンテキスト メニュー、インスペクション レポートのフィールドついては、Inspection Tool ウィンドウの説明をご覧ください。

カスタム スコープの使用

Android Studio に用意されている任意のカスタム スコープを次のように使用できます。

  1. [Specify Inspection Scope] ダイアログで、[Custom scope] をクリックします。
  2. [Custom scope] プルダウン リストをクリックしてオプションを表示します。

    インスペクション スコープの選択

    図 4. 使用するカスタム スコープの選択

    • [Project Files]: 現在のプロジェクトにあるすべてのファイル。
    • [Project Production Files]: 現在のプロジェクトにあるプロダクション ファイルのみ。
    • [Project Test Files]: 現在のプロジェクトにあるテスト ファイルのみ。テストのタイプと場所をご覧ください。
    • [Open Files]: 現在のプロジェクトで開いているファイルのみ。
    • [Module <your-module>]: 現在のプロジェクトの対応するモジュール フォルダにあるファイルのみ。
    • [Current File]: 現在のプロジェクトにある現在のファイルのみ。単一のファイルまたはフォルダを選択してある場合のみ表示されます。
    • [Class Hierarchy]: このオプションを選択して [OK] をクリックすると、現在のプロジェクトにあるすべてのクラスを表示したダイアログが表示されます。インスペクトするクラスの絞り込みと選択を行うには、ダイアログの [Search by Name] フィールドを使用します。クラスリストの絞り込みを行わない場合、すべてのクラスがコード インスペクションによって調査されます。
  3. [OK] をクリックします。

カスタム スコープの作成

現在使用可能ないずれのカスタム スコープでも対応していないファイルやディレクトリのセットを調査するには、カスタム スコープを作成します。

  1. [Specify Inspection Scope] ダイアログで、[Custom scope] を選択します。
  2. [Custom Scope] プルダウン リストの横にある省略記号をクリックします。

    図 5. [Specify Inspection Scope] ダイアログ

    [Scopes] ダイアログが表示されます。

    図 6. カスタム スコープの作成

  3. [Add] をクリックして 新しいスコープを定義します。
  4. 表示される [Add Scope] プルダウン リストで [Local] を選択します。

    プロジェクト内では、ローカルと共有の両方のスコープが、Inspect Code 機能に使用されます。[Shared] スコープはスコープ フィールドのある他のプロジェクト機能でも使用できます。たとえば、[Edit Settings] をクリックして [Find Usages] の設定を変更する場合、表示されるダイアログには [Scope] フィールドがあり、そこで共有スコープを選択できます。

    図 7. [Find Usages] ダイアログでの共有スコープの選択

  5. スコープに名前を付け、[OK] をクリックします。

    [Scopes] ダイアログの右側のパネルには、カスタム スコープを定義するためのオプションが表示されます。

  6. プルダウン リストから [Project] を選択します。

    使用可能なプロジェクトのリストが表示されます。

    注: プロジェクトまたはパッケージのカスタム スコープを作成できます。いずれの場合も手順は同じです。

  7. プロジェクト フォルダを展開し、カスタム スコープに追加するアイテムを選択してから、右側にあるいずれかのボタンをクリックします。

    図 8. カスタム スコープの定義

    • [Include]: このフォルダとフォルダ内のファイルを追加しますが、サブフォルダは追加しません。
    • [Include Recursively]: このフォルダとフォルダ内のファイルに加え、サブフォルダとサブフォルダ内のファイルを追加します。
    • [Exclude]: このフォルダとフォルダ内のファイルを除外しますが、サブフォルダは除外しません。
    • [Exclude Recursively]: このフォルダとフォルダ内のファイルに加え、サブフォルダとサブフォルダ内のファイルを除外します。

    図 9 では、main フォルダが追加されており、java フォルダが再起的に追加されています。青は部分的に追加されているフォルダを示し、緑は再帰的に追加されているフォルダとファイルを示します。

    図 9. カスタム スコープのパターン例

    • java フォルダを選択して [Exclude Recursively] をクリックすると、java フォルダと、その下のすべてのフォルダやファイルが緑色でハイライト表示されなくなります。
    • または、緑色でハイライト表示された MainActivity.java ファイルを選択して [Exclude] をクリックすると、MainActivity.java は緑色でハイライト表示されなくなりますが、java フォルダの下にある他のアイテムはすべて緑色でハイライト表示されます。
  8. [OK] をクリックします。カスタム スコープがプルダウン リストの下部に表示されます。

インスペクション プロファイルの確認と編集

Android Studio では、Android アップデートによって更新される、lint などのインスペクション プロファイルが複数提供されています。これらのプロファイルはそのまま使用することも、名前、説明、重要度、スコープを編集することもできます。プロファイルのグループ全体またはグループ内の個々のプロファイルの有効化と無効化も可能です。

[Inspections] ダイアログにアクセスする方法は次のとおりです。

  1. [Analyze] > [Inspect Code] の順に選択します。
  2. [Specify Scope] ダイアログで、[Inspection Profile] の下にある [More] をクリックします。

    サポートされているインスペクションとその説明のリストを含む [Inspections] ダイアログが表示されます。

    図 10. サポートされているインスペクションとその説明

  3. [Default](Android Studio)インスペクションと [Project Default](アクティブ プロジェクト)インスペクションを切り替えるには、[Profile] プルダウン リストを選択します。詳細については、IntelliJ の Specify Inspection Scope ダイアログのページをご覧ください。
  4. [Inspections] ダイアログの左側のパネルで、トップレベルのプロファイル カテゴリを選択するか、グループを展開して特定のプロファイルを選択します。プロファイル カテゴリを選択すると、このカテゴリに含まれているすべてのインスペクションを単一のインスペクションとして編集できます。
  5. インスペクションのコピー、名前の変更、説明の追加、エクスポート、インポートを行うには、[Manage] プルダウン リストを選択します。
  6. 完了したら、[OK] をクリックします。