Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Gradle for Android學習筆記(二)

Gradle for Android學習筆記(二)

編輯:關於Android編程

Gradle之管理多個Module編譯

在一個工程項目中,我們可能會有多個Module,如:多個app,library。

我們來看下一個最簡單的多個Module的build文件結構。

image

如果我們的app項目中依賴多個lib,這樣在項目中顯示的會有點亂,我們可以通過一個目錄管理它們,如:

image

1.在setting.gradle文件中:

include ':app',':libraries:library1',':libraries:library2'

2.在app項目的build.gradle文件中:

dependencies{
    compile project(':libraries:library1')
}

Integrating Android Wear(整合穿戴設備)

如果你的app項目需要支持可穿戴設備,你可能需要在項目中添加一個Android Wear module。

在Android Wear項目中的build.gradle文件中

dependencies{
     compile fileTree(dir: 'libs', include: ['*.jar'])    
     compile 'com.google.android.support:wearable:1.1.0'    
     compile 'com.google.android.gms:play-services-wearable:6.5.87' 
}


在app項目中的build.gradle文件中

dependencies{
    wearApp project(":wear")    //wear是Android Wear項目的名稱
}

這個wearApp的配置確保是Android Wear的module的apk文件,添加到最終的Android app項目的打包的APK中。


快速編譯多個module

在Project工程的gradle.properties文件中

org.gradle.parallel = true  //加快編譯,其實這個配置默認被注釋的,只要打開注釋就好

Gradle會嘗試根據CPU核數選擇正確的線程數量。為了防止可能出現的問題,從同一個模塊並行執行兩個任務,每一個線程擁有一個完整的模塊。


Module coupling(Module耦合)

在一個項目中有多個Module,我們可以把一些共有的配置抽取出來,放到root Project工程的build.gradle文件中allprojects{}中,如:

allprojects{
    apply plugin:'com.android.application'

    android{
        compileSdkVersion 24
        buildToolsVersion "24.0.0"
    }
}

或者是使用ext{}的方式(詳情見上篇)時,

如果這是你使用gradle.properties文件中的配置,如:

org.gradle.parallel=true

就會導致編譯失敗,原因是org.gradle.parallel=true會對每一個build任務采用一個線程執行(根據CPU的核心線程數分配),所以需要保持每個Module中的build任務獨立,采用allproperties和ext{}方式在build的時候任務是耦合的。


多任務Tasks執行的順序

定義2個任務task1和task2

task task1<<{
    println 'task1'
}

task task2<<{
    println 'task2'
}
mustRunAfter
task2.runMustAfter task1    //task2執行在task1後面

執行命令:
gradlew task2 task1 


log打印結果:

:task1
task1
:task2
task2
dependsOn
task2.dependsOn(task1) 或者 task2.dependOn task1  //task2任務依賴於task1,執行task2就會先執行task1

執行命令
gradlew task2


log打印結果:
:task1
task1
:task2
task2

自定義任務保護簽名信息的私密性

我們在設置簽名配置的時候,一般是通過明碼寫入在build.gradle文件中的。
如果拿到build.gradle文件就會暴露我們的keypassword等私密信息。

我們可以通過將這些私密信息寫到一個private.properties文件中,通過load這個文件中的配置來設置keypassword等私密信息。

1.在Project的根目錄下,創建一個private.properties文件,並寫好配置信息。
如:

release.password = newpassword

2.在Module中的build.gradle文件中創建一個任務

task getReleasePassword<<{
    def password=""

    if(rootProject.file('private.properties').exists()){
        Properties properties = new Properties();
        properties.load(rootProject.file('private.properties').newDataInputStream())    //加載文件

        password = properties.getProperty('release.password')   //獲取配置文件中的release.password的值,復制給password變量
    }   
}

3.做一個判斷,只針對release版本

task.whenTaskAdded{theTask->
    if(theTask.name.equals("packageRelease")){
        theTask.dependsOn "getReleasePassword"
    }
}

4.在buildTypes{}中的release{}配置中使用簽名配置

android.signingConfig.release.storePassword = password
android.signingConfig.release.keyPassword = password

Automatically renaming APKs(自動重命名apk)

android.applicationVariants.all{variant ->
    variant.output.each{output ->
        def file = output.outputFile

        if (outputFile != null && outputFile.name.endsWith('.apk')) {
            output.outputFile = new File(file.parent,file.name.replace(".apk","-${variant.versionName}.apk"))
        }       
    }
}

減小APK文件體積

ProGuard

混淆工具,通過minifyEnabled設置true,開啟混淆。ProGuard混淆工具修改類名和字段名保護apk的安全,同時也會壓縮apk的體積。

android{
    buildTypes{
        release{
            minifyEnabled = true
            ...
        }
    }
}

Shrinking resources

去除沒有使用過的resource,通過shrinkResource設置true。它可以在混淆的時候知道哪些resource使用了,如果resource沒有使用,會在混淆時過濾。

android{
    buildTypes{
        release{
            ...
            shrinkResource = true
        }
    }
}

Manual shrinking:

如果你的app中僅支持1,2種語言,但是可能引用的lib庫包含多種其他語言的strings資源,這個時候我們可以通過resConfig指定我們需要的strings資源。

    android{
        defaultConfig{
            resConfigs 'en','cn'
        }
    }

