読者です 読者をやめる 読者になる 読者になる

gradle模範解答メモ

gradle IDEA android AS

エントリ分割)
元 -http://d.hatena.ne.jp/kimukou_26/20130522/p1

android gradle plugin に関する翻訳Doc

あんまり更新がかかってないけど、こちらに関しては挙動安定してるんだよなー
(たまに
UTF8で動かしてない=>ASやコンソールでエラーでハマってる
人を見たことあるけど‥‥‥‥)

でもandroid gradle pluginのテストコード見てると

buildscript {
    repositories {
        maven { url '../../../../out/host/gradle/repo' }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.5.0-SNAPSHOT'
    }
}

な記述があるようなので、今後どうなんだろう?(gradle java pluginベースで書換えるかも?な話もあるようですし)



模範解答を書いてくださってる他方々がいるので考察してみる

1)

で「jenkinsで名前が変えられる」という言及があるけど
jenkins Jobで

  • デフォルトの作業ディレクトリってworkspaceだから
  • workspace-release.apk ってなってるのは気のせいかなー

workspace/yutoru_history って構成でDLしてコンパイルしてれば


yutoru_history-debug-unaligned.apk
とか出来そうな気がする‥‥‥*1
それでも出来てない場合は、作業フォルダの指定とかなんだろうな。。。

あと この gradle.properties って
$HOME/.gradle/gradle.properties
に置くってイメージだろうか??

カレントがworkspaceフォルダとして見れていれば、同じ位置であれば問題ないと思うけど

  • 上記の想定だと下記?
    • workspace/gradle.properties

でもこれだとレポに設定置くことになるので、書いてる記述とはちと違うかなー*2

あと defaultConfig等の記述は

  • AndroidManifest.xml
  • local.properties
  • project.properties

等の記述をチェック => エラーにしてる
って感じなので、かえって書くと可搬性が悪いかもとは思った(ただこれは個人的感想)

    defaultConfig {
        minSdkVersion 8
        targetSdkVersion 16
        versionCode <ここにVersionCode>
        versionName "<ここにVersionName>"
    }

あとfkmさんのproguard設定のままだと
proguard-project.txtの参照設定が出来ないので

の末尾に検証状況を追記した

追記)
後日にproguard対応版の話有


2)

上記の言及したbuild.gradleのバージョンアップ情報

 if (project.hasProperty('storeFile')) {
    android.signingConfigs. myConfig.storeFile = file(storeFile)
}

な書き方は秀逸だと思った。たしかにこう書けますね


3)


githubのコードを見ると

  • res/string.xml
  • packageName

を上書きという流れのよう

gradlew build

ls ./GradleAndroidFlavorExample/build/apk
出力結果>
GradleAndroidFlavorExample-cuttlefish-debug-unaligned.apk
GradleAndroidFlavorExample-cuttlefish-release-unsigned.apk
GradleAndroidFlavorExample-squid-debug-unaligned.apk
GradleAndroidFlavorExample-squid-release-unsigned.apk

productFlavors 宣言をした時点で普通のノーマルのやつに上書きしない という構成は厳しそう

ls ./GradleAndroidFlavorExample/src

main
cuttlefish	
  -res/string.xml
squid
  -res/string.xml

なのも関係あるのかしら。。。?

./GradleAndroidFlavorExample/build.gradle

println "[productFlavors]${productFlavors.dump()}"

に上記追加してDSLをdumpしてみると

store=[
GroupableProductFlavorDsl_Decorated{name=cuttlefish,
minSdkVersion=-1,
targetSdkVersion=-1,
renderscriptTargetApi=-1,
versionCode=-1,
versionName=null,
packageName=com.nowsprinting.gradleandroidflavorexample.cuttlefish,
testPackageName=null,
testInstrumentationRunner=null,
signingConfig=null},

GroupableProductFlavorDsl_Decorated{name=squid,
minSdkVersion=-1,
targetSdkVersion=-1,
renderscriptTargetApi=-1,
versionCode=-1,
versionName=null,
packageName=com.nowsprinting.gradleandroidflavorexample.squid,
testPackageName=null,
testInstrumentationRunner=null,
signingConfig=null}
]

な感じ


4)

このエラーって致命的なエラーが出た時によく出るんだけど
ASレベルじゃ分かんないですよね。。

今回はAndroid系のライブラリの依存関係がぶつかるって記載だったけど

  • gradle自体も沢山ライブラリ使ってる

=>

  • gradle自体の依存jarとぶつかる

って話はあるのでexclude記述は覚えておいたほうがいいかも。

 ただこれGUI素人レベルの人に説明するの無理やろ−
