kotlinを部分的に利用するメモ

はじめに

の前後で、lombokを導入していたんですけど

Android Studio側で GUI Pluginが不正扱いされて認識せず・・。*1

AS上で赤い表示が出っぱなし、補完も効かない状態はやはり嫌なので

まずは modelクラス あたりをKotlin化しようかと*2


動作環境

  • macOS Sierra
  • 16G
  • HDDタイプのiMac
  • AS 3.0-Beta3
  • gradle plugin 2.3.3
  • gradle plugin 3.0-beta3
  • gradle runtime-4.1-bin

事前準備

な環境ができているとします

beta3記述でちょっとハマった所

gradle-3.0-beta3 plguinだと下記でハマりました。

espresso-core が multidex 1.0.2依存だけど、1.0.2が正常にダウンロードできないからエラー

これは今日で強制的に1.0.1に変更してとりあえずビルド通しました*3

  • root/build.gradle
buildscript {
  ext.multidex_version="1.0.1"
    configurations.all {
        resolutionStrategy {
            force 'net.sf.proguard:proguard-gradle:5.3.3'
            force "com.android.support:multidex:$multidex_version" //◎
        }
    }
}
  • app/build.gradle
     androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
        exclude group: 'com.android.support', module: 'multidex' //◎
    })
    testCompile 'junit:junit:4.12'
    androidTestCompile 'com.google.code.findbugs:jsr305:3.0.1'
    
    debugCompile "com.android.support:multidex:$multidex_version" //◎
  • app/build30.gradle
     androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
        exclude group: 'com.android.support', module: 'multidex' //◎
    })
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.google.code.findbugs:jsr305:3.0.1'
    
    debugImplementation "com.android.support:multidex:$multidex_version" //◎

環境構築

事前準備の記述からの変更点

メイン部

  • root/build.gradle
