LoginSignup
20
20

More than 5 years have passed since last update.

Android Gradle Plugin 0.12 → 0.13の変更点

Posted at

Android Gradle Plugin 0.13が9月にリリースされて2週間以上が経ち、既に記事を書かれている方もいらっしゃるので今更なのですが、個人的に重要と思う箇所があり0.12 → 0.13の変更点について詳細に確認してみました。
http://tools.android.com/tech-docs/new-build-system

対象は、現時点でリリースされている0.13.0から0.13.2までです。

実際の動作等は部分的にしか確認できていませんので、ご了承ください。
※伝聞調の書き方の部分は未確認と思ってください
※後日アップデートするかもしれません

0.13.0の変更点

Gradle 2.1以上が必要

これまでGradle 1.10+が必要でしたが、これではもう動かなくなりました。
Gradleラッパー(gradlew)を使っている場合は、gradle/wrapper/gradle.propertiesdistributionUrlのバージョン部分を以下のように2.1に修正する必要があります。

gradle.properties
distributionUrl=http\://services.gradle.org/distributions/gradle-2.1-all.zip

build.gradleに独自のスクリプトを書いている場合は、Gradle 2.1で使えなくなるものがないか確認する必要があるかもしれません。

テストアプリでAndroidManifestが定義可能に

テストアプリといっているのはconnectedAndroidTestなどのタスクで動かすInstrumentationTestCaseなどのことですが、これまでは Plugin がテスト用のManifestを自動生成していたため、独自の設定を入れたりすることができませんでした。
これは特にライブラリ開発の場合に重要です。

UIライブラリなどでは実際のActivityに組込んで動かさなければほとんどテストできないため、Activityから利用するテストケースを書きたくなりますが、Activityを呼び出すにはAndroidManifest<activity>の定義を書かなければなりません。
今まで、Android Gradle Pluginでのテストではこうした設定が書けなかったため、以下のような方法をとるしかありませんでした。

  • Activityを使わなくてもできる部分だけをテストする
  • テスト用のアプリを別プロジェクトとして用意してテストする
  • (ライブラリにテスト用のActivityを組込む)

例えば、パッケージcom.exampleをテストするActivityを使って以下のようにテストケースを書くとします。

java
package com.example.test;
:
public class ActivityTest extends ActivityInstrumentationTestCase2<DemoActivity> {

    private DemoActivity activity;

    public ActivityTest() {
        super(DemoActivity.class);
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        setActivityInitialTouchMode(true);
        activity = getActivity();
    }

この場合、AndroidManifestに以下のような定義を書く必要があり、今までは書いても無視されていたのですが0.13で取り込まれるようになりました。
(つまり、テスト専用のActivityを用意してライブラリをテストすることができます)

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.test">

    <application>
        <uses-library android:name="android.test.runner" />
        <activity android:name=".DemoActivity" />
    </application>

</manifest>

<instrumentation>は自動的に追加されます。

※この変更のおかげで、自分のUIライブラリの場合はJaCoCoによるカバレッジ計測で10%程度だったものが95%以上までカバーできるようになりました。

Android Studioでの注意点

現時点のBeta 0.8.6はこの仕組みに対応していないため、少々問題があります。

テスト用のR.javaが生成されない

テストアプリのpackageは末尾に.testがつく別アプリの位置づけになるため、R.javaは本体とは別になりますが、0.8.6ではこれがビルドされません。
Android Studioで認識させるには、一度コマンドラインで./gradlew connectedCheckなどでビルドする必要があります。
現時点のBeta Channelで配布されているAndroid Studio 0.8.9では解消しています。

テスト用AndroidManiest内のURIやActivity名が認識されない

以下のように赤字になってしまいますが、動作上は問題ないです。
これはAndroid Studio 0.8.9でも、Canary Channel最新の0.8.11でも未解決のようです。

Screenshot 2014-10-05 15.29.36.png

AndroidManifestの placeholder が Build Types でも設定可能に

AndroidManifestにおけるplaceholderというのは、Android Gradle Plugin 0.11で導入された(はずの)ものです。
AndroidManifest内に${xxx}の形式で記述しておき、build.gradleでその値を決定するものです。
例えば以下のように書いておき、ActivityのラベルをProduct Flavorごとに変えることができます。

build.gradle
    defaultConfig {
        applicationId "com.example"
        :
        manifestPlaceholders = [ activityLabelMain: "Example" ]
    }
    productFlavors {
        free {
            applicationId "com.example.free"
            manifestPlaceholders = [ activityLabelMain: "Example free" ]
        }
        pro {
            manifestPlaceholders = [ activityLabelMain: "Example pro" ]
        }
    }
AndroidManifest.xml
        <activity
            android:name=".MainActivity"
            android:label="${activityLabelMain}" >

上記では、installFreeDebugでインストールするとExample FreeinstallProDebugでインストールするとExample Proのラベルが表示されます。

これまでこの機能はProduct Flavorで利用可能でしたが、Build Typeでも使えるようになったようです。
同じ例を使うと、例えば以下のようにBuild Typeをラベルにくっつけることができます。

build.gradle
    defaultConfig {
        applicationId "com.example"
        :
        manifestPlaceholders = [ activityLabelMain: "Example" ]
    }
    productFlavors {
        free {
            applicationId "com.example.free"
            manifestPlaceholders = [ activityLabelMain: "Example free" ]
        }
        pro {
            manifestPlaceholders = [ activityLabelMain: "Example pro" ]
        }
    }
    buildTypes {
        // debugビルドのみ末尾に debug を付与
        debug {
            manifestPlaceholders = [ activityLabelSuffix: " debug" ]
        }
        release {
            :
            manifestPlaceholders = [ activityLabelSuffix: "" ]
        }
    }
AndroidManifest.xml
        <activity
            android:name=".MainActivity"
            android:label="${activityLabelMain}${activityLabelSuffix}" >

上記でビルドすると、ラベルは以下のようになります。