絶対。。。(苦笑


5)@さんの記事

eclipseタスクのDSLをちゃんと書くべき って記載例が載ってた。。。(サボってましたごめんなさい><)
IDEA版もちゃんと書けばimport後の負担減ると思う(汗
でもこれ書かせる前提だとますます嫌がられそう。。。

でもここのbuild.gradleをコピペしてみてもなんか予想通り動かない
.classpath

<classpath>
	<classpathentry kind="output" path="bin"/>
	<classpathentry kind="src" path="src"/>
	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK" exported="true"/>
	<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES" exported="true"/>
</classpath>

と生成されてしまいます*3

androidLibs ってなんぞ?と言われる。

  • [、] => [,]に置き換える必要があります*4

ここも記事読んで試しただだけの人は嵌りそうだよなー

本当にリアルにするなら

ぐらいの記述は必要なんでしょうし‥‥‥

IDEAのせってゴリゴリな話は

に一応あります


勿論ASベースだとますます動かせませんので実際にリアルに近い形で弄ってみましょう

  • build.gradle
repositories {
   mavenCentral()
}

apply plugin: "java"
apply plugin: 'eclipse'

//[NOTE]sourceSetsの指定のためのjava pluginが必要
sourceSets {
	//eclipse export構成ならこれでもOK
/*	
	main {
		java.srcDirs "src","gen" 
		output.classesDir = "bin/classes"
	}
*/	
	main {
		//projectDir = rootProject.name
		println "projectDir=$projectDir"
		java.srcDirs = [
			"$projectDir/src",
			"$buildDir/source/r/debug" ,
			"$buildDir/source/rs/debug", 
			"$buildDir/source/buildConfig/debug", 
			"$buildDir/source/aidl/debug" 
		]
		//output.classesDir = "$buildDir/classes" //☆
	}
}

eclipse {
	projectNames= rootProject.name
	println "projectNames=$projectNames"
	project {
		//name = 'AndroidProject'
		name = projectNames  //☆こっちのほうがベターだと思う(Settings内で定義されてるプロジェクト名)
		natures 'com.android.ide.eclipse.adt.AndroidNature'
		buildCommand 'com.android.ide.eclipse.adt.ResourceManagerBuilder'
		buildCommand 'com.android.ide.eclipse.adt.PreCompilerBuilder'
		buildCommand 'com.android.ide.eclipse.adt.ApkBuilder'
	}
	classpath {
		defaultOutputDir=file("$buildDir/classes") //☆☆
		containers.clear();
		containers = [
			"com.android.ide.eclipse.adt.ANDROID_FRAMEWORK",
			"com.android.ide.eclipse.adt.LIBRARIES"
		]
		downloadSources = true
		downloadJavadoc = true
	}
}

.project に関しては問題ないようなのですが
.classpath はうまく生成されません

sourceSetsのところがうまく動いていないようなので
試しに
☆の箇所とは別に
☆☆を追加してみます


  • タスク実行時に生成されるプロジェクト設定ファイル

.project (vvakameさんができると提示した未来予想図とほぼ同じ)

<projectDescription>
	<name>AndroidProject</name>
	<comment></comment>
	<projects>
	</projects>
	<buildSpec>
		<buildCommand>
			<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
			<arguments>
			</arguments>
		</buildCommand>
		<buildCommand>
			<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
			<arguments>
			</arguments>
		</buildCommand>
		<buildCommand>
			<name>org.eclipse.jdt.core.javabuilder</name>
			<arguments>
			</arguments>
		</buildCommand>
		<buildCommand>
			<name>com.android.ide.eclipse.adt.ApkBuilder</name>
			<arguments>
			</arguments>
		</buildCommand>
	</buildSpec>
	<natures>
		<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
		<nature>org.eclipse.jdt.core.javanature</nature>
	</natures>
</projectDescription>

.classpath (実際出来たもの)

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
	<classpathentry kind="output" path="build/classes"/>
	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK" exported="true"/>
	<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES" exported="true"/>
</classpath>

.classpath (vvakameさんができると提示した未来予想図)

<?xml version="1.0" encoding="UTF-8"?>
<classpath>
	<classpathentry kind="src" path="src"/>
	<classpathentry kind="src" path="gen"/>
	<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
	<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
	<classpathentry kind="output" path="bin/classes"/>
</classpath>

なんだろうな。。(汗

eclipse {
    pathVariables 'GRADLE_USER_HOME': gradle.gradleUserHomeDir
}

とか出来るのは知ってるんですけどね・・・・



6)

ちょっと書き方は雑*5かなとおもったけど・・。

自分的感想としては
@さんや @ のほうが書き方精錬されてるかも。
まああえて言及されているってことは
かなりAndroid系でかなり有名な開発者の方がサンプル出してくれたんだろうしな。。。
それはそれでありがたいのかも‥‥‥

1個だけ build.gradle等読んでて 確かに納得したのは
一番最上位にのところだけに
build.gradle

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:0.4'
    }
}

