天天看點

蘑菇街Android元件與插件化

随着我街業務的蓬勃發展,産品和營運随時上新功能新活動的需求越來越強烈,經常可以聽到“有個功能我想周x上,行不行”。行麼?當然是不行啦,上新功能得發新版本啊,到時候費時費力打亂開發節奏不說,覆寫率也是個問題。蘇格拉底曾經說過:“現在移動端的主要沖突是産品日益增長的功能需求與平台落後的釋出流程之間的沖突”。

當然,作為一個靠譜的程式猿,我們就是為了滿足産品的需求而存在的(正義臉)。于是在一個陽光明媚的早晨,吃完公司的免費早餐後,我和小強、葉開,決定做一個完善的android動态加載架構。

android動态加載技術在蘑菇街的第一次實踐,還是在14年的時候,使用的就是之前網上廣(tu)為(du)流(si)傳(fang)的方式,這種方式有一個重大缺陷,就是插件内部對資源的通路隻能通過自己定義的方式,包括對layout檔案的inflate等,使用getresouces的方式,分分鐘crash給你看,而且内部實作有些複雜,容易出現莫名其妙的resourcesnotfound錯誤。在一段時間的使用之後,始終無法大面積推廣,原因就是對開發人員來說,寫一個“正常”的子產品和寫一個動态加載子產品,寫法是不一樣的。這件事一直如哏在喉,如果這個架構無法做到對開發業務的同學們透明,那麼就很難推廣開去。如何做到對業務開發者透明呢,最重要的是對于各類系統api的使用,尤其是android四大元件的使用和資源通路,都要遵循系統提供的方式。

抛開上面的東西,從頭開始講述一下動态加載的原理: 

android應用程式的.java檔案在編譯期會通過javac指令編譯成.class檔案,最後再把所有的.class檔案編譯成.dex檔案放在.apk包裡面。那麼動态加載就是在運作時把插件apk直接加載到classloader裡面的技術。

看完上面的原理,不知道你有沒有什麼疑問,反正我是有的。

如何加載插件裡面的.dex檔案。

apk裡面的資源怎麼辦。

上面兩個問題是動态加載架構最重要的兩點,無法動态安裝dex或資源檔案的動态加載架構都是耍流氓。我們在實作這個架構的時候同樣也遇到了這兩個問題。

a cast a錯誤而欲哭無淚的時候,我想你會喜歡上這種方式。 

函數先判斷mstringblocks變量是否為空,如果不為空的話,表示需要被初始化,于是調用makestringblocks函數初始化mstringblocks:

makestringblocks函數的參數也是一個stringblock數組,它表示系統資源,首先它調用getstringblockcount函數得到目前應用所有要加載的資源路徑數量。

然後進入循環,如果屬于系統資源,就直接用傳入參數seed中的對象來指派。

如果是應用自己的資源,就執行個體化一個新的stringblock對象來指派。并在stringblock的構造函數中調用getnativestringblock函數來擷取一個native層的對象指針,這個指針被java層stringblock對象用來調用native函數,最終達到通路資源的目的。

有興趣的同學可以繼續深入native層的源碼,可以看到不管是addassetpath函數還是makestringblocks函數,使用的都是native層同一個數組,這樣,這兩個函數就被關聯了起來。

到這裡,我們已經知道了如何動态添加資源路徑的“秘密”。

解決了以上兩個問題,一個基本滿足要求的動态加載架構就被搭了起來。 

關于如何延遲加載元件的問題,請期待下一期的 那些年蘑菇街android元件與插件化背後的故事 。

原文連結位址http://ju.outofmemory.cn/entry/208685

繼續閱讀