同樣我們可以指定我們需要支持的某些設備屏幕尺寸。如:

    android{
        defaultConfig{
            resConfigs "hdpi","xhdpi","xxhdpi","xxxhdpi"
        }
    }

這樣就可以過濾一些不要的資源。


Speeding up builds(加快編譯速度)

Gradle properties

通過設置Gradle的屬性配置的方式(在Project工程下的gardle.properties文件中配置相應的屬性),如:

org.gradle.parallel = true

parallel build是通過CPU的核心線程數來給每一個工程合理的分配一個獨立的線程進行編譯。

org.gradle.daemon = true

在Android Studio,Gradle daemnon 是默認true的。它的意思是,你第一次編譯後,下一次編譯就會更快一些。如果你使用命令行編譯,deamon值是不可用的,除非你設置org.gradle.daemon屬性true。

org.gradle.jvmargs = -Xms256m -Xmx1024m

jvmargs給JVM內存池設置不同的內存值。

Xms:設置初始的內存值,256m代表內存大小。

Xmx:設置最大的內存值,1024m代表內存大小。

org.gradle.configureondemand = true

configureondemand:如果設置為true,在運行配置信息之前,Gradle會試著算出modules中的configuration那些改變了,哪些沒有改變。

它會試著跳過modules中不執行的tasks,限制一些是小的configguration。

如果你的項目中有多個module,這個屬性對你來說是比較有用的。

Profiling

如果你想找到build慢的原因,你可以給Gradletask 添加一個–profile標簽,當你執行task時,Gradle會創建一個Profiling報告,告訴你build的那個部分最耗時。這個報告以html格式保存在build/reports/profile目錄。

Jack and Jill(不推薦使用)

Jack(Java Android Compiler Kit)

Jack是一個新的Android編譯工具,可以直接將Java源碼直接編譯成dex文件格式。他有自己的.jack庫。

Jill(Java Intermediate Library Linker)

Jill是一個可以將.aar或.jar文件轉成.jack庫工具。

這2個工具提高了編譯時間,簡化了編譯過程,但是不推薦使用。

Jack的使用

android{
    defaultConfig{
        useJack = true
    }
}

或者

android{
    productFlavors{

        store1{
            useJack = false
        }

        store2{
            useJack = true
        }
    }
}

Ignoring Lint

當我們執行release編譯時,Lint在編譯的時候可能會找到一些錯誤,會導致Gradle編譯失敗,Gradle可以忽略Lint錯誤,阻止中斷編譯過程,如:

android{
    lintOptions{
        abortOnError false  //默認true,false表示錯誤不中斷編譯
    }
}

Gradle 運行Ant任務

Gradle是直接支持運行一個標准的Ant

task archive<<{
    ant.echo 'Ant is acthiving......'

    ant.zip(destfile:'archive.zip'){
        fileset(dir:'zipme')
    }

}

這個task使用了2個Ant任務,echo和zip。

導入Ant腳本

如果你創建了一個Ant腳本,你可以使用ant.importBuild導入編譯配置。所有的Ant targets會自動轉成Gradle的task。

例如:

Ant的編譯文件build.xml


    
        Hello Ant
    

你可以導入Gradle編譯中:

ant.importBuild 'build.xml'

執行命令與結果:

gradlew hello

打印結果:
:hello
[ant:hello] Hello Ant

Ant task和Gradle task一起使用

hello{
     println 'Hello, Ant. It\'s me, Gradle' 
}

執行 gradlew hello


打印結果如下:

:hello
[ant:hello] Hello Ant
Hello, Ant. It's me, Gradle

Gradle task依賴Ant task,如:

task hi(dependsOn:hello)<<{
    println 'Hi'
}


執行gradlew hi

打印結果

:hello 
[ant:echo] Hello Ant 
Hello Gradle 
:hi 
Hi 

Ant task依賴Gradle task,如:

   
    Hello Ant 
 


執行gradlew hello

打印結果:
:hi 
Hi 

:hello 
[ant:echo] Hello Ant 
Hello Gradle 

如果你的Ant編譯文件中,包含比較多的task,為了避免覆蓋,可能需要重命名,如:

ant.importBuild('build.xml'){antTargatName->
    'ant-' + antTargetName
}

如果你的ant task重命名了,注意在與Gradle task相互依賴時,需要將ant task名字改過來。不然會報UnKnownTaskExecption。

Ant Properties

Ant還可以通過build.xml在Gradle中定義屬性,如:


    ${version}

在Gradle中定義version的屬性

ant.version = '1.0'

或者

ant.properties['version'] = '1.0'

執行命令:

gradlew appVersion


執行結果:

:appVersion
[ant:echo] 1.0

Split Apk

設備是允許通過屏幕密度(density)或者是ABI(application binary interface)來拆分apk的。

通過density進行split apk
android{
    split{
        density{
            enabled true
            exclude 'ldpi','mdpi'
            compatibleScreen 'normal','large','xlarge'
        }
    }
}
生成結果:
app-hdpi-release.apk
app-universal-release.apk
app-xhdpi-release.apk
app-xxhdpi-release.apk
app-xxxhdpi-release.apk
通過ABI進行split apk
android{
    split{
        abi{
            enabled true
            include 'armeabi','x86','mips'
            universaiApk true
        }
    }
}
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved