ApkChecker_new Android 包大小檢測及趨勢統計
GitHub地址 :https://github.com/pengchenglin/ApkChecker_new
根據@xinxi的Android 包大小檢查測試方案,增加了android bundle包的檢測,和一個web的頁面展示。
使用到的工具有:
基於Flask 和Bootstrap 優化了報告展示的UI頁面。少廢話,先看東西。
如何執行
由於使用到了matrix-apk-canary-0.6.5.jar和bundletool-all-0.15.0.jar兩個jar包,
首先要確保java環境已配置正確
- clone專案到本地
- 安裝python3及相關依賴的庫
pip3 install -r requirements.txt
- 使用 gunicorn執行
cd /GitHub/ApkChecker_new
gunicorn -w 4 -b 0.0.0.0:9876 server:app --timeout 300
# 300秒延時等待防止上傳apk後,後臺處理時長過長的保護性等待,沒加可能會導致aab的包處理超時導致報告生成失敗
App Bundle
什麼是App Bundle
App Bundle 是一種新的安卓編譯打包方式,編譯工具可以根據CPU架構型別、螢幕解析度、語言等維度將一個傳統的App 打包成一個App集合;使用者下載App時,應用市場會根據終端三種維度的型別提供僅適配此終端的App子集,從而在提供相同業務功能的前提下,節省使用者的網路流量與終端裝置空間。(副檔名為 .aab)
App bundle 是經過簽名的二進位制檔案,可將應用的程式碼和資源整理到模組中,如下圖所示。以藍色標識的目錄(例如 drawable/、values/ 和 lib/ 目錄)表示 Google Play 用來為每個模組建立配置 APK 的程式碼和資源。
更多關於App Bundle的資料可以從檢視 Android App Bundle 簡介
使用 bundletool 命令列工具進行測試
App Bundle的副檔名為 .aab,使用adb install
是沒辦法直接將應用安裝到手機的。Google 提供了bundletool 命令列工具實現aab檔案的安裝及資訊檢視。
當 bundletool 根據您的 app bundle 生成 APK 時,它會將這些 APK 納入到一個名為“APK set archive”的容器中,該容器以 .apks 作為副檔名。請使用 bundletool build-apks
命令來生成apks
java -jar bundletool-all-0.15.0.jar build-apks --bundle=/MyApp/my_app.aab --output=/MyApp/my_app.apks
apks裡面的內容如下,不同的app有所不同
由於部分版本(Android 5.0 以下) 不支援app Bundle功能,個別場景我們需要返回全量包,想要完整的apk,可以在上面的命令列後面加上--mode=universal
的引數就行
java -jar bundletool-all-0.15.0.jar build-apks --bundle=/MyApp/my_app.aab --output=/MyApp/my_app.apks --mode=universal
apks裡面就只有一個完整的universal.apk,解壓出來直接adb install universal.apk
就好啦
生成的apks 安裝到android裝置上需要執行下面的命令:
java -jar bundletool-all-0.15.0.jar install-apks --apks=/MyApp/my_app.apks
估算apks檔案實際安裝到手機上的apk大小,可以使用下面的命令:
java -jar bundletool-all-0.15.0.jar get-size total --apks=/MyApp/my_app.apks
更多bundletool的使用說明可以檢視:https://developer.android.com/studio/command-line/bundletool
Matrix-APKChecker
Matrix-ApkChecker 是微信針對android安裝包的分析檢測工具,根據一系列設定好的規則檢測apk是否存在特定的問題,並輸出較為詳細的檢測結果報告,用於分析排查問題以及版本追蹤。Matrix-ApkChecker以一個jar包的形式提供使用,通過命令列執行 java -jar ApkChecker.jar
` 即可執行。
簡單使用命令如下:
java -jar matrix-apk-canary-0.4.10.jar --apk <your_apk_path>
使用配置檔案命令如下:
java -jar matrix-apk-canary-0.4.10.jar -apk <your_apk_path> --config <your_config_path>
具體的使用和操作可以檢視:Matrix Android ApkChecker README
APP Bubdle檔案如何結合Matrix-APKChecker檢查包大小資訊
aab檔案通過bundletool命令列生成apks後(其實apks就是個壓縮檔案),解壓後發現裡面就是按照相關的邏輯生成了多個apk。google會根據裝置的相關配置,安裝上對應的apk達到縮小app大小的目的。
由於我測試的app,打包的aab通過bundletool命令列生成apks發現,其實裡面就是一個base-master.apk 和另外兩個base-arm64_v8a.apk和base-armeabi.apk。後兩其實是根據手機是否為64位分出來的兩個包,包含了不同的資源。只要知道其大小就好了,我只要用Matrix-APKChecker檢查去base-master.apk就可以了。
所以對於App Bundle的aab檔案,我處理的方式是
- 先使用bundletool 生成apks
- 解壓出apks裡的多個apk
- 記錄base-arm64_v8a.apk和base-armeabi.apk的檔案大小,用Matrix-APKChecker檢查去base-master.apk
- 然後將資料整理以報告的形式展示
基於Flask的web頁面
上面講了App Bundle 和Matrix-APKChecker的內容,下面講解下Web頁面是怎麼實現的
路由及頁面跳轉
route | templates |
---|---|
/ | home.html |
/<package> | dashboard.html、dashboard_aab.html |
/<package>/reports/<report_path> | report_template.html、report_template_aab.html |
dashboard頁面展示
上傳apk
點選上傳apk的按鈕後,彈出的彈框相關操作使用了Bootstrap的模態框(Modal),判斷是否為apk、aab的檔案,上傳到工程目錄下的update資料夾下,執行run,執行生成報告html檔案,並彈出alert 提示後自動跳轉到詳情報告頁面。
server.py
@app.route('/upload', methods=['GET', 'POST'])
def upload():
'''上傳apk、aab檔案'''
if request.method == 'GET':
return "is upload file ... "
else:
path = request.form.get('upload_path')
file = request.files['upload_file']
file_name = file.filename
if os.path.splitext(file_name)[-1][1:] not in ['APK', 'apk', 'aab']:
return jsonify({"code": 200, "info": "檔案:%s 不是apk or aab,請重試" % file_name})
else:
base_dir = config.tmp_upload_path
if not os.path.exists(base_dir):
mk_dir(base_dir)
base_dir = config.tmp_upload_path
file.save(os.path.join(base_dir, path, file_name))
logger.info('上傳%s' % file_name)
report_info = run(os.path.join(base_dir, path, file_name))
return jsonify({"code": 200, "info": "%s報告生成成功,即將跳轉%s" % (file_name, report_info['report_path']),'report_info': report_info})
home.html、 dashboard.html、 dashboard_aab.html
$('#upload').click(function() {
var upload_path = $('#upload_path').text();
var formData = new FormData($('#upload-form')[0]);
formData.append("upload_path", upload_path);
window.alert("檔案後臺上傳處理中,請稍後");
$.post({
url: '/upload',
dataType: 'json',
type: 'POST',
data: formData,
async: true,
cashe: false,
contentType: false,
processData: false,
success: function(returndata) {
if (returndata['code'] == 200) {
var info = returndata['info'];
alert(info);
var report_path =returndata['report_info']['report_path'];
window.location.href = report_path;
}
},
error: function(returndata) {
alert("報告生成失敗!")
}
})
});
報告統計頁面展示
統計頁面左側可以切換不同的apk 包檢視相應的包歷史大小資訊,由於沒有使用到資料庫,每次生成的html都會儲存在Project_path/Report/<package_name>
/reports的路徑下面,並且更新資料夾下的rs.json
檔案。 每次的頁面載入獲取資料都是讀取Project_path/Report/
下的檔案目錄結構和相應的rs.json
檔案資訊後展現出來的。
- 預設導航欄顯示的名稱為
Project_path/Report/
下各個<package_name>
資料夾的名字- 想要左側的導航欄內的不顯示packagename而是對應的app名稱,可以去
config.py
的dict internalapp
中填寫上自己app的包名和APP名稱- 同一個包名的,apk和aab會存放在兩個資料夾下,aab的包的會自動生成以
_aab
結尾的資料夾
由於apk和aab的資料內容有差別,web頁面展示也有所不同,統計頁面分別以dashboard.html、 dashboard_aab.html
模板,要是剛開始沒有任何報告的時候(Project_path/Report/
都還沒有的時候),則以home.html
為模板展示首頁。
server.py
@app.route('/')
@app.route('/<package>')
def statistics(package=None):
'''模板生成統計報告'''
folders = get_report_folders()
if folders:
if not package:
package = list(folders.keys())[0]
else:
pass
if not os.path.exists(os.path.join(config.report_folder, package, 'rs.json')):
pass
else:
reports_info = json.loads(read_file(os.path.join(config.report_folder, package, 'rs.json')))
reports_info['last']['package'] = package
report_list = reports_info['total']
script_list = make_script_str(report_list)
page, per_page, offset = get_page_args(page_parameter="page", per_page_parameter="per_page")
pagination_users = get_users(report_list, offset=offset, per_page=per_page)
pagination = Pagination(
page=page,
per_page=per_page,
total=len(report_list),
record_name="users",
css_framework="bootstrap4"
)
context = {
'urls': pagination_users,
'size_list': script_list[1],
'time_list': script_list[0],
'package': package,
'folders': folders,
'appname': reports_info['last']['appname']
}
if 'aab' in package:
return render_template("dashboard_aab.html", context=context, per_page=per_page, pagination=pagination)
else:
return render_template("dashboard.html", context=context, per_page=per_page, pagination=pagination)
else:
return render_template("home.html")
包打大小曲線圖繪製
報告上的折線圖是從Highcharts 演示 › 可縮放的時間軸修改而來的,在dashboard.html、 dashboard_aab.html
內編輯好相應html和js程式碼後,傳入的資料為apk的大小及報告的建立時間,都是在rs.json
中已經生成儲存好了的。
詳情報告頁面的,餅圖也是用的Highcharts 演示 › 基礎餅圖。
這個網站提供了豐富的報表展示效果,支援線上編輯和除錯,提供多種主題的選擇。
表格及分頁
每個包大小詳情的基本資料組成的表格在web頁面展示,內容傳入也都是在rs.json的total
中已經儲存好了的。只需要將資料傳入就行
dashboard.html
<div class="table-responsive">
<table class="table table-striped table-sm table-bordered">
<thead class="table-dark">
<tr>
<th>#</th>
<th>建立時間</th>
<th>APP版本</th>
<th>versioncode</th>
<th>包體大小</th>
<th>詳情</th>
</tr>
</thead>
<tbody>
<!--這裡寫for開頭-->
<!--{% for url in context["urls"] -%}-->
<tr>
<td>{{ loop.index + pagination.skip }}</td>
<td class="text-left">{{ url['create_time'] }}</td>
<td class="text-left">{{ url['versionName'] }}</td>
<td class="text-left">{{ url['versionCode'] }}</td>
<td class="text-left">{{ url['apksize'] }}</td>
<td><a href="{{ url['report_path'] }}"><span style="color: #0077FF;">檢視詳情</span></a></td>
</tr>
<!--{% endfor -%}-->
<!--這裡寫for結束-->
</tbody>
</table>
</div>
{{ pagination.links }}
表格要是資料很多,在一個頁面展示就會顯得頁面很長,因此需要對錶格進行分頁切換的處理。就是這個東西
Google了一下發現flask有相應的模組,就直接哪來用就是了。Flask-paginate/
python
from flask_paginate import Pagination, get_page_args
from flask import render_template
def get_users(users,offset=0, per_page=10):
return users[offset: offset + per_page]
@app.route('/')
def pages():
page, per_page, offset = get_page_args(page_parameter="page", per_page_parameter="per_page")
users = [{"create_time": "2020-05-05 19:52:32","size": "39.23"},
{"create_time": "2020-05-06 19:52:32","size": "39.23"},
...
...
]
pagination_users = get_users(users,offset=offset, per_page=per_page)
pagination = Pagination(
page=page,
per_page=per_page,
total=len(users),
record_name="users",
css_framework="bootstrap4"
)
return render_template('index.html', users=pagination_users, per_page=per_page, pagination=pagination)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=9876, debug=True)
index.html
{{ pagination.info }}
{{ pagination.links }}
<table class="table table-striped table-sm table-bordered">
<thead>
<tr>
<th>#</th>
<th>建立時間</th>
<th>包體大小</th>
</tr>
</thead>
<tbody>
{% for url in users -%}
<tr>
<td>{{ loop.index + pagination.skip }}</td>
<td class="text-left">{{ url['create_time'] }}</td>
<td class="text-left">{{ url['size'] }}</td>
</tr>
{% endfor -%}
</tbody>
</table>
{{ pagination.links }}
頁面的UI優化
頁面很多是表格的展示,因為是基於和Bootstrap 的,所以根據Bootstrap-Tables配置文件對模板html進行相關的修改就可以展現較為美觀的頁面了。
例如想把表格展示位黑的 ,加上class="table-dark"
就好了。
相關文章
- Android 手勢檢測Android
- Flutter Android/iOS包大小分析FlutterAndroidiOS
- 網際網路+檢驗檢測智慧化成發展趨勢
- 2020年程式設計趨勢預測程式設計
- Malwarebytes 報告:2019 Mac 威脅檢測呈上升趨勢Mac
- 英敏特:2019年及未來全球包裝行業流行趨勢行業
- 【機器視覺】機器人及視覺檢測系統在螺絲檢測包裝生產線上的應用視覺機器人
- [譯] 怎樣減少 Android 應用包 60% 的大小?Android
- 軟體測試發展趨勢
- 2019年WordPress流行趨勢預測
- 2020年,全球數字化轉型策略及10大趨勢預測
- 小鳥雲:2022年雲端計算趨勢和預測
- 計算機視覺 OpenCV Android | 基本特徵檢測之 霍夫圓檢計算機視覺OpenCVAndroid特徵
- 雲端計算大趨勢
- Android開發 - 掌握ConstraintLayout(十)按比例設定檢視大小AndroidAI
- 【論文閱讀】增量學習近期進展及未來趨勢預測
- 2019中國大資料產業佈局及發展趨勢預測大資料產業
- Unity 報告 | 2020年遊戲市場分析及2021年趨勢預測Unity遊戲
- c++ vector容器——檢測更改容量和大小 示例C++
- 如何使用SAP Analytics Cloud統計C4C系統每天新建的Lead個數和預測趨勢Cloud
- 2024年軟體測試行業趨勢:大模型、智慧化趨勢明顯行業大模型
- 2019 年技術大趨勢預測
- 軟體測試七大趨勢
- RVshare:2021年旅遊趨勢預測
- 漏洞型別及檢測型別
- 網路安全發展的趨勢及措施
- 媒介流量分析及後疫情趨勢展望
- 檢測包相容性的方法
- 蘇州能源計量檢測與能效統計管理系統
- 檢視錶大小
- 2021年平面設計流行趨勢
- 趨勢分析之雲端計算
- UI設計發展最新趨勢UI
- Amazon CTO Werner Vogels:2024年及未來四大技術趨勢預測
- Git無法檢測到檔名大小寫的更改Git
- 統計資料庫中表大小資料庫
- MySQL如何計算統計redo log大小MySql
- IFR:2024年機器人趨勢預測機器人