  • installFreeDebugExample Free debug
  • installFreeReleaseExample Free
  • installProDebugExample Pro debug
  • installProDReleaseExample Pro

ライブラリのAndroidManifestでplaceholderを定義可能に

ライブラリでも上記のplaceholderが利用できるようになったようです。
ライブラリ内で未解決のplaceholderは利用アプリ側で解決させることもできるようです。
(未確認です)

Variant.getMappingFile()でProGuardマッピングファイルが参照可能に

ProGuardを実行すると、難読化前後の名称のマッピングファイルが生成されますが、このファイルにbuild.gradleからアクセスできるようになったということのようです。

例えば、以下のようにすると、ProGuardをかけたVariantではマッピングファイルのオブジェクト(File)が取得できていることが分かります。

build.gradle
android {
    :
    productFlavors {
        free {
            :
        }
        pro {
            :
        }
    }
    buildTypes {
        debug {
            :
        }
        release {
            runProguard true
            :
        }
    }
    :
}

afterEvaluate { ->
    android.applicationVariants.each { variant ->
        println "mapping: ${variant.name}: ${variant.getMappingFile()?.path}"
    }
}
$ ./gradlew assemble
mapping: freeDebug: null
mapping: freeRelease: /xxx/app/build/outputs/proguard/free/release/mapping.txt
mapping: proDebug: null
mapping: proRelease: /xxx/app/build/outputs/proguard/pro/release/mapping.txt
:app:preBuild
:

※Issueとしては下記がありますが、アップデートがないため使い方等はよく分かりませんでした。
https://code.google.com/p/android/issues/detail?id=73737

DensityとABIでの複数APKへのSplitメカニズムを導入

詳細はApk Splitsにあります。
(未確認です)

バグ修正

(未確認です)

0.13.1の変更点

テスト用のManifestで<instrumentation>をマージできるように

上述のテスト用AndroidManifestでの<instrumentation>を自分で書いた場合にもマージされるようになったようです。
(未確認です)

uninstallAllタスクの修正

0.13.0で発生した不具合の修正のようです。
./gradlew uninstallAllを実行するとエラーが発生するようになっていたようです。
https://code.google.com/p/android/issues/detail?id=76388

設定不備があるとVariantが出力されずGradleの評価が失敗する問題を修正

(未確認です)

テストがない場合にconnectedCheckが失敗するように

これまではテストケースのないプロジェクトではconnectedCheckconnectedAndroidTestタスクを呼び出しても何事もなく通過していましたが、0.13.1ではテストケース(テストケースクラス)が一つもないとタスクが失敗するようになりました。

Screenshot 2014-10-05 15.40.40.png

テストが全くないプロジェクトで(テストでなくlint等を動かしたいために)取りあえずタスクを通過させるには、androidTest/javaディレクトリ以下に何らかのテストケースクラスを作ればOKです。

0.13.2の変更点

manifest mergerが不正な<uses-sdk>を追加するのを修正

0.13.1で発生した不具合の修正のようです。
下記のIssueなどでレポートされており、AndroidManifestのマージにより<uses-sdk>が複数出力されてしまう問題があったようです。
https://code.google.com/p/android/issues/detail?id=76612

補足

Issueは以下で検索して確認しています。
https://code.google.com/p/android/issues/list?can=1&q=label%3ASubcomponent-Tools-gradle&colspec=ID+Type+Status+Owner+Summary+Stars&cells=tiles

20
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
20