2019最新Android中級面試題目匯總解答 [復制鏈接]

2019-9-27 10:11
Newpaper 閱讀:368 評論:0 贊:0
Tag:  面試

Android進階延伸點

1、如何進行單元測試,如何保證App穩定 ?

參考回答:

要測試Android應用程序,通常會創建以下類型自動單元測試

  • 本地測試:只在本地機器JVM上運行,以最小化執行時間,這種單元測試不依賴于Android框架,或者即使有依賴,也很方便使用模擬框架來模擬依賴,以達到隔離Android依賴的目的,模擬框架如Google推薦的Mockito;
  • 檢測測試:真機或模擬器上運行的單元測試,由于需要跑到設備上,比較慢,這些測試可以訪問儀器(Android系統)信息,比如被測應用程序的上下文,一般地,依賴不太方便通過模擬框架模擬時采用這種方式;

注意:單元測試不適合測試復雜的UI交互事件

App的穩定主要決定于整體的系統架構設計,同時也不可忽略代碼編程的細節規范,正所謂“千里之堤,潰于蟻穴”,一旦考慮不周,看似無關緊要的代碼片段可能會帶來整體軟件系統的崩潰,所以上線之前除了自己本地化測試之外還需要進行Monkey壓力測試

少部分面試官可能會延伸,如Gradle自動化測試、機型適配測試等

2.Android中如何查看一個對象的回收情況 ?

參考回答:

  • 首先要了解Java四種引用類型的場景和使用(強引用、軟引用、弱引用、虛引用)
  • 舉個場景例子:SoftReference對象是用來保存軟引用的,但它同時也是一個Java對象,所以當軟引用對象被回收之后,雖然這個SoftReference對象的get方法返回null,但SoftReference對象本身并不是null,而此時這個SoftReference對象已經不再具有存在的價值,需要一個適當的清除機制,避免大量SoftReference對象帶來的內存泄露
  • 因此,Java提供ReferenceQueue來處理引用對象的回收情況。當SoftReference所引用的對象被GC后,JVM會先將softReference對象添加到ReferenceQueue這個隊列中。當我們調用ReferenceQueue的poll()方法,如果這個隊列中不是空隊列,那么將返回并移除前面添加的那個Reference對象。

3.Apk的大小如何壓縮 ?

參考回答:

3.1一個完整APK包含以下目錄(將APK文件拖到Android Studio):

  • META-INF/:包含CERT.SF和CERT.RSA簽名文件以及MANIFEST.MF 清單文件。
  • assets/:包含應用可以使用AssetManager對象檢索的應用資源。
  • res/:包含未編譯到的資源 resources.arsc。
  • lib/:包含特定于處理器軟件層的編譯代碼。該目錄包含了每種平臺的子目錄,像armeabi,armeabi-v7a, arm64-v8a,x86,x86_64,和mips
  • resources.arsc:包含已編譯的資源。該文件包含res/values/ 文件夾所有配置中的XML內容。打包工具提取此XML內容,將其編譯為二進制格式,并將內容歸檔。此內容包括語言字符串和樣式,以及直接包含在*resources.arsc8文件中的內容路徑 ,例如布局文件和圖像。
  • classes.dex:包含以Dalvik / ART虛擬機可理解的DEX文件格式編譯的類。
  • AndroidManifest.xml:包含核心Android清單文件。該文件列出應用程序的名稱,版本,訪問權限和引用的庫文件。該文件使用Android的二進制XML格式。


2019最新Android中級面試題目匯總解答


  • lib、class.dex和res占用了超過90%的空間,所以這三塊是優化Apk大小的重點(實際情況不唯一)

3.2.減少res,壓縮圖文文件

圖片文件壓縮是針對jpg和png格式的圖片。我們通常會放置多套不同分辨率的圖片以適配不同的屏幕,這里可以進行適當的刪減。在實際使用中,只保留一到兩套就足夠了(保留一套的話建議保留xxhdpi,兩套的話就加上hdpi),然后再對剩余的圖片進行壓縮(jpg采用優圖壓縮,png嘗試采用pngquant壓縮)

3.3.減少dex文件大小

  • 添加資源混淆

