日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

2020 Android 大厂面试-插件化、模块化、组件化,移动开发工程师的岗位职责

發布時間:2023/12/20 Android 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2020 Android 大厂面试-插件化、模块化、组件化,移动开发工程师的岗位职责 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

替換了主工程context中LoadedApk的mResource對象

將新的Resource添加到主工程ActivityThread的mResourceManager中,并且根據Android版本做了不同處理

//第三步:關聯resource和Activity

Activity activity = mBase.newActivity(plugin.getClassLoader(), targetClassName, intent);

activity.setIntent(intent);

//設置Activity的mResources屬性,Activity中訪問資源時都通過mResources

ReflectUtil.setField(ContextThemeWrapper.class, activity, “mResources”, plugin.getResources());

資源沖突

資源id是由8位16進制數表示,表示為0xPPTTNNNN, 由三部分組成:PackageId+TypeId+EntryId

修改aapt源碼,編譯期修改PP段。

修改resources.arsc文件,該文件列出了資源id到具體資源路徑的映射。

blog.csdn.net/jiangwei091…

// Main.cpp

result = handleCommand(&bundle);

case kCommandPackage: return doPackage(bundle);

// Command.cpp

int doPackage(Bundle* bundle) {

if (bundle->getResourceSourceDirs().size() || bundle->getAndroidManifestFile()) {

err = buildResources(bundle, assets, builder);

if (err != 0) {

goto bail;

}

}

}

Resource.cpp

buildResources

ResourceTable.cpp

switch(mPackageType) {

case App:

case AppFeature:

packageId = 0x7f;

break;

case System:

packageId = 0x01;

break;

case SharedLibrary:

packageId = 0x00;

break;

}

首先找到入口類:Main.cpp:main函數,解析參數,然后調用handleCommand函數處理參數對應的邏輯,我們看到了有一個函數doPackage。

然后就搜索到了Command.cpp:在他內部的doPackage函數中進行編譯工具的一個函數:buildResources函數,在全局搜索,發現了Resource.cpp:發現這里就是處理編譯工作,構建ResourceTable的邏輯,在ResourceTable.cpp中,也是獲取PackageId的地方,下面我們就來看看如何修改呢?

其實最好的方法是,能夠修改aapt源碼,添加一個參數,把我們想要編譯的PackageId作為輸入值,傳進來最好了,那就是Bundle類型,他是從Main.cpp中的main函數傳遞到了最后的buildResources函數中,那么我們就可以把這個參數用Bundle進行攜帶。

juejin.im/entry/5c008… www.jianshu.com/p/8d691b6bf…

————————————————————————————————————————————————

cloud.tencent.com/developer/a…

在整個過程中,需要修改到R文件、resources.arsc和二進制的xml文件

四大組件支持

ProxyActivity代理

代理方式的關鍵總結起來有下面兩點:

ProxyActivity中需要重寫getResouces,getAssets,getClassLoader方法返回插件的相應對象。生命周期函數以及和用戶交互相關函數,如onResume,onStop,onBackPressedon,KeyUponWindow,FocusChanged等需要轉發給插件。

PluginActivity中所有調用context的相關的方法,如setContentView,getLayoutInflater,getSystemService等都需要調用ProxyActivity的相應方法。

該方式有幾個明顯缺點:

插件中的Activity必須繼承PluginActivity,開發侵入性強。

如果想支持Activity的singleTask,singleInstance等launchMode時,需要自己管理Activity棧,實現起來很繁瑣。

插件中需要小心處理Context,容易出錯。

如果想把之前的模塊改造成插件需要很多額外的工作。

復制代碼

預埋StubActivity,hook系統啟動Activity的過程

VirtualAPK通過替換了系統的Instrumentation,hook了Activity的啟動和創建,省去了手動管理插件Activity生命周期的繁瑣,讓插件Activity像正常的Activity一樣被系統管理,并且插件Activity在開發時和常規一樣,即能獨立運行又能作為插件被主工程調用。

其他插件框架在處理Activity時思想大都差不多,無非是這兩種方式之一或者兩者的結合。在hook時,不同的框架可能會選擇不同的hook點。如360的RePlugin框架選擇hook了系統的ClassLoader,即構造Activity2的ClassLoader,在判斷出待啟動的Activity是插件中的時,會調用插件的ClassLoader構造相應對象。另外RePlugin為了系統穩定性,選擇了盡量少的hook,因此它并沒有選擇hook系統的startActivity方法來替換intent,而是通過重寫Activity的startActivity,因此其插件Activity是需要繼承一個類似PluginActivity的基類的。不過RePlugin提供了一個Gradle插件將插件中的Activity的基類換成了PluginActivity,用戶在開發插件Activity時也是沒有感知的。

