Androidプロジェクトでは、どうやって神器Graadleを構築しますか?


原文の住所:http://www.csdn.net/article/2015-08-10/2825420/2
Android Gradleの実戦
次はAndroid Gradeの実戦で遭遇した問題と経験について説明します.
productFlaavors
このものは基本的にはもう腐っています.gradleのプロジェクトは普通Product Flavorを使います.完璧な団の文章を見れば、分かります.
米グループAndroid自動化の旅—適配ルートパッケージ
buildTypes
多くのアプリには内測版と正式版がありますが、どうやって彼らが同時に携帯にインストールされますか?同時に一つの携帯電話にインストールして、package Nameが違っています.productFlaavorsで解決できますが、優雅さが足りないかもしれません.alphaバージョンはdebugとreleaseバージョンが必要です.卵痛ではないですか?buildTypesで解決できます.古いストラテジストの朱鴻さんの文章を洗って、詳しい説明がありますが、内容によってはちょっと古いかもしれません.脚本を変えなければなりません.
依存更新
プロジェクト依存のリモートパッケージは更新されたら、リマインダや自動更新がありますか?いいえ、手動でchangeを設定してtrueと表記する必要があります.このようにgradleは24時間ごとに更新を確認します.
configurations.all {
    // check for updates every build
    resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
}
dependencies {
    compile group: "group", name: "projectA", version: "1.1-SNAPSHOT", changing: true
}
以前はaarの同じバージョンをmaven倉庫にアップロードしましたが、依存は更新されていません.どうすればいいですか?ローカルキャッシュを直接削除することができます.キャッシュは~/.gradle/cachesディレクトリの下にあります.キャッシュを削除すると、今度の運転は自動的にリモート依存をダウンロードし直します.
aarをMaven倉庫にアップロードします.
プロジェクトのbuild.gradleに次のスクリプトを追加します.
apply plugin: 'maven'
uploadArchives {
    repositories {
        mavenDeployer {
            pom.groupId = GROUP_ID
            pom.artifactId = ARTIFACT_ID
            pom.version = VERSION
            repository(url: RELEASE_REPOSITORY_URL) {
                authentication(userName: USERNAME, password: PASSWORD)
            }
        }
    }
}
build.gradleとディレクトリの下にgradle.propertiesファイルを追加して、構成は以下の通りです.
GROUP_ID=dianping.android.nova.thirdparty
ARTIFACT_ID=zxing
VERSION=1.0
RELEASE_REPOSITORY_URL=http://mvn.dp.com/nova
USERNAME=hello
PASSWORD=hello
gradle.propertiesの属性は、build.gradleによって読み取られてaarをアップロードするために使用され、最後に./gradlew :Zxing:uploadArchivesを実行すればいいです.
より多くの配置は、企業内のMavenサーバーを構築し、Android Studioを使って公共プロジェクトを発表することを参考にすることができます.
ジョブをキャンセル
プロジェクト構築中には多くのタスクがありますが、test関連のタスクは全く必要ないかもしれません.直接オフできます.build.gradleには次のシナリオを入れます.
tasks.whenTaskAdded { task ->
    if (task.name.contains('AndroidTest')) {
        task.enabled = false
    }
}
taskysは現在のプロジェクト中のすべてのtaskを取得して、enabled属性制御タスクスイッチ、whenTask Addedの後のクローズドはgradle配置段階で完成します.
任務に加わる
ミッションはキャンセルできますが、まだ楽しくありません.ミッションに参加したいですが、どうすればいいですか?前にdepends Onの方法を説明しましたが、それを持ってきて使ってもいいです.元のミッションの依存関係はよく分かりません.ミッション名も分かりません.どうすればいいですか?
例えば、dexパッケージを実行する前にハロージョブを追加したいです.このように書いてもいいです.
afterEvaluate {
    android.applicationVariants.each { variant ->
        def dx = tasks.findByName("dex${variant.name.capitalize()}")
        def hello = "hello${variant.name.capitalize()}"
        task(hello) << {
            println "hello"
        }
        tasks.findByName(hello).dependsOn dx.taskDependencies.getDependencies(dx)
        dx.dependsOn tasks.findByName(hello)
    }
}
afterEvaalateは何の鳥ですか?配置段階で終わります.プロジェクトの評価が終わると、このステップに進みます.
variantは?variant=productFlaavors+buildTypesなので、dexパッケージのタスクはdexCommon Debugかもしれません.
dexタスクの具体的な名前はどう分かりますか?Android StudioのGradle Cosoneはgradleタスクを実行する時に出力があります.よく観察してください.
ハロータスクの定義の複雑さは何ですか?直接ハローと呼んでもいいですか?いいえ、eachはvariantsを遍歴しています.もしすべてhelloと呼ばれたら、複数のvariantは同じです.バカではないですか?分かりません.それに、variantのnameは後継ぎをして、ミッションの区別があります.
キーは、dx.task Dependencies.get Dependencies(dx)はdxタスクのすべての依存を取得し、ハロータスクをdxタスクのすべての依存に依存させ、dxタスクをハロータスクに依存させます.
私はふと思いました.doFirstでactionをdxタスクに加えると、上の効果があるはずです.
加速する
gradleは加速してこの友達の書いた加速Android Studio/Graadleの構築を見てもいいです.パラレルコンパイル、常駐メモリ、オフラインモードといった考え方がgradleに対して加速感が少ないです.
もっと速くしたいです.フェイスブックのBuckを試してみてもいいです.VineチームがBuckに似合う技術記事を見てもいいです.私たちの構築者もBuckに適応しています.加速効果は10倍ぐらいですが、Windowsシステムをサポートしないという二つの欠点があります.遠隔依存をサポートしていません.
任務監督
各タスクの実行時間を知りたいですか?各執行任務は何ですか?次のこのスクリプトをbuild.gradleに入ればいいです.
class TimingsListener implements TaskExecutionListener, BuildListener {
    private Clock clock
    private timings = []

