Android Studio を build.gradle に task追加の方向性で弄ってみる

情報整理エントリ
一応メモ途中)



というお話があったので弄ってみると。

 こういう構成で自分が馴染みがあるのは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()}

な書き方はできますが、ココは気分の問題かな−

☆)あとエミュレータで試す人は

要は爆速エミュレータだとNDKは上手く動かないと・・。
こういうのは実機でしか試したこと無いのですごく貴重な情報かも。。。



自分がよくやってる事)

  • 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 で読み込ませたほうが良くない?

で試してみたらたしかに動いた。。。

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が自動では読込まなくなったので
皆さん苦労しているみたい

http://twitter.com/kimukou2628/status/337857211265064960:twitter:detail:right
http://twitter.com/kimukou2628/status/337857816469577728:twitter:detail:right
http://twitter.com/kimukou2628/status/337858185899700224:twitter:detail:right

こういう話がリアルになってくると
上記のように手動でpropertiesファイルを読み込むか
環境変数設定、引数設定頼みになってしまうかも。。

  1. 実行時に -P オプション(-PXXXX=1234 みたいな感じ)
  2. ${user.home}/.gradle/gradle.properties
  3. 環境変数 GRADLE_ENV

で設定な感じ?



追記)

なのも見てるけど

な対応の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は書けるとのこと


でもまあ

http://twitter.com/kimukou2628/status/335796688281280512:twitter:detail:right
http://twitter.com/kimukou2628/status/335799800748457985:twitter:detail:right
http://twitter.com/kimukou2628/status/335804457721929729:twitter:detail:right
http://twitter.com/kimukou2628/status/335805715614662657:twitter:detail:right

って会話してたぐらいだから

  • APT使う
  • LibraryProject使う

って辺りでandroid中級者以上なのかもね

分割先)


http://twitter.com/kimukou2628/status/343204075246063616:twitter:detail:right

http://twitter.com/kimukou2628/status/343209781974155264:twitter:detail:right
http://twitter.com/kimukou2628/status/343212802116304897:twitter:detail:right
http://twitter.com/kimukou2628/status/343213326257491970:twitter:detail:right

で色々と教えて頂きました。
でも考えてみたら、できると見本でみてるbuild.gradle(u1さんのSlim3の奴とか)
javacでaptコンパイルの奴って、環境により動かせたり動かせなかったりした記憶があって
aptコマンド直に使ってた経緯を思い出したので、カスタムタスクで再チャレンジしてみるのがいいのかも・・
(これ残件課題

*1:VideoAd配信用にsoも追加されてるという話。実際に配信されてるのかな?

*2:普通はCompileタスクいじれないよ〜と怒られるので

*3:自分は動くの第一だと思うけど、TDDクラスタの方やbuild職人やgroovyクラスタの方々はコードの美しさを追求するからな。。。悪くはないんだけどね。。。<汗