android gradle 插件已經發展到0.5.7,同時gradle 自己也到了1.8,相比兩個月前,android gradle 更快,更完善,也更好用了,爲了讓各位androider 早日用上gradle這樣的神器,特意寫一篇關於gradle一些奇葩錯誤的解決指南.java
之前咱們寫的時候會這麼寫android
<pre> dependencies { classpath 'com.android.tools.build:gradle:0.5.0' } </pre>web
不過,因爲android gradle 插件的開發仍是很活躍的,並且目前而言,可能還存在一些咱們不知道的坑,可是,別人踩過,後邊,官方修復,爲了避免踩坑,我建議android gradle 始終保持最新版本,寫法以下:app
<pre> dependencies { classpath 'com.android.tools.build:gradle:0.6.+' } </pre>maven
有時候,咱們的代碼使用utf-8 保存的,可是,進行gradle build 的環境是gbk這類的,這時候會包以下錯誤:ide
15: 錯誤: 編碼GBK的不可映射字符 * 鍑虹幇涓枃璇鋒敞鎰?
這個時候咱們就須要手動的設置編譯時編碼類型.gradle
<pre> tasks.withType(Compile) { options.encoding = "UTF-8" } apply plugin: 'android' android {} </pre>ui
PS: android gradle 0.6.x 之後 編譯環境默認編碼再也不依賴系統環境,所有統一爲 utf8編碼
UNEXPECTED TOP-LEVEL EXCEPTION: java.lang.IllegalArgumentException: already added: Landroid/support/v4/app/Activ ityCompatHoneycomb; at com.android.dx.dex.file.ClassDefsSection.add(ClassDefsSection.java:12 3) at com.android.dx.dex.file.DexFile.add(DexFile.java:163) at com.android.dx.command.dexer.Main.processClass(Main.java:490) at com.android.dx.command.dexer.Main.processFileBytes(Main.java:459) at com.android.dx.command.dexer.Main.access$400(Main.java:67) at com.android.dx.command.dexer.Main$1.processFileBytes(Main.java:398) at com.android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpen er.java:245)spa
出現這個問題的緣由通常是因爲咱們這樣的寫法致使:
<pre> dependencies { compile fileTree(dir: 'libs', include: '*.jar') } </pre>
某個相同的jar包,被複制到了build目錄致使重複編譯使編譯時失敗,
因爲這個問題android support v4 出現的比較多,因此同類型的都歸類爲v4 問題吧.
要避免這個問題,咱們儘可能少使用依賴某個目錄下全部包,畢竟android項目不想java web項目動不動就有好幾十jar 包依賴.要修復這個v4,原理很簡單,可使用依賴maven的寫法.
<pre> dependencies { compile 'com.android.support:support-v4:13.0.0' } </pre>
用指定依賴包的方式打包,咱們會發現,最終打包後的jar沒有了*.so文件,這個時候,咱們須要自定義一個tasks,寫以下:
<pre> task copyNativeLibs(type: Copy) { from(new File('libs')) { include '**/*.so' } into new File(buildDir, 'native-libs') } tasks.withType(Compile) { compileTask -> compileTask.dependsOn copyNativeLibs } clean.dependsOn 'cleanCopyNativeLibs' tasks.withType(com.android.build.gradle.tasks.PackageApplication) { pkgTask -> pkgTask.jniDir new File(buildDir, 'native-libs') } </pre>
這樣,在編譯時,就會自動把libs目錄下的**/*.so 文件複製到apk裏面了.
在最新版本的gradle 0.5.7 中,構建多渠道包比以前簡單多了,在之前,你須要這麼寫:
<pre> android { buildTypes { hiapk { packageNameSuffix ".hiapk" } playstore { packageNameSuffix ".playstore" } } sourceSets { hiapk { manifest.srcFile 'hiapk/AndroidManifest.xml' } playstore { manifest.srcFile 'hiapk/AndroidManifest.xml' } } } </pre>
要替換某個類型的文件須要本身手動寫,渠道多了,這代碼量是可想而知的多,在0.5.7中,進行了一個約定規則,構建,渠道包你只需
<pre> android { buildTypes { hiapk { packageNameSuffix ".hiapk" } playstore { packageNameSuffix ".playstore" } } sourceSets { hiapk.setRoot('build-types/hiapk') playstore.setRoot('build-types/playstore') } } </pre>
在項目的根目錄下建立一個build-types的目錄,在建立對應渠道的子目錄,而後把一些,諸如要替換AndroidManifest.xml,裏面友盟渠道號什麼的,直接把xml複製進去就行,gradle在構建項目的時候,會自動的優先使用build-types下目錄文件的目錄,諸如,根據不一樣渠道,不一樣國家換個程序圖標什麼的,都只要放到目錄下便可.