ここが変だよ、AndroidStudio2.0 preview2

この記事は、モバイルDevOps Advent Calendar 2015 - Qiita の 7 日目の記事です。

の方で書こうかなと思ったけど

の「イヤになるAndroid Studio」な講演がされるぐらい
Androidネタが嫌いというか興味ない層が多い *1 ので
こちらに書きます。

まあG*界隈の人は、ASはIntelliJの布教素材としてしかみてないからな。。
それ以前に、日本だとiOSマンセーandroid蔑視な文化が未だにあるけど
i開発作業者が人募集した時に集まらないのも有るんでしょうね。。
しかもSwiftじゃなくObj-Cの人。。<苦笑



AS2.0に移行して困ったこと

  • IDEレイヤー
    • ソースリンク形式のlib-projectを使ってる時productFlavorを追加するとおかしくなる
      • lib-projectのみビルドして転送しようとするorz
      • [変更がない場合ビルドしないで実行]辺りのチェック処理が怪しい
MainP
  Flavor x BuildType(release/debug)
LibP
  BuildType(release/debug)

で、LibPのみコンパイルして転送する挙動が。。。(汗

一応 コマンドライン/ASのTerminal で
> gradlew assembleDebug をすると正常に実行できる
ただし
なぜか LibPの release.aar をビルドしてくっつけようとする><

Flavor自体を設定する前は、正常に動くので

MainP
  BuildType(release/debug)
LibP
  BuildType(release/debug)

InstantRunを動かすために、なにかおかしくしてしまっているくさい気がする*2

  • gradlew pluginレイヤー

gradlew taskコマンドで
BuildType x Flavorの一覧が出てこない。pecoで実行時に困る><

group="build" が android gradle plugin 2.0.xだと 設定されていないから

tasks.whenTaskAdded { task ->
    if (task.name.indexOf("assemble")!=-1) {
        task.group = "build"
    }
}

対処策として)

  • build.gradle をIDE編集用とコマンドビルド用に分ける

が思いつくわけですが

> gradlew assembleDebug -b build_staging.gradle -c settings.gradle
みたいな形で実行しようとすると失敗する。

  • -b で指定するときはgradleの仕様としてマルチプロジェクト扱いはしないらしい
    • -cのオプションを無視
  • -cのみであれば認識する

こうなると

  • settings.gradle
ext{
   flavorEnable=false
}

等を定義して差し替える&build.gradle上で頑張る のが現状としては一番の方法かもしれない

勿論下の方のInstantRunで検証してるような aar化してバイナリとして
直参照すれば、settings.gradle自体要らないので

  • -b 運用は問題なくなるけどね。。。

よくこの手の話をググる
> local Repoにuploadなタスクってわかんねー
な話で相談されて、大事になるけど
flatDirで指定すればいいだけなので。。

まあそもそも IDEA自体がシングルプロジェクトのIDE なのに
無理やりlibrary projectのマルチプロジェクト構成に対応
するのが無理だったんだと思う・・・



Instant Runに関して

TL見てると
「InstantRunで爆速ウハウハだぜ〜」
というtwが矢鱈RTされてるんだけど、まず動かせなかった。

個人MacでQittaとかに指定されたサンプルなら動く?な感じですけどね*3

動かせなかった要因としては

  1. ADT export形式
  2. library-projectをsettings.gradle定義越しに参照している

あたり。

まず dex化時に dex時間/CPUがやたら食う問題に関しては
2つ目を
> gradlew assemble
して本体側にaarをコピーしてきて

repositories{                                             
        flatDir{                                              
            dirs "libs_aar"                                      
        }                                                     
}  

dependencies {
    releaseCompile(name:'google_play_services_froyo-release', ext:'aar')         
    debugCompile(name:'google_play_services_froyo-debug', ext:'aar')
} 

な感じにすればOKでした。

ということはInstantRun自体はマルチプロジェクトに対応してないのではないか疑惑が・・・

1つ目に関しては、
まだAndroid Plugin自体のsourceSetリマッピング対応になってないんだろうなという理解*4



おまけ)ASをWinで動かすために設定していること

