ある文章はGradleの使命を認識している.

3690 ワード

Gradleは私たちの多くのAndroid開発者にとってよく知られていると言っても過言ではありません.しかし、この理由は私にこの文章を書くのに十分ではありません.それは主にこのようなためです.最近プロジェクトの開発に参加して、プロジェクトの工事のbuildを発見しました.gradleは以前に接触したものよりずっと複雑で、大部分の内容は表面の英語でもやっと理解できるが、一部の内容は人を混乱させる.特にgradleが間違っているとき、私は最初に非常に熟練したスキルを運用して、ctrl+c問題、ctrl+vからgoogleまで、それからgoogleを通じて出てきた結果を変えて、運がいいですよ.このような簡単な変更はgradleが通過して、この時喜びの前に噴き出して、口元が狂ったように上昇し始めました.しかし、実は心はとても虚しくて、あなたがどんな原理に基づいて解決したのか全然知らないからです.総じて言えば、このブログの目的は2つです.
無効なctrl+c/v時間を減らしてgradleの使命を理解し、gradle問題に遭遇してもそんなに虚しくないブログの核心内容は3つに分けられます.
GroovyとJavaGradleのライフサイクルtaskの定義GroovyとJava gradleを学ぶ過程で、gradleの摩天楼で方向を見失わないように、次の言葉を覚えたほうがいいです.
GradleスクリプトはGroovy音声に基づいているので、Groovyの構文に従う必要があります.
Groovyはスクリプト言語であり、JVM言語でもあり、最終的にはclassファイルにコンパイルしてjvm上で実行するので、Java言語の特性Groovyはサポートされており、JavaとGroovyを完全に混在させることができます.あれ、なんだこの話はコトーリンを紹介して見たことがあるみたいだね.はい、kotlinを習ったことがあると、kotlinとgroovyの多くの文法規則が同じであることがわかります.
それならGroovyの強みは何ですか?簡単に言えば、Groovyはより柔軟で簡単な文法を提供し、大量の文法糖と閉包特性はJavaと同じ機能をより少ないコードで実現することができます.例えばxmlファイルを解析するとGroovyは非常に便利で、数行のコードだけででき、Javaでは数十行のコードが必要です.
以下ではGroovyのいくつかの文法を簡単に紹介します.より多くの文法は公式ドキュメントを参照することができます.本稿の重点はここではありません.
  • 文字列テンプレートdef name="world"println"Hi${name}"
  • defキーワードは変数と関数def a=1//セミコロンdef b=「hello world」def int c=1
    def hello(msg) {  //       
         println (msg) 
         1  //        return
    }
    を宣言するGroovyではタイプが弱く、すべてのタイプがGroovyで多くのものを省略できると動的に推定できる.例えば、文後のセミコロン、戻り値の最後のrenturn、関数パラメータのタイプ
  • クローズドパッケージ(Closure)簡単な理解で、一対の{}でコードブロックをブロックし、全体のオブジェクトとして{[closureParameters->]sataments}[]の内容を処理するのは省略できるが、ないわけではない.Groovyは自動的に分析して推測し、人工的に書く煩雑な過程を省くことができる
  • くりをいくつかあげる
    { -> item++ }   //      item
    
    { it -> println it } //        it
    
    { println it }      //        it
    
    { name -> println name } //      
    
    { string x, int y ->    //      
            printIn "hey ${x} the value is $(y}"
    }  
  • 演算子Groovyの多くの演算子は、オブジェクトに対する通常の関数呼び出しとしてマッピングされます.例えば、a+bはGroovyによってa.plus(b)a-bと解釈され、Groovyによってa.minus(b)a[b]=cはGroovyによってa.putAt(b,c)と解釈される.このような特性があるからこそ、私たちによく見られるtask文がある.task helloword<{println'hello,world}Gradleのライフサイクルgradleは自動化コンパイルの使命を果たすには、3つのプロセスが必要である.つまり、そのライフサイクルは
  • です.
  • 初期化の初期化フェーズの主な役割は、処理する必要があるbuildファイルを特定することです.単一のエンジニアリングであれば、次のフェーズの入力として個別のbuildファイルが認識されます.マルチエンジニアリングであれば、複数のbuildファイルが見つかり、次の段階の入力として使用されます.この段階ではgradleファイルが解析されます.
  • は、すべてのモジュールを処理するbuildスクリプト、処理依存、属性などを構成する.Androidにとって各モジュールのbuild.gradleファイルは解析されて構成され、このときtask全体のチェーンテーブル(依存関係のあるtaskの集合のみを指し、データ構造のチェーンテーブルではない)が構築される.この段階のターゲット生成物は、実際にはtask 1つからなるDAG図(Directed Acyclic Graph)
  • である
  • 実行このフェーズはGradleの価値を真に体現するフェーズであり、前のフェーズのDAG結果に基づいて特定のtaskを実行し、このtaskに依存する他のtaskは
  • 事前に実行される.
    次の栗は、この周期の過程を直感的に感じることができ、ドアを転送します.
    Gradle-実行タイミングの包括的な理解
    Task定義Taskは、Gradleの実行ユニットとして理解される.Gradleはtaskごとに具体的な構築タスクを完了し、Taskの定義を見てみましょう.
    task myTask {
            println "config myTask"
    }

    実行task:gradle myTaskまたはgradle clean
    config myTaskは、私がどのtaskを実行してもconfig myTaskが出力されることを示しています.これはなぜですか.
    各taskが実行される前に、完全な構成が必要です.
    しかし、多くの場合、構成コードを書く必要はありません.それは実行速度に影響しませんか?
    このときgradleの提供するいくつかのAPI方法を通じて:
    doFirst:task実行最初の操作doLast:task実行最後の操作はleftShift操作に等しいので、このオペレータ<<では構成コードと実行コードを分けてこのように書くこともできます.
    task myTask {
            println "config myTask"
    }
    
    myTask << {
            println "after execute myTask"
    }
    
    myTask.doFirst {
            println "before execute myTask"
    }

    もちろんです.多くの場合、taskを定義するときにGradle自身が提供するTaskを継承することができます.例えば、Copy、Delete、Syncなどです.
    栗をあげて、Deleteのtaskを受け継ぐ
    task clean(type: Delete) {
            delete rootProject.buildDir
    }

    プロジェクトルートディレクトリ全体のbuildフォルダを削除するには