2019最新Android中級面試題目匯總解答


  • shrinkResources為true表示移除未引用資源,和代碼壓縮協同工作。
  • minifyEnabled為true表示通過ProGuard啟用代碼壓縮,配合proguardFiles的配置對代碼進行混淆并移除未使用的代碼。
  • 代碼混淆在壓縮apk的同時,也提升了安全性。

3.4.減少lib文件大小

  • 由于引用了很多第三方庫,lib文件夾占用的空間通常都很大,特別是有so庫的情況下。很多so庫會同時引入armeabi、armeabi-v7a和x86這幾種類型,這里可以只保留armeabi或armeabi-v7a的其中一個就可以了,實際上微信等主流app都是這么做的。
  • 只需在build.gradle直接配置即可,NDK配置同理


2019最新Android中級面試題目匯總解答


4.如何通過Gradle配置多渠道包?

參考回答:

首先要了解設置多渠道的原因。在安裝包中添加不同的標識,配合自動化埋點,應用在請求網絡的時候攜帶渠道信息,方便后臺做運營統計,比如說統計我們的應用在不同應用市場的下載量等信息

  • 這里以友盟統計為例
  • 首先在manifest.xml文件中設置動態渠道變量:

2019最新Android中級面試題目匯總解答


  • 接著在app目錄下的build.gradle中配置productFlavors,也就是配置打包的渠道:

2019最新Android中級面試題目匯總解答


  • 最后在編輯器下方的Teminal輸出命令行
  1. 執行./gradlew assembleRelease ,將會打出所有渠道的release包;
  2. 執行./gradlew assembleVIVO,將會打出VIVO渠道的release和debug版的包;
  3. 執行./gradlew assembleVIVORelease將生成VIVO的release包。

5.插件化原理分析

參考回答:

插件化是指將 APK 分為宿主和插件的部分。把需要實現的模塊或功能當做一個獨立的提取出來,在 APP 運行時,我們可以動態的載入或者替換插件部分,減少宿主的規模

  • 宿主: 就是當前運行的APP。
  • 插件: 相對于插件化技術來說,就是要加載運行的apk類文件。

而熱修復則是從修復bug的角度出發,強調的是在不需要二次安裝應用的前提下修復已知的bug。能


2019最新Android中級面試題目匯總解答


類加載機制

Android中常用的兩種類加載器,DexClassLoader和PathClassLoader,它們都繼承于BaseDexClassLoader,兩者區別在于PathClassLoader只能加載內部存儲目錄的dex/jar/apk文件。DexClassLoader支持加載指定目錄(不限于內部)的dex/jar/apk文件

插件通信:通過給插件apk生成相應的DexClassLoader便可以訪問其中的類,可分為單DexClassLoader和多DexClassLoader兩種結構。

  • 若使用多ClassLoader機制,主工程引用插件中類需要先通過插件的ClassLoader加載該類再通過反射調用其方法。插件化框架一般會通過統一的入口去管理對各個插件中類的訪問,并且做一定的限制。
  • 若使用單ClassLoader機制,主工程則可以直接通過類名去訪問插件中的類。該方式有個弊端,若兩個不同的插件工程引用了一個庫的不同版本,則程序可能會出錯

資源加載

  • 原理在于通過反射將插件apk的路徑加入AssetManager中并創建Resource對象加載資源,有兩種處理方式:
  • 合并式:addAssetPath時加入所有插件和主工程的路徑;由于AssetManager中加入了所有插件和主工程的路徑,因此生成的Resource可以同時訪問插件和主工程的資源。但是由于主工程和各個插件都是獨立編譯的,生成的資源id會存在相同的情況,在訪問時會產生資源沖突。
  • 獨立式:各個插件只添加自己apk路徑,各個插件的資源是互相隔離的,不過如果想要實現資源的共享,必須拿到對應的Resource對象。

6.組件化原理

參考回答:

引入組件化的原因:項目隨著需求的增加規模變得越來越大,規模的增大導致了各種業務錯中復雜的交織在一起, 每個業務模塊之間,代碼沒有約束,帶來了代碼邊界的模糊,代碼沖突時有發生, 更改一個小問題可能引起一些新的問題, 牽一發而動全身,增加一個新需求,需要熟悉相關的代碼邏輯,增加開發時間

  • 避免重復造輪子,可以節省開發和維護的成本。
  • 可以通過組件和模塊為業務基準合理地安排人力,提高開發效率。
  • 不同的項目可以共用一個組件或模塊,確保整體技術方案的統一性。
  • 為未來插件化共用同一套底層模型做準備。

