編輯:關於Android編程
在一個工程項目中,我們可能會有多個Module,如:多個app,library。
我們來看下一個最簡單的多個Module的build文件結構。
如果我們的app項目中依賴多個lib,這樣在項目中顯示的會有點亂,我們可以通過一個目錄管理它們,如:
1.在setting.gradle文件中: include ':app',':libraries:library1',':libraries:library2' 2.在app項目的build.gradle文件中: dependencies{ compile project(':libraries:library1') }
如果你的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中。
在Project工程的gradle.properties文件中
org.gradle.parallel = true //加快編譯,其實這個配置默認被注釋的,只要打開注釋就好
Gradle會嘗試根據CPU核數選擇正確的線程數量。為了防止可能出現的問題,從同一個模塊並行執行兩個任務,每一個線程擁有一個完整的模塊。
在一個項目中有多個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的時候任務是耦合的。
定義2個任務task1和task2
task task1<<{ println 'task1' } task task2<<{ println 'task2' }mustRunAfter
task2.runMustAfter task1 //task2執行在task1後面 執行命令: gradlew task2 task1 log打印結果: :task1 task1 :task2 task2dependsOn
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
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")) } } }
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" } }
這樣就可以過濾一些不要的資源。
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 } } }
當我們執行release編譯時,Lint在編譯的時候可能會找到一些錯誤,會導致Gradle編譯失敗,Gradle可以忽略Lint錯誤,阻止中斷編譯過程,如:
android{ lintOptions{ abortOnError false //默認true,false表示錯誤不中斷編譯 } }
Gradle是直接支持運行一個標准的Ant
task archive<<{ ant.echo 'Ant is acthiving......' ant.zip(destfile:'archive.zip'){ fileset(dir:'zipme') } }
這個task使用了2個Ant任務,echo和zip。
如果你創建了一個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,如:
執行gradlew hello 打印結果: :hi Hi :hello [ant:echo] Hello Ant Hello Gradle Hello Ant
如果你的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
設備是允許通過屏幕密度(density)或者是ABI(application binary interface)來拆分apk的。
通過density進行split apkandroid{ 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 } } }
一、介紹一個橫向進度條 下載完成區域有一個滑塊不斷從左往右滑動(最開始就是被這個吸引的,就想著這個怎麼實現的) 進度條中間顯示當前進度,值得注意的是,進度條文本包含在下載
TouchImageView繼承自ImageView具有ImageView的所有功能;除此之外,還有縮放、拖拽、雙擊放大等功能,支持viewpager和scaletype
今天主要分析下ActivityManagerService(服務端) 與應用程序(客戶端)之間的通信模型,在介紹這個通信模型的基礎上,再簡單介紹實現這個模型所需要數據類型
本文實例講述了Android開發之簡單文件管理器實現方法。分享給大家供大家參考,具體如下:這裡運用Java I/O、ListActivity、Dialog、Bitmap等
測試環境: win7 64 g++ 4.8.1 /*