面向企業定製化需求的移動應用平臺:以Android端為例
移動辦公,是企業協同產品的大勢所趨。但在實際使用過程中,對於同一個產品,可能不同企業對於其定位都不太一樣;另一方面,一個產品也難以完全符合不同企業的需求,此時就需要根據其訴求進行產品定製化。面對企業不同的個性化需求,解決思路往往也是不同的,這要求產品擁有一定的擴充套件能力,例如,最初通過打包配置項+後臺引數配置+應用跳轉的方式來進行自定義功能擴充套件;發展為支援通過內嵌一個擴充套件應用,如完成定製首頁的效果;後續發展為支援擴充套件自定義輕應用、小程式等外掛,如為應用實現某定製協議的NFC卡識別能力;再進一步發展為支援配置嵌入原生程式碼,如配置一個定製的原生首頁或實現一個統計步數的後臺服務等。
然而,擴充套件的靈活性,也會同時給產品帶來更多的不確定性因素,即每個擴充套件應用都有讓程式崩潰的可能性,導致問題的定位變得更困難。例如,公安行業中使用的是定製安全系統的手機,並且面對的是複雜的內網環境,一旦程式出現問題,其故障排查通常需要大費周章。在這種情況下,如果能對系統日誌、網路請求、使用記憶體等各方面進行監控,將有利於準確尋找問題根源。
聆客企業協作平臺(BingoLink,下簡稱“聆客”)是一款面向企業生態系統的雲端協作與開放平臺,可為企業開發者提供一站式的應用開發環境擴充套件和定製標準功能、整合和聯通第三方應用並構建全新業務單元,通過敏捷開發和快速迭代幫助企業實現全面資訊化。本文將主要從技術的角度對聆客Android端開發的擴充套件能力和監控能力進行介紹。
本期大咖 >>

譚智慧
品高雲應用產品研發工程師,擁有多年豐富的移動化產品構建經驗。目前主要負責聆客企業協作平臺(BingoLink)的Android端研發工作,包括:作業系統新特性與相容性的研究、產品體驗和效能的優化、產品功能的持續迭代(如:訊息點對點加密、語音視訊聊天)等。
擴充套件能力
1. 聆客能利用打包平臺的能力達到擴充套件的效果,為企業自由組合不同的個性化版本。首先,需要在程式碼中預留替換引數檔案和資原始檔夾,然後打包平臺並依據不同企業的設定按照預設規則進行引數和資源替換,最後執行編譯命令生成APK檔案。這裡用簡單的流程圖介紹一下打包平臺中對於Android程式的執行流程:

• 介面配置: 聆客的UI支援顏色、圖片、語言包以及介面的自由搭配。在Android的編譯過程中,AAPT對於資源的生成會遵循專案的依賴關係,我們可以利用生成的這個規則對於資源重複的情況做一個優先順序處理,使打包最終效果為:所有的資源項都將優先使用打包配置的資源,其次再使用內建的程式碼。
• 功能配置: 在功能配置方面,聆客使用INI格式進行定義,該格式的優點在於定義簡單,便於打包人員或管理人員進行配置,降低人為造成的出錯概率。引數除了支援自定義以外,還包含當前介面的變數,例如群組名片擴充套件的功能會傳入當前群名片的ID,個人聊天擴充套件的功能選單會傳入當前聊天物件的ID。
2. 通過自定義開發的方式達到擴充套件的效果,結合上述的功能配置,可以在聆客預留的擴充套件點嵌入自定義功能開發。
• 聆客為開發者提供了H5、輕應用、小程式、原生應用多種不同APP型別的接入和擴充套件,除了管理應用的安裝、更新和解除安裝外,還為接入應用提供了便捷的SSO單點登入整合以及大量的原生API呼叫。
• 支援Native的擴充套件,開發者除了可以用內建的API以外,還能對Native層進行自定義擴充套件,比如對輕應用自定義Plugin、對小程式自定義Module和Component,甚至在首頁Tab內嵌一個自定義原生的Fragment。通過APP+Native的擴充套件,開發者可以實現各種不同需求的定製開發。
監控能力
監控介面請求
對主流的HTTP請求庫關鍵函式進行Hook操作,可以對整個APP使用這些庫發起的HTTP請求進行統一監控。這樣做的優點是,除了能監控平臺內發起的請求外,還能監控第三方開發者自己擴充套件的外掛。
該能力主要是通過ASM修改位元組碼的方式實現的,通過自定義Gradle方式修改Dex生成的過程,在這個過程裡找到需要替換的Class類,再找關鍵函式並對其注入監控的程式碼。
小技巧:注入程式碼裡如果需要用到未公開的類,可以用Object代替。
監控全域性日誌
很多Android開發者都知道手機直接通過資料線連線就可以通過ADB檢視Logcat日誌,但在某些遮蔽了USB連線的作業系統,例如公安行業定製的安全系統裡,是無法進行資料線操作的,這時如果程式出現Bug,即便拿到手機也難以排查問題,該如何解決?辦法還是有的,在這個場景下我們就要繞過ADB能力,通過程式直接呼叫系統內建的Logcat命令工具收集日誌,自己實現對日誌的輸出控制檯和日誌的收集。
小技巧:Logcat執行會包括其他APP產生的日誌,而且該命令也沒有過濾引數,不過我們可以發現每行日誌都會包含程序ID這一規律,所以這裡呼叫命令時可以通過使用Grep Pid進行過濾,只保留該應用的日誌。
崩潰日誌收集
有時,出現一些偶現或出現概率低的崩潰會很難定位,加上平臺支援自定義的程式碼擴充套件也會增加崩潰的可能性,而且出現崩潰時上述的全域性日誌監控已經無法生效,因為Logcat的輸出是非同步的,出現崩潰意味著程序將停止執行。不過幸好系統的API為開發者提供了這個時機的擴充套件:通過Thread提供的能力,捕獲所有執行緒中崩潰時出現的異常資訊,平臺可以在崩潰時儲存當前時間、手機型號、堆疊資訊等資訊,只要程式下次啟動時把崩潰日誌再發回來,Bug就原形畢露了。
記憶體異常監控
相信不少開發者都碰到過OutOfMemory的情況,平臺會增加記憶體溢位的可能性,但不僅平臺自身面臨著這種風險,上架的每一個應用都有記憶體洩露的風險,並且長時間開啟應用不關閉還會有記憶體溢位的可能。當這種情況出現時,說明程式裡所有程式碼都已經極為不穩定,每個物件的建立都有引起OutOfMemory崩潰的可能,此時上文提及的崩潰日誌已經基本沒什麼作用。因為堆疊裡顯示的是最後一次申請空間達到上限丟擲的,但這往往不是引起記憶體溢位的罪魁禍首,也許甚至還令人疑惑:這點小操作怎麼可能就引起記憶體溢位呢?
那麼,遇到這種情況該怎麼辦?
面對這種情況,聆客的解決辦法是,基於上面的記錄崩潰時機判斷如果出現OutOfMemory異常,把這一刻的記憶體情況Dump儲存下來,剩下的就是通過工具分析記憶體情況和享受解決Bug的過程了。
介面卡頓監控
偶然出現的操作卡頓現象,這種體驗的優化是比較頭疼的——因為沒有錯誤日誌,讓人有種無從下手的感覺。聆客利用MainLoop類提供的能力,該類提供了一個日誌回撥的方法讓開發者可以清楚知道主執行緒的呼叫過程,程式裡通過把每次呼叫的開始時間和結束時間作比較,耗時大的即為卡頓,把本次主執行緒的堆疊資訊記錄下來,最後就可以根據卡頓時的堆疊資訊來解決Bug了。
總結
綜上,聆客企業協作平臺的擴充套件能力能滿足企業的定製化需求,讓開發者實現更敏捷全能的開發;而監控能力則可以解決因整合應用多或擴充套件多樣性所導致的程式不穩定引發的問題排查困難,有利於開發者解決應用故障。
隨著聆客產品的持續發展,我們將不斷對各種各樣的使用者痛點進行分析與解決,例如安全性方面的應用加固、本地資料安全、應用防篡改和網路防劫持等,還包括效能方面的訊息資料量膨脹的優化、複雜佈局結構的優化、應用啟動速度優化以及節省流量和電量消耗等問題,敬請期待後續的專題技術分享。