Android打包優化

Android混淆

http://www.jianshu.com/p/7436a1a32891“>Android 混淆從入門到精通

buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

proguard-android.txt 

  1. jni方法不可混淆,因爲這個方法需要和native方法保持一致;
  2. 反射用到的類不混淆(否則反射可能出現問題);
  3. AndroidMainfest中的類不混淆,所以四大組件和Application的子類和Framework層下所有的類默認不會進行混淆。自定義的View默認也不會被混淆;所以像網上貼的很多排除自定義View,或四大組件被混淆的規則在Android Studio中是無需加入的;
  4. 與服務端交互時,使用GSON、fastjson等框架解析服務端數據時,所寫的JSON對象類不混淆,否則無法將JSON解析成對應的對象;
  5. 使用第三方開源庫或者引用其他第三方的SDK包時,如果有特別要求,也需要在混淆文件中加入對應的混淆規則;
  6. 有用到WebView的JS調用也需要保證寫的接口方法不混淆,原因和第一條一樣;
  7. Parcelable的子類和Creator靜態成員變量不混淆,否則會產生Android.os.BadParcelableException異常;
-keep class * implements Android.os.Parcelable { # 保持Parcelable不被混淆            
    public static final Android.os.Parcelable$Creator *;
}
  1. 使用enum類型時需要注意避免以下兩個方法混淆,因爲enum類的特殊性,以下兩個方法會被反射調用,見第二條規則。
-keepclassmembers enum * {  
    public static **[] values();  
    public static ** valueOf(java.lang.String);  
}

打包提速

刪除無用的module,lint清理資源文件,刪除test模塊,減少方法數,multidex最費時。

利用no-op加快debug的速度

剔除重複引用的包

exclude group: 'com.android.support', module: 'support-v4'

放棄lambda,謹慎使用AspectJ

利用MultiChannelPackageTool進行多渠道打包

原理是在zip文件的comment中加入渠道號,這樣既可以寫入渠道號又不會破壞zip的簽名,因爲apk本身就是一個zip文件,所以這個規則是可靠並完全適用的。

Android打包黑科技

http://geek.csdn.net/news/detail/76488

添加comments多渠道打包

首先解釋什麼是comments(註釋或評論)的打包方式?

Android應用使用的APK文件就是一個帶簽名信息的zip文件,根據zip文件格式規範(請參見:https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT),
每個文件的最後都必須有一個叫Central Directory Record
https://users.cs.jmu.edu/buchhofp/forensics/formats/pkzip.html)的部分,這個CDR的最後部分叫“End of Central Directory Record”,這一部分包含一些元數據,它的末尾是zip文件的註釋。註釋包含Comment Length和File Comment兩個字段。前者表示註釋的長度,後者是註釋的內容,正確修改這一部分不會對zip文件造成破壞,利用這個字段,我們可以添加一些自定義數據。

簡單來說就是:我們利用的是zip文件“可以添加comment(摘要)”的數據結構特點,在文件的末尾寫入任意數據,而不用重新解壓zip文件(apk文件就是zip文件格式);所以該工具不需要對APK文件解壓縮和重新簽名即可完成多渠道自動打包,可謂是高效、速度快,無兼容問題。

這種高效的方式是奇虎360的一位工程師公佈的,他已經把相關工具的代碼開放在GitHub上面了,地址爲https://github.com/seven456/MultiChannelPackageTool。工具本身爲命令行形式,一條命令即可生成一個多渠道包,並且非常高效。作者本人公佈的性能數據是:5M的APK,1秒種能打300個。

可以在下載完了再添加渠道。

美團的Android多渠道打包

把一個Android應用包當作zip文件包進行解壓,然後發現在簽名生成的目錄下添加一個空文件不需要重新簽名。利用這個機制,該文件的文件名就是渠道名。這種方式不需要重新簽名等步驟,非常高效。

首先把一個已經簽名好的Android應用程序包解壓縮,簽名文件的目錄爲:META-INF,如圖1所示。
分別爲:assets目錄和META-INF目錄

豌豆莢Android多渠道打包

豌豆莢的多渠道打包方案和美團的所用的方式一樣,都是添加一個文件,文件本身會帶入渠道消息。但不同點在於它添加的是一個不爲空的文件。之前已經提到過了,如果添加一個非空文件,就會破壞簽名校驗,需要重新簽名。

加入渠道時主要有以下步驟:
1. 首先需要準備好渠道文件。在Android應用程序包的同級目錄,新建一個assets目錄,並且在該目錄下放入一個channel.txt文件,文件內容是渠道信息,可以是wandoujia或360等。
2. 使用AAPT加入渠道文件:

aapt add wandoujia.apk asserts/channel.txt

3. 在渠道加入後,重新簽名APK文件並且進行對齊。

重新簽名相關的步驟就不再介紹了,如果感興趣的話,推薦看一下calabash-android這個開源項目的resign相關部分實現,calabash的重新簽名實現是我見過最嚴謹的。

從安全的角度看多渠道打包方案

在介紹篡改渠道之前,還是先簡單介紹AAPT這個工具的一般使用方法。在AndroidSDK的build-tools中。
* 查看Android開發包的基本信息,例如:包名、版本等。以微信的Android版本爲例:

```
'' INPUT  apt dump badging weixin.apk
'' OUTPUT package: name='com.tencent.mm' versionCode='740' versionName='6.3.13.49_r4080b63'
'' uses-permission:'com.tencent.mm.plugin.permission.READ'
'' uses-permission:'com.tencent.mm.plugin.permission.WRITE'
'' uses-permission:'com.tencent.mm.permission.MM_MESSAGE'
''  uses-permission:'com.huawei.authentication.HW_ACCESS_AUTH_SERVICE'
'' sdkVersion:'15'
'' targetSdkVersion:'23'
'' uses-feature-not-required:'android.hardware.camera'
'' uses-feature-not-required:'android.hardware.camera.autofocus'
'' uses-feature-not-required:'android.hardware.bluetooth'
'' uses-feature-not-required:'android.hardware.location'
'' uses-feature-not-required:'android.hardware.location.gps'
'' uses-feature-not-required:'android.hardware.location.network'
'' uses-feature-not-required:'android.hardware.microphone'
'' uses-feature-not-required:'android.hardware.telephony'
'' uses-feature-not-required:'android.hardware.touchscreen'
'' uses-feature-not-required:'android.hardware.wifi'
'' uses-permission:'android.permission.ACCESS_NETWORK_STATE'
'' uses-permission:'android.permission.ACCESS_COARSE_LOCATION'
'' uses-permission:'android.permission.ACCESS_FINE_LOCATION'
'' uses-permission:'android.permission.CAMERA'
'' .....
```

* 使用AAPT查看Android開發包的目錄結構如下:

'' INPUT aapt list weixin.apk
'' OUTPUT META-INF/MANIFEST.MF
'' META-INF/COM_TENC.SF
'' META-INF/COM_TENC.RSA
'' assets/jsapi/wxjs.js
'' assets/avatar/default_nor_avatar.png
'' assets/avatar/default_meishiapp.png
'' assets/avatar/default_hd_avatar.png
'' assets/ipcall_country_code.txt
'' assets/merged_features.xml
'' assets/address
'' .....

* 使用AAPT添加一個文件:

'' INPUT aapt add wandoujia.apk assets/channel.txt

* 使用AAPT刪除一個文件

'' INPUT aapt remove wandoujia.apk assets/channel.txt

在掌握了以上簡單的四個命令行後,修改美團的渠道就已經非常簡單了。先通過list命令找到渠道文件,然後直接刪除文件,最後再加入自己的惡意渠道。但豌豆莢的渠道也可以通過相同的方式來進行篡改,但篡改之後需要重新簽名。在沒有官方的簽名文件時,是沒有辦法完全僞造一個相同的簽名的。

添加comments多渠道打包方式中雖然渠道信息不是明文顯示,但也存在着被篡改的可能性。如果自己進行一些簡單的加密可以杜絕大多數的惡意篡改,但由於不需要重新簽名,這種方法還是存在着被篡改的機率的。

具體選擇哪一種多渠道打包方式,還是由業務決定的。豌豆莢作爲一個應用商店,需要有自己的渠道,渠道的安全性會很不好。如果是一個普通的App,一般都是在一些應用商店上發佈新版本,應用商店本身會給開發者提供相對安全的環境。所以這也就是美團方案依然能夠使用的關鍵。

美團Android自動化之旅—生成渠道包

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章