ここが変だよ、AndroidStudio2.0 preview2
この記事は、モバイルDevOps Advent Calendar 2015 - Qiita の 7 日目の記事です。
- 昨日は tnj - Qiitaさんの アプリ上でサーバの「メンテナンス中」をリアルタイムに伝える方法 - Qiita のお話です
- 明日は windowsでpecoを使う2 - exception thinkのお話です
の方で書こうかなと思ったけど
の「イヤになるAndroid Studio」な講演がされるぐらい
Androidネタが嫌いというか興味ない層が多い *1 ので
こちらに書きます。
まあG*界隈の人は、ASはIntelliJの布教素材としてしかみてないからな。。
それ以前に、日本だとiOSマンセーでandroid蔑視な文化が未だにあるけど
i開発作業者が人募集した時に集まらないのも有るんでしょうね。。
しかもSwiftじゃなくObj-Cの人。。<苦笑
AS2.0に移行して困ったこと
- IDEレイヤー
- ソースリンク形式のlib-projectを使ってる時productFlavorを追加するとおかしくなる
- lib-projectのみビルドして転送しようとするorz
- [変更がない場合ビルドしないで実行]辺りのチェック処理が怪しい
- ソースリンク形式のlib-projectを使ってる時productFlavorを追加するとおかしくなる
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
動かせなかった要因としては
- ADT export形式
- 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形式に対応させてつかつてます。
勿論デフォルトのままでは環境的に無理な設定なので色々とカスタマイズしてます。
- JDK8を使うように修正*5
- 勿論 作業場Winにインストーラで入れる権限はないので Windows版JDKをインストールせずに使用する。 - Qiitaあたりの対応は必須
- 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 のチェックを付けておく
- コマンドラインで実行するときは --offline付与する
- NWアクセスが必要な新規ライブラリを追加した場合は
- Terminalより gradlew tasks を実行する
- Gradle>offline のチェックを付けておく
- 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
MetaspaceSize=128m
MaxMetaspaceSize=128m
+HeapDumpOnOutOfMemoryError
+UseConcMarkSweepGC
CMSInitiatingOccupancyFraction=15
-
- G1GC版
MetaspaceSize=128m
MaxMetaspaceSize=128m
+UseG1GC
G1HeapRegionSize=1m
InitiatingHeapOccupancyPercent=15
の検証テストにあるようにG1GC自体は大容量メモリを効率的に動かすためのものらしいので、G1HeapRegionSizeは環境により修正する必要があり。
8G程度のWin7 64bit環境だと1MBぐらいだと最適でした。
@kimukou2628 そうです、G1 は断片化を生じさせません。(というより断片化はコンパクションをしない CMS GC のみ発生します)
JDK9あたりではG1GCがデフォルトになるので
ココらへんは試行錯誤しておいたほうがいいのかも
- GIGC詳細に関しては
を参照してください
- ログインアカウントによって.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も。。(苦笑