自分だと
業務だと未だADT形式で、個人的にローカルでAS形式に対応させてつかつてます。
勿論デフォルトのままでは環境的に無理な設定なので色々とカスタマイズしてます。

  • AS自体の設定
set STUDIO_JDK=c:/opt/jdk8
export STUDIO_JDK=/opt/jdk8

と実行SDKを指定

みてASの設定ファイルを指定位置に編集して設置する。
64bitJDK8なら studio64.exe.vmoptions の方を弄ると。実行はstudio64.exeの方*6


ADTの設定と同じく

-Xms1024m
-Xmx1024m
-XX:PermSize=256m
-XX:MaxPermSize=256m

あたりかな。JDK8を使う場合は
> PermSize => MetaspaceSize
に修正する

  • gradle自体の修正
    • 通信でトラブルと固まるのでローカルにダウンロードしておく

gradle/wrapper/gradle-wrapper.properties

#distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
distributionUrl=file\:/c\:/opt/gradle-2.9-all.zip
  • AS上
    • Gradle>offline のチェックを付けておく
    • NWアクセスが必要な新規ライブラリを追加した場合は
      • Terminalより gradlew tasks を実行する
  • gradle.propeties

デフォルトの設定がナンセンスなので修正する

#org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
org.gradle.jvmargs=-Xms512m  -Xmx512m -XX:Flags=c:/opt/vm.option.txt -Dfile.encoding=UTF-8

org.gradle.workers.max=4 //CPUコア数
org.gradle.java.home=c:/opt/jdk8 //gradleを実行するJDK
  • /opt/vm.option.txt (JDK8用)
MetaspaceSize=128m
MaxMetaspaceSize=128m
+HeapDumpOnOutOfMemoryError
+UseConcMarkSweepGC
CMSInitiatingOccupancyFraction=15
    • G1GC版
MetaspaceSize=128m
MaxMetaspaceSize=128m
+UseG1GC 
G1HeapRegionSize=1m 
InitiatingHeapOccupancyPercent=15

の検証テストにあるようにG1GC自体は大容量メモリを効率的に動かすためのものらしいので、G1HeapRegionSizeは環境により修正する必要があり。
8G程度のWin7 64bit環境だと1MBぐらいだと最適でした。

で確保さえ出来れば最適な感じになるよう

JDK9あたりではG1GCがデフォルトになるので
ココらへんは試行錯誤しておいたほうがいいのかも

を参照してください

  • ログインアカウントによって.gradleのキャッシュを作りなおすのは困るよ〜な対策
    • gradlew.bat/gradlew の先頭に上記を追記しておく
set GRADLE_USER_HOME=C:/opt/.gradle
export GRADLE_USER_HOME=/opt/.gradle



でもオマケな環境 を作ってて ちょっと困った挙動がある。

> gradlew --stop

daemonプロセスを停止したと表示されているのに
javaとしてのプロセスが残ってて終了できないことが有り。

alias jkill=taskkill /f /im java.exe

あたりを定義して終了させていたりする。
windowsでのgradle daemonはやはり無理があるのか??

12/7追加検証)

gradleのworker taskがtask終了しても残ってしまう感じ。
今だと
> org.gradle.workers.max=4
で4スレッドに制限してるから、

  • taskがだんまりした?
    • gradle cleanすれば治るんじゃね?

とよくQittaにかかれている状況でも、実は jkillすると走りだす。
ようはゾンビスレッドが居て、新規タスク用のスレッド作れなくて止まってる状況orz。

gradleでこういうゾンビが出来る時ってtaskが正常終了していない時なので
gradle android pluginの 基底taskの作りがどうも悪いんだろうな。。と思う

新機能よりもうちょっと安定性を期待したいんだけどな。。
まだ正式版ではない?からしかたないのかな〜 ASもgradle pluginも。。(苦笑

*1:IntelliJ IDEA好きが多い

*2:ndk 用の external plugin もNDKデバックがまともに動かないみたいだし

*3:winではやはり無理でしたが dex化に2Gぐらいは必要??

*4:途中でエラーになるので

*5:JRokitと統合されているので速い

*6:Win7 64bitで32bit動かせな話がたまに出てくるけど、あれ32bitエミュレーションで若干遅いから。。<苦笑