天天看點

依賴檢查的插件

作者: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 類找不到的異常