今更遅れてDataBinding事始め(1)[環境構築]

前提的な話

AS 2.2の環境にして、ライブラリを最新化してしまうと下記ぐらいの記述で既にMultiDex対応になってしまう状態です。

  • appcompatベースのプロジェクトを新規作成して
  • map系のアプリを作ろうとする(Field Tripみたいな)

ぐらいのレベルで。。。。

完全に環境富豪すぎる状態なんですよね。。*1

  • ROOT/build.gradle
buildscript {
    dependencies {
        classpath 'com.google.gms:google-services:3.0.0'
    }
}
  • app/build.gradle
project.ext{
    supportVersion="24.2.+"
    googlePlayVersion="9.6.+"
}

dependencies {
    compile "com.android.support:appcompat-v7:$supportVersion"
    compile "com.android.support:design:$supportVersion"
    compile "com.android.support:support-v4:$supportVersion"
    //compile "com.android.support:recyclerview-v7:$supportVersion"  //☆ココまで到達できない ><

    compile "com.google.android.gms:play-services-maps:$googlePlayVersion"
    compile "com.google.android.gms:play-services-location:$googlePlayVersion"
    //compile "com.google.android.gms:play-services-ads:$googlePlayVersion"//☆ココまで到達できない ><
    //compile "com.google.android.gms:play-services-wearable:2.0.+"  //☆ココまで到達できない ><
}

// 一番下に追加
apply plugin: 'com.google.gms.google-services'

他の support-library/google-play-services の記述は下記参照

support-v4 は既に細分化されているよう*2


で、Multidexどうせ使うなら databindingを使おうと。

ButterKifeと違い双方向が出来るようですし。。

その代わり Multidexは target-14 からの動作する形ですので*3

Android 4.0.3 以下は切り捨てるイメージとなります*4

環境設定編(前提編)

  • JAVA 1.7まで現時点でサポート。
    • JAVA 1.8はサポートしていないので jackOptions は使えません *5
      • Retrolambda/RoboVM とかと共用は不可
      • まあラムダ式つかいたいだけであれば RxAndroid or kotlin 使えば?という指摘もあるのですけど・・
    • target-sdk 24 指定した場合は JAVA 8のJava SDKが必要なんですけどね。でもcompile Option は JAVA 7というジレンマ。。

環境設定編(記述編)

  • app/build.gradle
android {
    dataBinding {
        enabled = true
    }
    
    defaultConfig {
        if(dataBinding.enabled){
            multiDexEnabled true
        }   
    }

    dexOptions {
        dexInProcess = true
        javaMaxHeapSize "2g"
    }
    
    compileOptions {
        encoding="UTF-8"
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }
}

dependencies {
    if(android.dataBinding.enabled){
        compile 'com.android.support:multidex:1.0.1'
    }   
}

databindingは、凄いデカいライブラリなので multidexはほぼ必須です*6

databinding も昔はdependencyに記述されていましたけど

multidexもそのうちdependency記述いらなくなるんですかね・・

前提条件として必要なら早くそうなって欲しいものです

Multidex対応

  • databinding有効記述(build.gradle)
  • multidex有効記述(build.gradle)
  • multidex dependency記述(build.gradle)

だけで何故か動いてしまっている。

multidexのライブラリがclasspathにあれば内部で勝手に使って動いてしまう挙動。

まあ完全動作テストしてるわけでもないので、Multidex作法の対応は入れておく

  • app/AndroidManifest.xml
<application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        android:name="hoge.fuga.MyApplication">
  • app/MyApplication.java
public class MyApplication extends Application {
    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
    }
}

動かないときに疑う処

  • APTを使ったライブラリがないか?

databinding自体、内部でaptを使用して生成しているためライブラリの不一致で動かなくなることがあるとのこと

  • ROOT/build.gradle
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.+'
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'  //★現在マッチングしてるversion
    }
}
  • app/build.gradle
apply plugin: 'android'
apply plugin: 'android-apt' // add : ★apt用のプラグインを呼び出す



dependencies {
    compile 'net.vvakame:jsonpullparser-core:1.6.2' // add : jsonPullParserのcoreをdependenciesに指定する
    apt 'net.vvakame:jsonpullparser-apt:1.6.2' // add : ★aptをdependencies指定する
}

対策(use APT plugin)

現在、android gradle plugin 2.2.+ に対応している apt pluginは 1.8 ですが

時折pluginのアップデートで動かなくなる場合があります。

更新版のpluginがすぐ出ればいいのですが、それが出るまでの暫定対処法方は下記になります

  • 一旦 gradle:2.1.+ とかAPTが動くバージョンにしてAPTコードを生成
    • GradleSync の段階で生成できますのでこの状態で確認
  • 生成したXXXGen.java を本体側のsrcにコピー
    • 昔はSourceSet記述で別フォルダ参照追加できたが、gradle:2.2.+ のチェックTaskで怒られるのでこの対応は不可
  • 上記のAPTの★の箇所をコメントにする
  • gradle:2.2.+ に戻す

使用感

な簡単だよーな記事がありますが、試してみると正直キツイ。。

少しずつ置き換えていくほうが良いかと思います。

そこら辺は次回以降でまとめようかと

ReleaseBuild時の対策

ビルドが通らない

下記はandroid gradle plguin 2.2.X 依存の問題かもしれない

  • app/proguard-rules.pro
-keepattributes EnclosingMethod
-dontwarn android.databinding.**

実行時にエラーで落ちる

visible true さんのブログで書かれていた話ですが、確かに落ちますねorz

  • app/build.gradle
android {
  defaultConfig {
    multiDexEnabled = true
    multiDexKeepProguard file('multi-dex-keep.txt') //☆
  }
}
  • app/multi-dex-keep.txt
-keep public class * extends android.databinding.ViewDataBinding {
 *;
}

*1:AndroidのSlackでもココらへん言及されている方がいました。こちらはmapの新規プロジェクトを作っただけで同じ状態になったそうですが。。

*2:ただaar内部のAndroidManifest.xml は minsdk 9 に一律変更されているようですが。。

*3:それより下はコンパイルは出来るがエラーにしていないだけ

*4:まあ Multidexがちゃんと快適に動くのは target-23<OS5.0>かららしいので、OS4.0系はとりあえずコンパイル通るだけ?

*5:まあ今の時点でJackOptionは凄いシンプルなやつしかコンパイル通らないので無考慮で良いかもしれませんが

*6:まずビルドが通らない