作者:codelang
寫這款工具主要是看了優酷的幾篇
向工程腐化開炮
的系列文章,覺得其中的幾個點可以通過依賴檢查的方式提前找到問題,是以着手找了幾個點寫了下,并輸出 report html 友善檢視。
一、檢查
目前該檢查工具提供了 5 項内容的檢查:
- so 檔案檢查
- 64 位 so 未适配檢查
- 更安全的導出元件檢查
- 未比對的權限檢查
- uses-sdk 檢查
1、so 檔案檢查
so 檔案檢查可以分析出依賴裡面包含了多少個 so 檔案,并且展示 so 大小,做這個可以輔助 apk 包體積優化來提前分析,哪些 so 檔案過大,并且這個 so 檔案屬于哪個依賴,然後根據依賴找到開發責任人進行溝通,如下是檢查結果展示:
2、64 位 so 未适配檢查
Google Play 自 2019 年 8 月 1 日起就強制應用必須支援 64 位 架構,但國内的應用市場會相對應的滞後:
平台 | 32 位庫檔案夾 | 64 位庫檔案夾 |
ARM | lib/armeabi-v7a | lib/arm64-v8a |
x86 | lib/x86 | lib/x86_64 |
對于我們工具的檢查,隻需要周遊擷取 32 位 so 的檔案名稱,然後去查下這個檔案在 64 位的目錄下存不存在,如果存在,說明該 so 支援,反之不支援,檢測效果如下:
3、更安全的導出元件檢查
在 Android 12 的适配中,如果 activity、received 和 service 有使用 intent-filter,則必須顯示申明 exported 的值,否則應用将無法在搭載 Android 12 或更高版本的裝置上進行安裝。工具檢測效果如下:
4、未比對的權限檢查
在我們的應用開發中,會對所有的權限申明進行管控,每個敏感權限的申請都需要經過團隊的把關,也即意味着權限不能亂申請和亂用。是以,我們需要事先申明好一份白名單配置,在檢查依賴的過程中,如果依賴中的 AndroidManifest.xml 申明的權限不在這個白名單中,則會提示該依賴使用了白名單之外的敏感權限,需要進行确認。工具檢測效果如下:
5、uses-sdk 檢查
manifest 中一些全局性配置,對 apk 安裝和運作時行為具有重要影響,最為典型的就是 minSdkVersion和 targetSdkVersion,一旦非預期變更被帶到線上,後果不堪設想。
檢查工具會檢查如果與白名單的配置不一緻,則會輸出結果:
二、使用
如果想體驗 demo 的話,可以直接執行指令:
./gradlew checkDependency -Pbuild=debug
他會在 build 的 checkPlugin 目錄輸出 html 報告檔案,用浏覽器打開即可預覽:
當然,你也可以直接檢視 demo 輸出的報告,我已經給倉庫開通了 github pages,html 浏覽位址為 mrwangqi.github.io/pluginDemo/
1、接入
嘗試過幾次在 jitpack 釋出 gradle 插件,經常會報莫名的錯誤,是以,就不打算對外釋出插件了,如果想用到自己項目的話,可以釋出到 maven local,展開 task 點選 publish 釋出到本地:
然後在在自己項目的 build.gradle 中配置 mavenLocal 鏡像源和依賴,示例如下:
buildscript {
repositories {
...
// 配上本地 maven 源
mavenLocal()
}
dependencies {
classpath "com.android.tools.build:gradle:7.0.4"
// 依賴 check 插件,版本号可以釋出本地 maven 之前修改
classpath "com.github.MRwangqi:checkPlugin:1.0.0"
}
}
然後在 app 工程的 build.gradle 中依賴插件,并且在工程下面配置白名單檔案:
plugins {
id 'com.android.application'
// apply check 插件
id 'checkPlugin'
}
check{
// 配置白名單
manifestWhiteFile="ManifestWhite.xml"
}
ManifestWhite.xml 檔案如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.codelang.includebuildingdemo">
<!-- 插件會讀取 uses-sdk ,如果分析出的依賴不等于 targetSdk 或是如果不等 minSDK 則會輸出分析-->
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="30" />
<!-- 插件會讀取 uses-permission ,如果分析出的依賴權限不在下面則會輸出分析-->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
</manifest>
2、使用
執行指令模闆如下:
./gradlew checkDependency -Pbuild=${build variant}
要執行的 build variant 可以在 Android studio 中檢視:
比如我們要檢查 debug 的依賴分析,則指令如下:
./gradlew checkDependency -Pbuild=debug
當然,也可以直接使用如下指令進行檢查,插件預設的 build variant 是 debug
./gradlew checkDependency
三、原理
原理很簡單,就是從 configurations 中拿到繼承自 implements 的 CompileClassPath configuration,然後通過 asPath 方法拿到所有依賴緩存到本地的路徑,然後解析依賴拿到檔案和内容進行分析,然後産出報告,具體可以檢視源碼。
四、總結:
基于工程腐化系列的文章其實可以做很多的檢查,比如混淆章節中:
layout 中引用不存在的 class 需要進行檢查,而且在 apk 編譯過程中,并不會引發建構失敗,但依然會生成相對應的keep規則,并且這個layout 一旦在運作時被“加載“,那麼會引發 Java 類找不到的異常