編輯:關於android開發
本文作者:hyxbiao & tony xin
作者Email:[email protected][email protected]
移動APP插件化是平台化產品解決系統限制(65535)、模塊解耦、和多團隊協作的利器。它的最大特點是模塊動態下發,給產品帶來的收益顯而易見,但是,在百度,這套系統給移動端測試技術帶來了新思路
移動端線上問題定位的幾個場景:
場景一: 雲端用戶反饋某功能不可用,RD猜測幾種可能觸發原因,線上收集的客戶端打點日志信息不全,無法完全確認問題。陷入死循環,線上用戶持續暴露問題,線下無法穩定復現,不能及時定位問題。如何破?
場景二:通過客戶端預埋方式打點用戶行為,往往會出現打點不全的問題,而往往線上問題的定位需要這些行為日志為問題定位提供良好的復現步驟。 如何無需編碼,通過技術手段獲取全量用戶與客戶端交互日志?
場景三:線下很多好工具可以SDK化,給線上問題發現和定位帶來大量正向收益,但因為測試能力本身會影響集成app的性能,或開發團隊排期等原因,無法集成,大量線上問題無法充分暴露。如何優美的解決這種問題?
場景四:百度的線上客戶端小流量實驗表明,線上問題實際是一種正態分布的隨機事件,TOP問題,往往只需抽樣很少量用戶即可召回,而不需要影響全量用戶
移動端線下測試的幾個場景:
場景一: 客戶端測試簡單卻又復雜,一個客戶端測試人員的簡單技能樹可能包括這些問題的分析能力: ANR、crash、卡頓、內存洩露、內存、CPU占用、電量分析、啟動速度分析等等一系列的技能。而往往,部分QA人員並不是全棧。並且這些工具的使用本身,就是一個工具大集合。如何讓客戶端測試人員,或非專業測試人員,無需任何背景,只需要點一點就可以具備全部客戶端問題分析能力
場景二:同剛才說的線上問題定位,線下大量的優秀功能,並不能適用於全量用戶,因為他們本身就是傷敵八百,自傷一千的能力。如何在盡量小用戶體驗損耗的前提下,讓問題盡量的全部召回?
基於插件系統,做一個測試插件,把我們所有覺得有用的線下測試能力打進去,同時集成業內知名的好框架,譬如dexposed、 leakcanary等,還有一些系統開放了但是主版使用會影響性能的好東西traceviewer、Choreographer、ActivityLifecycleCallback等。統統打到雲插件中,並通過雲端已經構建好的動態模塊小流量系統下發到特定目標用戶手機中,持續暴露問題
NICE JOB!!
雲插件工作原理:
雲插件本身就是宿主的一個插件而已,真正能夠發揮它的測試能力的是,線下構建的大量測試場景,以及插件本身的動態加載機制,這樣我們的測試場景就可以在線上發揮它的效力了。提到這個就不得不新鍋炒舊飯:
雙親委托機制:java的類加載機制下,子classloader可以向上查找父classloader的加載內容,從而給雲插件動態查找宿主各種類信息提供了先決條件(多進程化的插件系統。。請忽略我把)
dexclassloader:可以加載文件系統的任意JAR(包含dex文件)、zip、apk文件
patchclassloader: 只可以加載data/app/的apk文件,常用於多dex拆分項目
dexfile: 可以加載動態文件,同時提取文件內部的類信息,這個是dexclassloader不具備的
破殼: 雲插件自己的場景需要集成信息上傳類,但在編譯時,不能將對應類編譯進插件包。這樣場景插件在被加載起來以後,就可以回調宿主的日志系統進行信息采集了
經過如上,下圖中的JAR或APK中包裹的場景插件就可以被雲插件動態加載進來,同時對宿主的各種類、本地空間、以及系統中與宿主相關的信息進行讀取、采集。至於是hook、反射、代碼注入、異常捕獲、插樁等這些只是一種手段了
注意: 下面的case,雖然說的是雲插件的問題定位場景,但是不止雲插件,我們後面會以SDK形式開源這部分技術,所以,集成了這個SDK的app也可以這麼干,但是脫離了插件系統,本身的安全性,需要集成的開發者關注自己的安全性。 當然也可以不關注,root的手機上,你的app本身就已經全部暴露給了黑客(BLESS…)
正文: 以流暢度為例,我們看如何非常快速的構建雲調試插件的case吧
流暢度:可以理解為android系統繪制UI的速度,理論上,人眼在1s內接收60幀圖像才會感覺程序流暢。 android系統之初,流暢度一直是人們诟病的目標,直到android 4.1系統的時候,有了注明的project Buffer,並引入了三大元素,VSYNC(垂直同步)、Triple Buffer和Choreographer。其中Choreographer這個東西是我們今天討論的目標。它是整套機制中的協調者,並且所有looper都共用一個Choreographer對象
Choreographer對外開放了一個FrameCallback的東西,在每次系統繪制時,都會通過這個回調doFrame函數,通過這個函數可以計算出在1s內,當前頁面的繪制次數。但是問題來了:
看上圖,含義就是,此貨雖然好,但是建議是你們開發者還是不要用了。。。這如何玩,本來還想拿它上個流暢度監控的。。此時一定會想到,我們有雲調試插件。
構建很簡單,如下,只需要把這段代碼copy到任意android工程,然後打包,注意NutXError只作為編譯依賴即可, 如果已有插件系統, 這段代碼就可以直接被加載並運行了
public class NutFrameMonitor extends BaseCase { private static final String TAG = "NutFrameMonitor"; @Override public void invoke(Context context) { int sdkVersion = 0; try { sdkVersion = Build.VERSION.SDK_INT; } catch (Exception e) { // TODO } if (sdkVersion >= 16) { try { Choreographer.getInstance().postFrameCallback(NutFrameCallback.callback); } catch (Exception e) { // TODO } } } private static class NutFrameCallback implements Choreographer.FrameCallback { static final NutFrameCallback callback = new NutFrameCallback(); private long mLastFrameTimeNanos = 0; private long mFrameIntervalNanos = (long)(500000000) - 1; @Override public void doFrame(long frameTimeNanos) { if (mLastFrameTimeNanos != 0) { final long jitterNanos = frameTimeNanos - mLastFrameTimeNanos; if (jitterNanos > mFrameIntervalNanos) { NutXError error = new NutXError(TAG); error.setDetailMessage("frame Choreographer waste more than 500ms"); error.dump(); } } mLastFrameTimeNanos = frameTimeNanos; Choreographer.getInstance().postFrameCallback(NutFrameCallback.callback); } } }
下面這個截圖是在操作客戶端運行的時候(注意監控case是通過雲插件動態加載的喲),發現的一個流暢度問題。同時也可以看到,在監控到繪制問題後,用戶停留的每個界面也被畫了出來。 然後線下就可以沿著這條trace去復現結果了~
是不是很酷~~~
如上,便結束了對百度在移動端測試的技術探討。然而,其實有很多沒提到,譬如現在已經構建好的自動化case有哪些、這套機制兼容性如何等,再譬如有眼尖的同學也會發現這套系統本身可能就會有兼容性問題,如何做好問題卡控,保證雲調試插件(其實我們叫堅果雲)有效及時回收。 其實,我們有充足的自信在線上嘗試這個東西。在廠子的線上,我們一整套動態模塊小流量系統,雲插件本身其實就被作為了一個動態模塊,當線上出現問題時,我們的雲插件就會發揮它的價值了
更多干貨分享請關注”百度MTC學院“http://mtc.baidu.com/academy/article
ArrayAdapter適配器的用法,模擬QQ發消息界面。,arrayadapter適配器 1 import java.util.ArrayList; 2 3 im
android NDK 教程一(初識JNI--hello world) 前言 android的知識太過龐雜了,自己如果學過了,但過一段時間不用了又會忘記。寫andro
手機安全衛士——閃屏頁相關處理,手機安全衛士根據功能模塊劃分(Android開發推薦此方法) - Activity mo
Android 高級面試題及答案,android試題及答案一 性能優化 1.如何對 Android 應用進行性能分析 android 性能主要之響應速度 和UI刷新速度。