buildscript {
    //==== ココから追加 ======
    ext.kotlin_version = '1.1.4-3'
    if(project.hasProperty('_use30Plugin'))
        ant.echo "_use30Plugin="+ _use30Plugin
        
    if(project.hasProperty('_use30Plugin') && _use30Plugin == 'true'){
        ext.gradle_plugin_version = '3.0.0-beta3'//★
    }
    else{
        ext.gradle_plugin_version = '2.3.3'//★
    }
    //==== ココまで追加 ======
    
    repositories {
        jcenter()
        maven { url 'https://maven.fabric.io/public' }
        maven { url "https://plugins.gradle.org/m2/" }
        google()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:$gradle_plugin_version"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" //★★追加
    }

★に関しては、あとで記載しますが kapt が [2.3.+] みたいな書き方を許さない状況のよう

アプリ部

  • app/build.gradle
apply plugin: 'com.android.application'

//use kotlin
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

android{

    dataBinding {
        enabled = true
    }
    //TODO:data-bindingの変換がたまにコケるので必須 ■■
    kapt {
        generateStubs = true
     }
}

dependencies {
    //TODO:glide 4.0
    compile 'com.github.bumptech.glide:glide:4.0.0'

    //annotationProcessor 'com.github.bumptech.glide:compiler:4.0.0' //★★★
    kapt 'com.github.bumptech.glide:compiler:4.0.0'
    compile 'com.github.bumptech.glide:okhttp3-integration:4.0.0'
    compile 'com.github.bumptech.glide:recyclerview-integration:4.0.0@aar'

    //TODO:glide 3.0
    //compile 'com.github.bumptech.glide:glide:3.8.0'
    //compile 'com.github.bumptech.glide:okhttp3-integration:1.5.0@aar'



    //provided "org.projectlombok:lombok:1.16.18"
    //use kotlin
    if(_JavaVersion as String == "VERSION_1_7"){//◎◎
        compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
    }
    else{
        compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
    }
    kapt "com.android.databinding:compiler:$gradle_plugin_version"
}
  • app/build30.gradle
apply plugin: 'com.android.application'

//use kotlin
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

android{

    dataBinding {
        enabled = true
    }
    //TODO:data-bindingの変換がたまにコケるので必須 ■■
    kapt {
        generateStubs = true
     }
}

dependencies {
    //TODO:glide 4.0
    implementation 'com.github.bumptech.glide:glide:4.0.0'

    //annotationProcessor 'com.github.bumptech.glide:compiler:4.0.0' //★★★
    kapt 'com.github.bumptech.glide:compiler:4.0.0'
    implementation 'com.github.bumptech.glide:okhttp3-integration:4.0.0'
    implementation 'com.github.bumptech.glide:recyclerview-integration:4.0.0@aar'

    //TODO:glide 3.0
    //implementation 'com.github.bumptech.glide:glide:3.8.0'
    //implementation 'com.github.bumptech.glide:okhttp3-integration:1.5.0@aar'



    //compileOnly "org.projectlombok:lombok:1.16.18"
    //use kotlin
    if(_JavaVersion as String == "VERSION_1_7"){//◎◎
        implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
    }
    else{
        implementation "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
    }
    kapt "com.android.databinding:compiler:$gradle_plugin_version"
}
  • ■■
    • data-bindingを併用するとたまにコンパイルエラーが出て悩むのですが、この対策を入れて安定しました*4
  • ★★★ 
    • kotlin pluginを入れた時点でannotationProcessorは一切動かなくなるのでkaptに変更が必要
  • ◎◎
    • kotlin はJDKのバージョンに依存

あと予想通り、kaptだとapt変換(annotationProcesser)が安定して動きました。

バージョン固定にさせることといい独自で変換してるんだろうな・・*5


Glide 4.0の話

このタイミングでGlideのバージョンを変更したのですが、4.0からannotationProcessorを使う形になりましたね

GlideModuleは、Dagger2を使う形のようです

でもAS3.0だと中々認識せず、permission Dispatcher pluginのように一度ビルドする必要があり

一応公式のDocと下記を読んで対応していたんですけど、ところどころ分からなくて結局sampleのコード実装見るほうが早い感じでした

bumptech.github.io

記述修正

kotlin pluginをいれて[Convert Java To Kotlin] あたりまでは変わらず

殆どは Null許可有りのval 変数に変換されるのがデフォルトっぽい

変換後の手修正箇所

  1. annotation除去
  2. 変換後の記述を手修正
    1. getterのみ => val
    2. getter/setter => var
    3. 外向けアクセスさせるにはprivate属性は外す
    4. static変数は companion object で囲む

まあ大体は変換後にこまめにコンパイルすることで気づける

package com.example.foo.bar;

import lombok.Getter;
import lombok.Setter;

import com.google.gson.annotations.Expose

@Getter
@Setter
public class Greeting {
    private final static String TAG = Greeting.class.getSimpleName()

    private String id;
    private ArrayList<String> list = new ArrayList<>();

    @Expose
    private String content;
    
}

=>

package com.example.foo.bar;

import com.google.gson.annotations.Expose

class Greeting {
    //static 変数
    companion object {
        private val TAG = Greeting::class.java.simpleName
    }

    var id: String? = null

    //val list: ArrayList<String>? = null
    // => 記述修正
    val list: ArrayList<String>
    init {
        list = ArrayList()
    }

    @Expose
    var content: String? = null
}

参考にした情報

あとで追記予定

qiita.com qiita.com qiita.com

www.slideshare.net

*1:まあこれkotlinのAnko pluginも同じなのだが・・・

*2:現時点ではkotlinとjavaは混在可能なので

*3:gradle plugin 2.3.3の場合は何故か問題なし・・・

*4:gradle runtime 4.1 だとマルチスレッドビルドしてるから、偶にタイミング的にずれることが有るみたい

*5:安定動作?のために既存のannotationProcesserをちゃんと殺してるし・・