編輯:關於Android編程
Gradle遵循約定優先於配置的概念,在盡可能的情況下提供默認的配置參數。最基本的項目有兩個”source set”組件,他們是:
1. src/main
2. src/androidTest
在裡面,每個存在的文件夾對應相對應的源組件,比如對應java plugin和Android plugin來說,他們的java代碼和資源路徑如下:
java/
resources/
但是對於Android plugin來說,它還擁有一下特有的文件夾結構:
1. AndroidManifest.xml
2. res/
3. assets/
4. aild
5. rs
6. jni
7. jniLibs
這就意味著在Android plugin下,*.java的文件的目錄是src/main/java,對於AndroidManifest.xml的目錄是src/main/AndroidManifest.xml
有一些時候我們使用一些別的項目的代碼,或者是把一些不屬於Android項目的資源之類的引入進來,可以通過如下配置,在build.gradle中引入即可,可以引入的資源和方法:
android{ main{ manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] resorces.sreDirs = ['src'] aidl.srcDirs=['src'] renderscript.srcDirs=['src] res.srcDirs=['res'] assets.srcDirs=[assets] } androidTest.setRoot('tests') }
其中,在Android特有的sourceSets在Java sourceSets中不起作用。假如是多個,比如java.srcDirs包含多個,可以使用”,”分割開來,比如 java.srcDirs=[‘src-gen’,’src-test’]。setRoot的作用就是把另外一個可以是作為獨立的測試的代碼資源的文件夾安裝main的格式合並進來,作為某一個builtType特有的資源。可以用作是測試,或者是dev或者是release等,在builtType中再去詳細介紹。
例子:比如我們現在有一個使用greendao產生的src-gen的java代碼,根目錄就是src-gen,裡面包好了greendao幫助我們產生的關於數據庫的代碼,我們再不適用copy進入項目而是可以直接使用的方式是:把src-gen目錄拷貝到跟build.gradle同級目錄,然後在build.gradle中的android節點下面,加入:
sourceSets{ main{ java.srcDirs=['src-gen'] } }
這樣子之後,我們就可以在我們的項目中引入和使用這些代碼了。
在添加了java或者的Android插件之後,gradle會自動的帶有以下task
1. assemble 組合項目的所有輸出
2. check 執行所有的檢查任務
3. build 執行assemble和check兩個task的所有工作
4. clean 清空項目的輸出,也就是build文件夾會被刪除
實際上,assemble,Check,build這三個task不做任何事情,他只是一個Task的標志,用來告訴plugin添加實際需要執行的task去完成這些工作。
task的依賴關系:當一個task依賴於另外一個task的時候,當task被調用的時候,被依賴的task會先調用,比如check task依賴於一個新task,那麼當check運行的時候,新的task會先運行。
獲取更改級別的task
gradle tasks
查看所有的task列表以及他們之間的依賴關系
gradle tasks --all
常用的task有assemble
build
buildDependents buildNeeded classes clean jar testClasses
documentation
javadoc
help
buildEnvironment components dependencies dependencyInsight help model projects properties tasks
other
compileJava compileTestJava processResources processTestResources
verification
check test
可以看到,assemble需要jar task,jar需要classes task,classes 是用於編譯java生成clazz文件的task。可以使用jar或者是assemble或者是build命令去生成jar。
check依賴於test,task,test task依賴於classes和testClasses,也就是需要運行java獲取字節碼,同時運行測試
assembbleDebug assembleRerlease
其中,單獨的assemble會依賴於上面的兩個task,會構建出兩個apk文件。
注意:Gradle在命令行上支持駝峰命名的task簡稱,比如
gradle aR
等同於
gradle assembleRelease
aD等同於assembleDebug
check task的依賴:
check 依賴 lint
connectedCheck 依賴connectedAndroidTest
deviceCheck 進行測試時才會觸發。
只要可被安裝,也就是使用了”com.android.application”gradle插件的項目,就可以被安裝。使用
installDebug //安裝debug版本 installRelease//安裝release版本 uninstallAll //卸載 uninstallDebug //卸載debug版本 uninstallRelease //卸載正式版本 uninstallDebugAndroidTest // 卸載測試
Android的常用task有:
android task
androidDependencies signingReport sourceSets
build task
assemble assembleAndroidTest assembleDebug assembleRelease build buildDependents buildNeeded classes compileDebugAndroidTestSources compileDebugSources compileDebugUnitTestSources compileReleaseSources compileReleaseUnitTestSources compileRetrolambda extractDebugAnnotations extractReleaseAnnotations jar mockableAndroidJar testClasses
build setup task
init wrapper
documentation task
javadoc
help task
buildEnvironment components dependencies dependencyInsight help model projects properties tasks
install task
installDebug installDebugAndroidTest uninstallAll uninstallDebug uninstallDebugAndroidTest uninstallRelease
other task,這個比較多,可以在AS的gradle視圖查看
assembleDebugAndroidTest assembleDebugUnitTest assembleDefault assembleReleaseUnitTest bundleDebug bundleRelease .....
verification task
check connectedAndroidTest connectedCheck connectedDebugAndroidTest deviceAndroidTest deviceCheck lint lintDebug lintRelease test testDebugUnitTest testReleaseUnitTest
minSdkVersion //app運行的最多版本 tagetSdkVersion //使用的sdk版本 versionCode //app版本code versionName //app版本name applicationId //包名 testApplicationId //測試包名 testInstrumentationRunner
這些屬性都是使用AS的android的gradle插件提供的,需要使用插件的某一個,然後在android節點下面定義。比如
android{ compileSdkVersion 23 buildToolsVersion "23.0.1"' defaultConfig{ versionCode 100 versionName "1.0.0" minSdkVersion 14 targetSdkVersion 23 applicationId "com.test.gradle" } }
通過android 節點下面的buildType節點可以構建不同的類型的apk。目前只是針對一個產品,針對多個產品的可以使用 productFlavors,這個之後再做解析。
使用buildType節點,默認的,AS會為我們添加debug和release這兩個構建類型。例如:
buildTypes { release { minifyEnabled true signingConfig signingConfigs.release proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug{ minifyEnabled false signingConfig signingConfigs.debug proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } }
這兩種類型。
其中,minifyEnabled 是是否混淆,signingConfig 是簽名,proguardFiles是混淆的文件。我們一般在開發的時候需要使用這兩個版本的apk,方便我們調試。
假如,我們需要其他的包名,或者是簽名的,可以繼續添加構建類型,比如:
buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug{ minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } dev{ minifyEnabled false applicationIdSuffix ".dev" signingConfig signingConfigs.debug } }
這樣子我們就可以構建了另一個一個dev的類型的apk,他的報名時原來的defaultConfig的applicationId+”.dev”,這是他的心新報名,我們允許的時候,可以在AS的左下角,build Variants選擇運行類型,或者是在右邊的選擇對應的task去build或者是install apk都是可以的,因為定義了對應的buildType之後,gradle會生成對應的task,比如這裡的會生成assembleDev,可以使用aD進行快速的構建。
使用buildType的另外一個好處就是可以對不同的類型使用不同的代碼或者是資源,他同樣是支持sourceSets的,可以為他自己設置不同的代碼,不同的資源,通過
sourceSets.buildType.setRoot('path')
其中path就是對應的目錄,比如是dev的就是把dev所在的目錄,相當於完整的另一個的目錄設置進去,就可以作為devbuild時候的資源了。
注意:
1. manifest 將被合並到 app 的 manifest
2. 代碼只是換了一個源文件夾
3. 資源將疊加到 main 的資源中,並替換已存在的資源。
也就是dev這個builtType會合並main文件夾的代碼和資源,合並的方式就是上面的方式。
但是實際上,建議使用的是產品定制化,也就是使用productFlavors去實現,關於productFlavors實現不同的產品定制化,在後續給大家分享。
設置簽名是位於android節點下面的signingConfigs節點下面,例如:
android { compileSdkVersion 23 buildToolsVersion "23.0.2" defaultConfig { applicationId "com.example.user.testproject" minSdkVersion 15 targetSdkVersion 23 versionCode 1 versionName "1.0" } signingConfigs { debug { storeFile file("C:\\Users\\liweijie\\Desktop\\liweijie.jks") storePassword "liweijie123" keyAlias "liweijie" keyPassword "liweijie123" } release { storeFile file("C:\\Users\\liweijie\\Desktop\\liweijie.jks") storePassword "liweijie123" keyAlias "liweijie" keyPassword "liweijie123" } dev{ storeFile file("C:\\Users\\liweijie\\Desktop\\liweijie.jks") storePassword "liweijie123" keyAlias "liweijie" keyPassword "liweijie123" } } buildTypes { release { signingConfig signingConfigs.release minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug{ signingConfig signingConfigs.debug minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } dev{ minifyEnabled false applicationIdSuffix ".dev" signingConfig signingConfigs.dev } } compileOptions { sourceCompatibility JavaVersion. VERSION_1_8 targetCompatibility JavaVersion. VERSION_1_8 } sourceSets.dev.setRoot('src/dev') }
這裡設置了debug和release簽名都是同一個,你也可以設置為不同的簽名。
其中:
storeFile file() 指定簽名的路徑,可以使用相對路徑,把對應的簽名放在項目跟對應的build同級目錄下去引用
storePassword 簽名的密碼
keyAlias 簽名的別名
keyPassword 別名對應的密碼
我們可以定義多個簽名給不同的buildType,不同對應不同的簽名,但是建議不需要太多,太多的話運行的時候回懵逼,特別是我們通過判斷簽名是否是正式的簽名來判斷代碼是否是debug狀態的時候。
使用dependencies節點,該節點是跟android節點同級的.
1、 引用本地的依賴,比如我們的jar,通過
dependencies{ compile fileTree(dir: 'libs', include: ['*.jar']) }
他會把跟src同級的libs目錄下面的jar文件作為依賴引入進來,當你存放在其他地方的時候,也可以手動的引入進來,比如我們存放在src/lib目錄下面,可以通過
dependencies { compile files('src/lib/test.jar') }
這一個方式引入進來。
2、 引用遠程的依賴
我們有時候會使用一些github的開源庫,或者是自己公司私有的maven庫或者是一些其他公司提供的倉庫,使用到他們的jar。當然我們可以把他們下載下來存放到libs目錄下面進行依賴,但是這樣子不是很方便,因為有時候版本變更的比較頻繁的時候,我們就需要經常去下載,使用遠程依賴我們就是只是需要升級一下版本號,clean一下項目就ok了。
使用方式:
dependencies { compile 'com.android.support:appcompat-v7:23.1.0' compile 'com.android.support:design:23.1.0' compile 'io.reactivex:rxandroid:1.2.1' compile 'io.reactivex:rxjava:1.1.6' }
這裡我們引入rx的依賴和v7已以及support:design依賴。依賴的引入時跟maven左邊的那種
groupId:artifactId:version
比如上面的io.reactivex就是groupId,rxJava就是artifactId,1.1.6就是version
需要使用這些依賴,同時我們需要申明倉庫地址,比如常用的maven倉庫,jcenter倉庫,我們在整個project的根目錄(也就是聲明gradle插件的地方)的build.gradle中申明。比如:
buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.2.1' classpath 'me.tatarka:gradle-retrolambda:3.2.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } }
3、引用lib依賴
我們開發的時候,常常會考慮模塊化,多人開發,功能分類等,常常有lib的抽取,同時這個lib有時候也會作為一個公用庫,做成arr給別的項目依賴,當我們需要多個lib分開整個app的模塊或者是測試我們做成的aar的lib的時候,我們就需要使用模塊依賴。
我們新建一個android lib,android插件類型是
apply plugin: 'com.android.library'
然後需要使用到的app可運行或者是其他的lib,使用
dependencies { compile project(':lib') }
其中lib就是你的lib項目。
lib是可以輸出一個arr別的lib或者是可運行的app module使用。
lib使用的android插件是com.android.library
lib包含的內容有源代碼,資源文件,清單文件,lib本身的相關依賴(so文件或者是其他的arr,jar文件)。他被依賴到別的項目的時候,資源文件和清單會被合並,當有重復命名的時候,比如同樣有兩個string的name為app_name的,那麼lib的將會被覆蓋。java代碼就是不會被合並,當存在兩個包名相同,類名相同的java文件的時候回報多個字節碼文件的錯誤。
當一個lib或者是app module依賴多個子lib的時候,假如子lib之間存在著資源沖突,也會發生某某資源已經定義的錯誤。
我們發布被依賴的lib版本的時候,可以通過buildType或者productFlavors去實現,同樣可以通過
android { defaultPublishConfig "flavor" }
其中,flavor在沒有其他定義的產品渠道的時候,是debug或者是release,一般我們使用的是release版本,假如我們需要發布多個arr,包括debug,release或者是其他flavor或者是buildType的時候,可以通過
android { publishNonDefault true }
每一個arr都是獨立的,包含自己的資源和代碼,相對應的sourceSets等。
下一篇文章分析如何構建變種apk和測試。
1 背景其實有點不想寫這篇文章的,但是又想寫,有些矛盾。不想寫的原因是隨便上網一搜一堆關於性能的建議,感覺大家你一總結、我一總結的都說到了很多優化注意事項,但是看過這些文
不廢話,先上圖,看看效果 這是用ExpandableListView來實現時間軸效果,原理比較簡單,以月份為第一級,以天為第二級來實現的。
本文實例講述了Android控件之ImageView用法。分享給大家供大家參考。具體如下:ImageView控件是一個圖片控件,負責顯示圖片。以下模擬手機圖片查看器目錄結
也許各位魅藍Note 3的機友們都有過這樣的遭遇,發現在使用文件管理器的時候修改不了外置卡的文件,這個情況其實是安卓系統的一個安全機制,當然對於喜歡倒騰的機