Android Studio を build.gradle に task追加の方向性で弄ってみる
情報整理エントリ
一応メモ途中)
数時間ほどNoClassDefFoundErrorと格闘した結果,Android StudioでNativeライブラリ(.so)とJavaライブラリ(.jar)を含むプロジェクトを動かせるようになった,後でブログに書く
2013-05-21 03:18:05 via web
@tondol 楽しみにしてます?
2013-05-21 09:49:39 via hamoooooon to @tondol
@kimukou2628 どもです〜!ビルドシステムについての理解が浅いので試行錯誤という感じですが……とりあえずこちらに公開しました URL
2013-05-21 16:25:35 via web to @kimukou2628
@tondol ありがとうございます。やはりtaskを作るしかない形なんですね(苦笑。NDKビルドをする場合現状だと同じようにtaskを作らないと駄目だと思われますがそこまで試されていらっしゃいますでしょうか?<たぶん直接makeFileを叩くようなイメージになってしまうかも
2013-05-21 16:37:15 via YoruFukurou to @tondol
@kimukou2628 NDKビルドまではまだ試していませんが、おっしゃる通りndk-buildをtaskで実行するような形で実現できそうですね。Gradleを勉強しつつ、近々試してみたいと思います。
Android Studioで外部ライブラリを使うアプリを実行する - FLYING URL 書きました
というお話があったので弄ってみると。
こういう構成で自分が馴染みがあるのはMedibaAd さんの構成だよねー*1って ことで
その構成で試してみようと思ってたら
あー。android DSLの所で書けば ごにょごにょいじれるのか‥‥‥
上のほうの例と同様に外部task登録してって認識だったので
そう考えれば確かにあってますね。。。(汗
実際のbuild.gradleの中を見てみると
android { //〜略〜 tasks.withType(Compile) { compileTask -> compileTask.dependsOn ndkBuild } }
のコンパイルタスクへの割込のやり方も凄いと思った*2
まだまだGradle勉強足りないorz
上記のbuild.gradleのコピーだけでいけたけど
javaのライブラリも必要だったので
dependencies { compile fileTree(dir: 'libs', includes: ['*.jar']) }
これだとjniフォルダがない場合でも
上のsoをコピーしてくれる用途とかでは使えないので(ndk buildがいらない)場合は
android { //〜略〜 if(new File(projectDir,"jni").exists()){ tasks.withType(Compile) { compileTask -> compileTask.dependsOn ndkBuild } } }
と記述は直さないと駄目かも
追記>
dependencies {
compile 'mediba.ad.sdk.android.openx:MasAdView:2.0.2:so:armeabi'
}
みたいな書き方でもいいみたいな話も‥‥‥色々と書けるんですね。。。
あたりをば追加して試したぐらい?。でも殆どLibraryProject使ってるから
残念ながら使いドコロが微妙だったりしますorz
sourceSets { main { } println "[sourceSets.main]${main.dump()}" //☆ }
追加してdumpしてみた感じだと
[sourceSets.main]<com.android.build.gradle.internal.api.DefaultAndroidSourceSet_Decorated@46e5590e dynamicObjectHelper=org.gradle.api.internal.AsmBackedClassGenerator$MixInExtensibleDynamicObject@f1d5566 mapping=org.gradle.api.internal.ConventionAwareHelper@4ed1a34a manifestSet=false aidlDirectoriesSet=false resourcesSet=false compileConfigurationNameSet=false assetsDirectoriesSet=false renderscriptDirectoriesSet=false resSet=false jniSet=false resourcesDirectoriesSet=false manifestFileSet=false allSourceSet=false nameSet=false aidlSet=false javaDirectoriesSet=false allJavaSet=false packageConfigurationNameSet=false javaSet=false jniDirectoriesSet=false resDirectoriesSet=false assetsSet=false renderscriptSet=false displayNameSet=false name=main javaSource=main Java source allJavaSource=main Java source javaResources=main Java resources manifest=AndroidManifest.xml assets=[assets] res=[res] aidl=[src] renderscript=[src] jni=[src/main/jni] displayName=main allSource=main source>
なので下記みたいに直接っこめばいい?と感じてしまいますが下記な感じエラーになります
main.jni=['CCC']
Cannot set the value of read-only property 'jni' on source set main.
DSL定義のこの位置(インスタンス)変更扱いと認識されたようです。
実際NodeBuilderでclassをembbedしているだけですので
更に下の階層(メンバ変数が存在するか)をdumpしていきます
println "[sourceSets.main.jni]${main.jni.dump()}"
すると
[sourceSets.main.jni]<com.android.build.gradle.internal.api.DefaultAndroidSourceDirectorySet@2ad1e832 name=main jni fileResolver=org.gradle.api.internal.file.BaseDirFileResolver@5826d8e6 source=[jni]>
ココを見ると、sourceでも可能に見えます
main.jni.source=['BBB'] println "[sourceSets.main.jni]${main.jni.dump()}"
[sourceSets.main.jni]<com.android.build.gradle.internal.api.DefaultAndroidSourceDirectorySet@2ad1e832 name=main jni fileResolver=org.gradle.api.internal.file.BaseDirFileResolver@5826d8e6 source=[BBB]>
と書き換わりはするようです
勿論公式通りに
sourceSets.main. jni.srcDirs = ['AAA'] println "[sourceSets.main.jni]${main.jni.dump()}"
と書いても
[sourceSets.main.jni]<com.android.build.gradle.internal.api.DefaultAndroidSourceDirectorySet@2ad1e832 name=main jni fileResolver=org.gradle.api.internal.file.BaseDirFileResolver@5826d8e6 source=[AAA]>
で指定でも問題無いようです
- 変数チェック代入/チェック時にエラーがわかりにくい、
- [--debug]とかつけるの面倒!
- gradleタスクがエラーはちょっとな〜
という人は
groovyはjava(をscript言語のように扱える言語)なので
try{ sourceSets.main. jni.srcDirs = ['AAA'] }catch(e){println e.dump()}
な書き方はできますが、ココは気分の問題かな−
☆)あとエミュレータで試す人は
Android Studioでlibs/*/*.soファイルがうまく取り込まれなくていろいろ調べて、gradle.buildも修正してみたのにダメ。URL
2013-05-25 22:13:50 via web
armのバイナリしか用意してないのに、x86なエミュレータで動かそうとしてたせいでした。
2013-05-25 22:14:31 via web
祝 ffmpeg build通過。--cpu=cortex-a8を明示的に渡すのね。
nanoでndk開発するならAndroid Studio連携いらないなと達している
要は爆速エミュレータだとNDKは上手く動かないと・・。
こういうのは実機でしか試したこと無いのですごく貴重な情報かも。。。
Android StudioにC++ Plugin入れてNDK開発が色々捗る
Android Studioクンさんhello-jniさんをimportしただけじゃ起動できないじゃないですか やだー
2013-05-27 18:08:56 via web
おっ…いけたくさい
2013-05-27 18:19:43 via web
ndk-build cleanしてから再度ndk-buildするだけかいな
2013-05-27 18:32:49 via web
@epy0n0fftask1個作って defaultTasks ndkclean とかしておいたほうがいいかもしれませんね(汗
2013-05-27 19:24:26 via YoruFukurou to @epy0n0ff
@kimukou2628 そうですねー(´ノω`) 低スペックじゃない限り入れた方がよさそうです
2013-05-27 20:13:53 via web to @kimukou2628
自分がよくやってる事)
- eclipseプロジェクトでの設定の共通化
自分とかだとantで署名までしていて
- local.propertiesに同じ情報書いてる
sdk.dir=/Users/XXXXX/android-sdk-macosx key.store=yutori.keystore key.alias=yutori_history key.alias.password=yutori_world key.store.password=yutori_black_world release.app.name=yutori_history release.app.version=v01g
-
- => gradle.properties 作るより apply from:config.gradle で読み込ませたほうが良くない?
で試してみたらたしかに動いた。。。
- android_yuotri/config.gradle
def prop1 = new Properties() //[NOTE]マルチプロジェクト構成(AS形式で)ルート直下なので今回はこちら prop1.load(new FileInputStream( new File(settigDir,'local.properties') )) //[NOTE]eclipse-export形式だとこちらでないと怒られるかも。。。 //prop1.load(new FileInputStream( new File(projectDir,'local.properties') )) def config = new ConfigSlurper().parse(prop1) println config.dump() //println config.key."store.password" JAVA_OPTS=-Dgroovy.source.encoding=UTF-8 -Dfile.encoding=UTF-8 //☆これは固定値 ANDROID_HOME=config.sdk.dir key_store=config.key.store key_alias=config.key.alias key_alias_password=config.key."alias.password" key_store_password=config.key."store.password"
- android_yuotri/build.gradle 修正
apply from:"config.gradle"
- android_yuotri/yutori_hisotry/build.gradle 修正
android { //〜中略〜 signingConfigs { //[TODO] debugに関しては特に定義しなければ上記の状況で自動的に勝手に動くらしい //debug{ // 〜略〜 //} myConfig { //storeFile file(key_store) //AS等のIDEから動かすとカレントが変に動くことがあるので親指定がベター storeFile file(new File(projectDir,key_store)) //[NOTE]マルチプロジェクト構成(AS形式で)ルート直下ならこちらでもOK //storeFile file(new File(settingsDir,key_store)) keyAlias key_alias keyPassword key_alias_password storePassword key_store_password } } buildTypes { release { signingConfig signingConfigs.myConfig } } }
使える変数名 | 使える構成 | 位置 |
---|---|---|
settingsDir | マルチプロジェクト構成(AS形式)のメインプロジェクト側 | 実行ディレクトリ直下 |
projectDir | シングルプロジェクト構成(eclipse形式) | 実行しているbuild.gradleの位置 |
あと、以前サポートされていた build.propertiesが自動では読込まなくなったので
皆さん苦労しているみたい
はてなブログに投稿しましたAndroid StudioでGoogle Play sevicesを含んだgradleベースの新規プロジェクトを作る方法 - sos の 作業メモURL
http://twitter.com/kimukou2628/status/337857816469577728:twitter:detail:right
http://twitter.com/kimukou2628/status/337858185899700224:twitter:detail:right
@kimukou2628 ありゃ そうなんですか。ありがとうございます > build.properties
こういう話がリアルになってくると
上記のように手動でpropertiesファイルを読み込むか
環境変数設定、引数設定頼みになってしまうかも。。
- 実行時に -P オプション(-PXXXX=1234 みたいな感じ)
- ${user.home}/.gradle/gradle.properties
- 環境変数 GRADLE_ENV
で設定な感じ?
追記)
Gradle+Android StudioでAndroidAnnotations使えるかどうか試行錯誤してんだけどどうしてもうまくいかない
URL わからん
なのも見てるけど
な対応のtaskを自分で追加しないと駄目なのは厳しいのではないかな・・・
gradleだとgant(AntBuilder)を暗黙的変数 ant として参照できるからまあ移植は簡単なんだけどね−
まだ動くかどうか検証中なので、出来たら詳細状況追記します
task apt { ant.mkdir(dir:'bin') ant.mkdir(dir:'gen') //apt 実行バージョン ant.exec(outputproperty:"cmdOutA", errorproperty: "cmdErrA", resultproperty:"cmdExitA", failonerror: "true", dir:".", executable: "apt") { arg(value:"-AJsonPullParserClassPostfix=Gererated") arg(value:"-AJsonPullParserDebug=true") arg(line:"-cp factory/jsonpullparser-apt-1.5.1.jar") arg(line:"-factory net.vvakame.util.jsonpullparser.factory.JsonAnnotationProcessor") arg(line:"-d bin") arg(line:"-s gen") new File("src/com/twitpic/bean").eachFileMatch(~".*.java"){ arg(value:it.absolutePath) println it.absolutePath } } println "<${ant.project.properties.cmdExitA}>=${ant.project.properties.cmdOutA}" /* //java 1.6バージョン(動かない) //see http://svn.codehaus.org/groovy/tags/GROOVY_1_7_6/src/test/groovy/util/AntTest.groovy // https://gist.github.com/4428306 def cls_lib = ant.path { fileset(dir: "${config.sdk.dir}/tools/lib") { include(name: "*.jar") } fileset(dir: 'libs') { include(name: "*.jar") } } ant.javac( includeAntRuntime: false, classpath: cls_lib, srcdir: "src/com/twitpic/bean", encoding: "UTF-8" ) { //compilerarg(line:"-AJsonPullParserClassPostfix=Gererated") //認識されない警告が出る //compilerarg(line:"-AJsonPullParserDebug=true") //認識されない警告が出る //compilerarg(line:"-factory net.vvakame.util.jsonpullparser.factory.JsonAnnotationProcessor") compilerarg(line:"-processorpath factory/jsonpullparser-apt-1.5.1.jar") //compilerarg(line:"-d bin") compilerarg(line:"-s gen") } */ }
かっこいい書き方をググると
あたりも出てくるけど、こっちは動かなかったorz *3
追記)
IDEA(AS)依存にはなるけど
なtaskは書けるとのこと
でもまあ
なにかこわいメンションが飛んできていたようだ。
2013-05-18 23:55:13 via web
@kimukou2628 楽勝だなんてとんでもない ^^; ありがとうございます。
2013-05-19 01:44:30 via web to @kimukou2628
@kimukou2628 パッと見なんですが、それにしては海外勢が静かすぎるような気もしています。実際自分はまだ触れていないのでなんとも言えませんが…
2013-05-19 02:05:40 via web to @kimukou2628
http://twitter.com/kimukou2628/status/335805715614662657:twitter:detail:right
@kimukou2628 なるほど… 情報ありがとうございます。しかしまだ少ないにしても皆無というのはなにか引っかかるんですよね ;-)
2013-05-19 02:17:16 via web to @kimukou2628
@kimukou2628 (というより、多分自分の調べ方がまずいんじゃないかという懸念はもちろんありますけど。)
2013-05-19 02:18:04 via web to @kimukou2628
@kimukou2628 ^^;;;
2013-05-19 02:56:56 via web to @kimukou2628
って会話してたぐらいだから
- APT使う
- LibraryProject使う
って辺りでandroid中級者以上なのかもね
分割先)
http://twitter.com/kimukou2628/status/343204075246063616:twitter:detail:right
@kimukou2628 URL のようにconfigurationsに指定すると独自の設定を定義できるようになります。
@kimukou2628 configurations.aptで dependencies { apt 'hoge' } 指定したjarだけを取得出来ます。ただし、 'hoge'が他に依存している場合それを持ってきますので、必要ないものだけexcludeするのがいいと思います。
@kimukou2628 あとは URL の Examplesの2番目が応用出来るのではないかと。
http://twitter.com/kimukou2628/status/343213326257491970:twitter:detail:right
@kimukou2628 URL にexcludeの例があるのでそちらのほうがいいですね。transitive = falseだと、依存を見ないようになるので単体で取得出来ます。
で色々と教えて頂きました。
でも考えてみたら、できると見本でみてるbuild.gradle(u1さんのSlim3の奴とか)
javacでaptコンパイルの奴って、環境により動かせたり動かせなかったりした記憶があって
aptコマンド直に使ってた経緯を思い出したので、カスタムタスクで再チャレンジしてみるのがいいのかも・・
(これ残件課題