な記載に留めてる処。確かに無駄なNWアクセスだよね(一度読みこめばずっとclasspath内には存在するので)



7)

aptタスクの書き方がわからなかったのですごく勉強になった

  • MyTemplate/build.gradle
configurations {
    apt
}

dependencies {
  // http://stackoverflow.com/questions/16683944/androidannotations-nothing-generated-empty-activity/16802216#16802216
    apt "com.googlecode.androidannotations:androidannotations:${androidAnnotationsVersion}"
    compile "com.googlecode.androidannotations:androidannotations-api:${androidAnnotationsVersion}"
}

と書けば認識すると。ココらへん公式サイトに書いてなかった気もするんだよな‥‥(汗。
困ったときのstackoverflow頼み。

aptOutput = file("${project.buildDir}/source/apt_generated/${variant.dirName}")
    println "****************************"
    println "variant: ${variant.name}"
    println "manifest:  ${variant.processResources.manifestFile}"
    println "aptOutput:  ${aptOutput}"
    println "****************************"

    variant.javaCompile.doFirst {
        println "*** compile doFirst ${variant.name}"
        aptOutput.mkdirs()
        variant.javaCompile.options.compilerArgs += [
                '-processorpath', configurations.apt.getAsPath(),
                '-AandroidManifestFile=' + variant.processResources.manifestFile,
                '-s', aptOutput
        ]
    }

のところはaptOutputのところをgenに出力してたんだけど、
android maven projectだとそれ何処い当たるのかいまいちわからんな。。。(汗

  1. MyTemplate プロジェクトを選択し、 File > Project Structure を開く
  2. Modules >MyTemplate を選択し
  3. Sources タブを選んで build/source/apt_generated/debug を選択し
  4. 上にある Sourcesボタン を押して Sourceフォルダとする。

と記載して頂いてるけど。。。

のほう読みなおしたほうがベストかも。。。



8)

上記のaptのをJPPでやったお話らしい

  • variant.javaCompile
  • android.applicationVariants.each
  • android.libraryVariants.each

等の記載がないと駄目って
書いてるんだけど、普通にコンパイルしてAPKで来てるんだよな‥‥‥
apt_generated とかの設定ってあくまでGUIの設定だと思ってるんだけど
違うんだろうか??

これ勘違い><。でもなんでapkできるんだろう?
逆に有効にするとエラーになるので改めて追わないと・・・(汗

一応 zakiさんプロジェクト微改版 は動いてるので
何か設定足りないのかも。pluginのソース読み込まないと駄目かな。。。

追記)

一応これに関しては

で解決。@ さんの環境 https://github.com/zaki50/android_gradle_template/blob/master/MyTemplate/src/main/AndroidManifest.xml
の環境で[_]が付いてるの見落としてただけだった。
androidannotationsの引数オプションは調べたほうがいいかも(汗

でも自分の環境だと再度試しても
ASから実行時に「そんなActivityはありません」とエラーになるんだけどな‥‥。環境依存?

な話もあるようなので環境依存はあるっぽいかも。。。
<変にgradleやIDEAのローカルのファイルが残っちゃってるとか?

後者の話は、自分も再現できなかった・・・うーん。



9)

この構成はちょっと調べてみたいかな。
setRootが相対パス指定出来れば多分eclipseの構成のまま
gradleで使えるかもな夢が広がるかも((ただしASとしてはダメな可能性は高いけど。。。))



10)

アプリを起動する あたりの話は 後で検証してみたいかも<実際はUSBにつながってる全端末に送れないと微妙な気がしますよね。。
(installDebug等は単一モードしか対応してないし

gradle pluginを作るとしたら、マルチOSはサポートしないと厳しいんだろうなとは思いつつ

あたりを読み返そうと思ってる



11)

*1:apk名は 現状フォルダ名依存っぽい

*2:それとも作業ワークスペースをローカルの指定フォルダ固定してるのだろうか??

*3:想定構成に近い ABSのプロジェクトで試しました

*4:記事記載時に文字変換されたよう

*5:eclipse projectっぽくないのも。あえてそういう描き方してるのかもしれないけど。v4のライブラリ参照あたり