組件化開發流程就是把一個功能完整的App或模塊拆分成多個子模塊(Module),每個子模塊可以獨立編譯運行,也可以任意組合成另一個新的 App或模塊,每個模塊即不相互依賴但又可以相互交互,但是最終發布的時候是將這些組件合并統一成一個apk,遇到某些特殊情況甚至可以升級或者降級

舉個簡單的模型例子


2019最新Android中級面試題目匯總解答


2019最新Android中級面試題目匯總解答


App是主application,ModuleA和ModuleB是兩個業務模塊(相對獨立,互不影響),Library是基礎模塊,包含所有模塊需要的依賴庫,以及一些工具類:如網絡訪問、時間工具等

注意:提供給各業務模塊的基礎組件,需要根據具體情況拆分成 aar 或者 library,像登錄,基礎網絡層這樣較為穩定的組件,一般直接打包成 aar,減少編譯耗時。而像自定義 View 組件,由于隨著版本迭代會有較多變化,就直接以源碼形式抽離成 Library

7.跨組件通信

參考回答:

7.1.跨組件通信場景:

  • 第一種是組件之間的頁面跳轉 (Activity 到 Activity, Fragment 到 Fragment, Activity 到 Fragment, Fragment 到 Activity) 以及跳轉時的數據傳遞 (基礎數據類型和可序列化的自定義類類型)。
  • 第二種是組件之間的自定義類和自定義方法的調用(組件向外提供服務)。

7.2.跨組件通信方案分析:

  • 第一種組件之間的頁面跳轉實現簡單,跳轉時想傳遞不同類型的數據提供有相應的 API即可
  • 第二種組件之間的自定義類和自定義方法的調用要稍微復雜點,需要 ARouter 配合架構中的 公共服務(CommonService) 實現:
  • 提供服務的業務模塊:

  • 在公共服務(CommonService) 中聲明 Service 接口 (含有需要被調用的自定義方法), 然后在自己的模塊中實現這個 Service 接口, 再通過 ARouter API 暴露實現類。

  • 使用服務的業務模塊:
  • 通過 ARouter 的 API 拿到這個 Service 接口(多態持有, 實際持有實現類), 即可調用 Service 接口中聲明的自定義方法, 這樣就可以達到模塊之間的交互。
  • 此外,可以使用 AndroidEventBus 其獨有的 Tag, 可以在開發時更容易定位發送事件和接受事件的代碼, 如果以組件名來作為 Tag 的前綴進行分組, 也可以更好的統一管理和查看每個組件的事件, 當然也不建議大家過多使用 EventBus。

7.3.如何管理過多的路由表?

  • RouterHub 存在于基礎庫, 可以被看作是所有組件都需要遵守的通訊協議, 里面不僅可以放路由地址常量, 還可以放跨組件傳遞數據時命名的各種 Key 值, 再配以適當注釋, 任何組件開發人員不需要事先溝通只要依賴了這個協議, 就知道了各自該怎樣協同工作, 既提高了效率又降低了出錯風險, 約定的東西自然要比口頭上說強
  • Tips: 如果您覺得把每個路由地址都寫在基礎庫的 RouterHub 中, 太麻煩了, 也可以在每個組件內部建立一個私有 RouterHub, 將不需要跨組件的路由地址放入私有 RouterHub 中管理, 只將需要跨組件的路由地址放入基礎庫的公有 RouterHub 中管理, 如果您不需要集中管理所有路由地址的話, 這也是比較推薦的一種方式。

7.4.ARouter路由原理:

ARouter維護了一個路由表Warehouse,其中保存著全部的模塊跳轉關系,ARouter路由跳轉實際上還是調用了startActivity的跳轉,使用了原生的Framework機制,只是通過apt注解的形式制造出跳轉規則,并人為地攔截跳轉和設置跳轉條件


我來說兩句
您需要登錄后才可以評論 登錄 | 立即注冊
facelist
所有評論(0)
領先的中文移動開發者社區
18620764416
7*24全天服務
意見反饋:[email protected]

掃一掃關注我們

Powered by Discuz! X3.2© 2001-2019 Comsenz Inc.( 粵ICP備15117877號 )

重庆时时彩开奖模拟器