    @Override
    void beforeExecute(Task task) {
        clock = new org.gradle.util.Clock()
    }

    @Override
    void afterExecute(Task task, TaskState taskState) {
        def ms = clock.timeInMs
        timings.add([ms, task.path])
        task.project.logger.warn "${task.path} took ${ms}ms"
    }

    @Override
    void buildFinished(BuildResult result) {
        println "Task timings:"
        for (timing in timings) {
            if (timing[0] >= 50) {
                printf "%7sms  %s
", timing } } } @Override void buildStarted(Gradle gradle) {} @Override void projectsEvaluated(Gradle gradle) {} @Override void projectsLoaded(Gradle gradle) {} @Override void settingsEvaluated(Settings settings) {} } gradle.addListener new TimingsListener()
上記はタスク毎のタイミングの一例です.各タスクの役割を理解したいです.上記のスクリプトを修正して、各タスクのinputとouts putを印刷してください.たとえば、asemble Debugのように多くのタスクに依存していますが、それぞれは何をしていますか?各taskの入出力を見ると、その役割が大体分かります.assiembleの各タスクを監聴すれば、コードを変更するbuildの時間は主にdexにかかります.buck牛が迫るところはこの場所を最適化して、増分的にコンパイルして運行する時間を大幅に減らしました.
buildscript方法
Androidプロジェクトでは、ルートプロジェクトのデフォルトのbuild.gradleはこうなるべきです.
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.2.3'
    }
}

allprojects {
    repositories {
        jcenter()
    }
}
これは何をしていますか?buildscriptメソッドの役割は設定スクリプトの依存であり、私たちが普段使っているcompleは配置projectの依存である.repositoriesというのはカバンが必要な時にお兄さんのところに来て探してください.そしてcom.android.tools.build:gradle:1.2.3はjcenterからダウンロードすると思いますよね.図面が壊れています.信じないで次のシナリオを入れて出力を見てみます.
buildscript {
    repositories {
        jcenter()
    }
    repositories.each {
        println it.getUrl()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.2.3'
    }
}
結果はこうです.
file:/Application/Android%20 Studio.ap/Contents/gradle/m 2 repository/https://jcenter.bintray.com/
私は、倉庫がAndroid Studioアプリケーションの内部に直接にあるので、buildscriptのjcenterを外しても大丈夫です.下にはもっと快適なものがあります.上のclassityのgradlegradle-coreに依存しています.gradle-corelintに依存しています.lintに依存しています.このルートディレクトリの依存配置はすべてのプロジェクトの配置ファイルに届きますので、asm関連のクラスを参照するなら、クラスパスパスをセットせずに直接importで大丈夫です.前の依存関係はどうやって分かりますか?上のm 2 repositoryディレクトリに対応するpomファイルを見ればいいです.
なぜASMについて話しますか?ASMはまた意地悪なものです.Javaバイトコードを直接操作して、classファイルを動的に変更する効果があります.ASMを用いて面に向かってプログラムでき,デカップリング効果を達成した.Android DEXは自動的にカバンを外して、動的なローディングプロファイルに記載されているclass依存分析とR定数が入れ替わるスクリプトはASMでやってもいいです.
スクリプトをインポート
脚本を書きすぎて、全部一つのbuild.gradleの中に押し込むのもよくないです.人が大きくなったらいつも自分で外に出て住もうとしますが、脚本の部分を引き出してもいいですか?もちろんいいです.新しいother.gradleでスクリプトを引き出して、build.gradleにlint-checksを追加すればいいです.引き出した後、本来はimportのasmカバンが見つからないことが分かります.どういうことですか?本プロジェクトに配置されたブリジットはすべてのプロジェクトに伝達されますが、ブリーフィングスクリプトにしか伝達されません.他のスクリプトは構いません.だから、あなたがother.gradleにbuildscriptを再配置する必要があります.そして、other.gradleの中のrepositoriesはm 2 repositoryディレクトリを含まないので、自分でjcenterを配置します.追加でダウンロードしたくないなら、other.gradleでやってもいいです.
buildscript {
    repositories {
        maven {
            url rootProject.buildscript.repositories[0].getUrl()
        }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.2.3'
    }
}
Android Manifestファイルを取得します.
Application Id versus Package Nameによると、gradleの中のaplicationidはアプリケーションを区別するために使用され、manifestの中のpackage NameはRファイルのパッケージ名を指定するために使用され、各productFlavorのmanifestの中のpackage Nameは一致するはずである.appication idはgradleシナリオの定義にすぎませんが、最後に作成されたappleファイルのpackage Nameはやはりappicationidに置き換えられます.
Rファイルのパッケージ名を取得するにはどうすればいいですか?Android Manifestのpackage属性を取得するには、このmaifetが開始されたファイルは、最終ファイルのpackage属性がaplication idによって削除されますので、各maifetのpackage属性が同じで、非マスターmaifetはpackage属性がなくてもいいです.
def manifestFile = android.sourceSets.main.manifest.srcFile
def packageName = new XmlParser().parse(manifestFile).attribute('package')
リソース
不要な資源はAPKに包装しないでください.
Resource Shrine king
一つのBug
前は創業会社で Travisは継続して継承しています.悩みの問題があります.Travis上で構築スクリプトを実行すると以下のようになります.
./gradlew clean
./gradlew assembleXR
最後に作成したAPKは運転中にエラーが発生し、ヒントが見つからなかった.そしてファイルを解凍して、APKの中にあるライブラリプロジェクトのsoファイルが不足していることを発見しました.しかし、現地で運行する時は問題がなく、長い間悩んでいました.Android StudioでClean Projectを実行していると、GEnerate Sourcesのタスクが実行されます.それをビルドスクリプトに入れてから包装します.最近発見されたのですが、これは元々Bugで、android gradle 1.3で修復されました.
慌ただしい間に、たくさんのことを書きました.この文章を読んで、神器を構築する魅力を感じていただきたいです.柔軟性と強さを感じてください.もちろん、Gradeを使って、より適切なものにしたいです.