www.jianshu.com/p/ac96420fc…

Service插件化總結

初始化時通過ActivityManagerProxy Hook住了IActivityManager。

服務啟動時通過ActivityManagerProxy攔截,判斷是否為遠程服務,如果為遠程服務,啟動RemoteService,如果為同進程服務則啟動LocalService。

如果為LocalService,則通過DexClassLoader加載目標Service,然后反射調用attach方法綁定Context,然后執行Service的onCreate、onStartCommand方法

如果為RemoteService,則先加載插件的遠程Service,后續跟LocalService一致。

3.模塊化實現(好處,原因)


www.cnblogs.com/Jackie-zhan…

1、模塊間解耦,復用。

(原因:對業務進行模塊化拆分后,為了使各業務模塊間解耦,因此各個都是獨立的模塊,它們之間是沒有依賴關系。

每個模塊負責的功能不同,業務邏輯不同,模塊間業務解耦。模塊功能比較單一,可在多個項目中使用。)

2、可單獨編譯某個模塊,提升開發效率。

(原因:每個模塊實際上也是一個完整的項目,可以進行單獨編譯,調試)

3、可以多團隊并行開發,測試。

原因:每個團隊負責不同的模塊,提升開發,測試效率。

組件化與模塊化

組件化是指以重用化為目的,將一個系統拆分為一個個單獨的組件

避免重復造輪子,節省開發維護成本;

降低項目復雜性,提升開發效率;

多個團隊公用同一個組件,在一定層度上確保了技術方案的統一性。

模塊化業務分層:由下到上

基礎組件層:

底層使用的庫和封裝的一些工具庫(libs),比如okhttp,rxjava,rxandroid,glide等

業務組件層:

與業務相關,封裝第三方sdk,比如封裝后的支付,即時通行等

業務模塊層:

按照業務劃分模塊,比如說IM模塊,資訊模塊等

Library Module開發問題

在把代碼抽取到各個單獨的Library Module中,會遇到各種問題。

最常見的就是R文件問題,Android開發中,各個資源文件都是放在res目錄中,在編譯過程中,會生成R.java文件。

R文件中包含有各個資源文件對應的id,這個id是靜態常量,但是在Library Module中,這個id不是靜態常量,那么在開發時候就要避開這樣的問題。

舉個常見的例子,同一個方法處理多個view的點擊事件,有時候會使用switch(view.getId())這樣的方式,

然后用case R.id.btnLogin這樣進行判斷,這時候就會出現問題,因為id不是經常常量,那么這種方式就用不了。

4.熱修復、插件化


www.jianshu.com/p/704cac3eb…

宿主: 就是當前運行的APP

插件: 相對于插件化技術來說,就是要加載運行的apk類文件

補丁: 相對于熱修復技術來說,就是要加載運行的.patch,.dex,*.apk等一系列包含dex修復內容的文件。

QQ 空間超級補丁方案

Tinker

HotFix

當然就熱修復的實現,各個大廠還有各自的實現,比如餓了嗎的Amigo,美團的Robust,實現及優缺點各有差異,但總的來說就是兩大類

ClassLoader 加載方案

Native層替換方案

或者是參考Android Studio Instant Run 的思路實現代碼整體的增量更新。但這樣勢必會帶來性能的影響。

Sophix

www.jianshu.com/p/4d30ce3e5…

底層替換方案

原理:在已經加載的類中直接替換掉原有方法,是在原有類的結構基礎上進行修改的。在hook方法入口ArtMethod時,通過構造一個新的ArtMethod實現替換方法入口的跳轉。

應用:能即時生效,Andfix采用此方案。

缺點:底層替換穩定性不好,適用范圍存在限制,通過改造代碼繞過限制既不優雅也不方便,并且還沒提供資源及so的修復。

類加載方案

原理:讓app重新啟動后讓ClassLoader去加載新的類。如果不重啟,原來的類還在虛擬機中無法重復加載。

優點:修復范圍廣,限制少。

應用:騰訊系包括QQ空間,手QFix,Tinker采用此方案。

QQ空間會侵入打包流程。

QFix需要獲取底層虛擬機的函數,不穩定。

Tinker是完整的全量dex加載。

Tinker與Sophix方案不同之處

Tinker采用dex merge生成全量DEX方案。反編譯為smali,然后新apk跟基線apk進行差異對比,最后得到補丁包。

Dalvik下Sophix和Tinker相同,在Art下,Sophix不需要做dex merge,因為Art下本質上虛擬機已經支持多dex的加載,要做的僅僅是把補丁dex作為主dex(classes.dex)加載而已:

將補丁dex命名為classes.dex,原apk中的dex依次命名為classes(2, 3, 4…).dex就好了,然后一起打包為一個壓縮文件。然后DexFile.loadDex得到DexFile對象,最后把該DexFile對象整個替換舊的dexElements數組就好了。

資源修復方案

基本參考InstantRun的實現:構造一個包含所有新資源的新的AssetManager。并在所有之前引用到原來的AssetManager通過反射替換掉。

Sophix不修改AssetManager的引用,構造的補丁包中只包含有新增或有修改變動的資源,在原AssetManager中addAssetPath這個包就可以了。資源包不需要在運行時合成完整包。

so庫修復方案

本質是對native方法的修復和替換。類似類修復反射注入方式,將補丁so庫的路徑插入到nativeLibraryDirectories數據最前面。

Method Hook

www.jianshu.com/p/7dcb32f8a… pqpo.me/2017/07/07/…

5.項目組件化的理解


juejin.im/post/5b5f17…

總結

組件化相較于單一工程,在組件模式下可以提高編譯速度,方便單元測試,提高開發效率。

開發人員分工更加明確,基本上做到互不干擾。

業務組件的架構也可以自由選擇,不影響同伴之間的協作。

降低維護成本,代碼結構更加清晰。

6.描述清點擊 Android Studio 的 build 按鈕后發生了什么


blog.csdn.net/u011026779/… blog.csdn.net/github_3713…

apply plugin : ‘com.android.application’

apply plugin : ‘com.android.library’

編譯五階段

1.準備依賴包 Preparation of dependecies

2.合并資源并處理清單 Merging resources and proccesssing Manifest

3.編譯 Compiling

4.后期處理 Postprocessing

5.包裝和出版 Packaging and publishing

簡單構建流程:

1. Android編譯器(5.0之前是Dalvik,之后是ART)將項目的源代碼(包括一些第三方庫、jar包和aar包)轉換成DEX文件,將其他資源轉換成已編譯資源。

2. APK打包器將DEX文件和已編譯資源在使用秘鑰簽署后打包。

3. 在生成最終 APK 之前,打包器會使用zipalign 等工具對應用進行優化,減少其在設備上運行時的內存占用。

構建流程結束后獲得測試或發布用的apk。

復制代碼

圖中的矩形表示用到或者生成的文件,橢圓表示工具。

1. 通過aapt打包res資源文件,生成R.java、resources.arsc和res文件

2. 處理.aidl文件,生成對應的Java接口文件

3. 通過Java Compiler編譯R.java、Java接口文件、Java源文件,生成.class文件

4. 通過dex命令,將.class文件和第三方庫中的.class文件處理生成classes.dex

5. 通過apkbuilder工具,將aapt生成的resources.arsc和res文件、assets文件和classes.dex一起打包生成apk

6. 通過Jarsigner工具,對上面的apk進行debug或release簽名

7. 通過zipalign工具,將簽名后的apk進行對齊處理。

這樣就得到了一個可以安裝運行的Android程序。

復制代碼

7.徹底搞懂Gradle、Gradle Wrapper與Android Plugin for Gradle的區別和聯系


zhuanlan.zhihu.com/p/32714369 blog.csdn.net/LVXIANGAN/a…

Offline work時可能出現"No cached version of com.android.tools.build:gradle:xxx available for offline mode"問題

Gradle: gradle-wrapper.properties中的distributionUrl=https/😕/services.gradle.org/distributions/gradle-2.10-all.zip

Gradle插件:build.gradle中依賴的classpath ‘com.android.tools.build:gradle:2.1.2’

Gradle:

一個構建系統,構建項目的工具,用來編譯Android app,能夠簡化你的編譯、打包、測試過程。

Gradle是一個基于Apache Ant和Apache Maven概念的項目自動化建構工具。它使用一種基于Groovy的特定領域語言來聲明項目設置,而不是傳統的XML。當前其支持的語言限于Java、Groovy和Scala

最后

我見過很多技術leader在面試的時候,遇到處于迷茫期的大齡程序員,比面試官年齡都大。這些人有一些共同特征:可能工作了7、8年,還是每天重復給業務部門寫代碼,工作內容的重復性比較高,沒有什么技術含量的工作。問到這些人的職業規劃時,他們也沒有太多想法。

其實30歲到40歲是一個人職業發展的黃金階段,一定要在業務范圍內的擴張,技術廣度和深度提升上有自己的計劃,才有助于在職業發展上有持續的發展路徑,而不至于停滯不前。

不斷奔跑,你就知道學習的意義所在!

以上進階BATJ大廠學習資料可以免費分享給大家,需要完整版的朋友,【點這里可以看到全部內容】。

總結

以上是生活随笔為你收集整理的2020 Android 大厂面试-插件化、模块化、组件化,移动开发工程师的岗位职责的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。