android開發(fā)2

三、常用開發(fā)技術(shù)面試題

Android性能優(yōu)化:

1、布局優(yōu)化

? ? 布局優(yōu)化的思想就是減少布局文件的層級,這個道理很淺顯,布局文件少了,繪制事件就少了,響應(yīng)速度就會提升

? ? 1、1使用一些低耗的控件比如ViewGroup,LinearLayout,懶加載控件ViewStub等

2、繪制優(yōu)化

? ? 繪制優(yōu)化主要是指避免在view的onDraw方法中進(jìn)行大量的操作,它會直接影響界面的響應(yīng)速度

? ? 2、1避免在onDraw方法中進(jìn)行局部變量,應(yīng)為onDraw方法會頻繁創(chuàng)建,這樣會產(chǎn)生大量的臨時變量占用內(nèi)存,銷毀 這些臨時變量會頻繁的執(zhí)行g(shù)c,降低效率

? ? 2、2onDraw方法中不要執(zhí)行耗時操作,它運(yùn)行在主線程,容易造成anr

3、內(nèi)存泄漏優(yōu)化

? ? 具體詳見下面

4、響應(yīng)速度和ANR優(yōu)化

? ? 核心思想是避免在主線程中進(jìn)行耗時操作,這些主線程一般指服務(wù)、廣播onReceiver,主線程等,如果在activity中左過多操作會引起黑白屏和ANR錯誤,

5、ListView優(yōu)化

? ? 復(fù)用convertView、使convertView綁定viewHolder、翻頁加載、使用緩存

6、線程優(yōu)化

? ? 使用線程池。

Android內(nèi)存泄漏相關(guān):

什么是內(nèi)存泄漏:內(nèi)存泄漏就是應(yīng)用程序申請內(nèi)存,申請內(nèi)存的對象不會被釋放,這樣就會導(dǎo)致內(nèi)存泄漏

內(nèi)存泄漏帶來哪些問題:

1、應(yīng)用可用內(nèi)存減少,增加內(nèi)存壓力

2、會頻繁的出發(fā)GC, 降低應(yīng)用的性能

3、當(dāng)沒有可用內(nèi)存時,會導(dǎo)致OOM程序異常

內(nèi)存泄漏中的常見場景&解決方案

1、單例引起的內(nèi)存泄漏

? ? 單例的生命周期跟隨整個應(yīng)用程序,對于單例我們有這幾種優(yōu)化

? ? 1、1懶加載,用到的時候在進(jìn)行初始化

? ? 1、2避免在單例中引用activity的context上下文,這樣被引用的activity就不會釋放

? ? 1、3盡量少使用單例

2、靜態(tài)變量引起的內(nèi)存泄漏

? ? 在開發(fā)過程中,盡量不要對上下文,自定義類,自定義屬性進(jìn)行statice修飾,常量除外,因?yàn)橐坏╈o態(tài)變量應(yīng)用了上下文,那么當(dāng)前上下文坐在的activity就不會被釋放,導(dǎo)致內(nèi)存泄漏

3、屬性動畫引起的內(nèi)存泄漏

android3.0以后google提供屬性動畫,屬性動畫中有一個類循環(huán)播放的動畫,如果頁面離開,動畫不關(guān)閉就會導(dǎo)致內(nèi)存泄漏

4、handler以及內(nèi)部類造成的內(nèi)存泄漏

Handler主要用于主線程跟子線程進(jìn)行通信,Handler允許發(fā)送延遲消息,如果發(fā)送延遲消息期間關(guān)閉了activity就會造成內(nèi)訓(xùn)泄露

非靜態(tài)內(nèi)部類會持有外部類的引用,如果在耗時操作期間關(guān)閉的頁面也會導(dǎo)致內(nèi)存泄漏

解決辦法:

定義靜態(tài)內(nèi)部類、對外引用弱引用

ondestory中執(zhí)行handler.removeCallbackAndMessage(null)

內(nèi)訓(xùn)泄露工具排查

1、Android profile 是 Android Studio 提供的?代碼掃描分析工具,包括CPU真用、網(wǎng)絡(luò)請求、內(nèi)存占用等情況查看,它可以幫助我們發(fā)現(xiàn)代碼機(jī)構(gòu) / 質(zhì)量問題,

2、LeakCanary 是 Square 公司開源的「Android 和 Java 的內(nèi)存泄漏檢測庫」,Square 出品,必屬精品,功能很強(qiáng)

指紋解鎖開發(fā)

1、添加權(quán)限use_fingerprint

2、獲取當(dāng)前指紋上下文對象FingerprintManager

FingerprintManager fingerprint2 = (FingerprintManager) getSystemService(Context.FINGERPRINT_SERVICE);

3、執(zhí)行三個方法

fingerprint.isHardwareDetected(); // 判斷設(shè)備是否支持指紋解鎖

?fingerprint.hasEnrolledFingerprints(); //判斷設(shè)備是否以保存過指紋信息,至少需要保存過一個

對驗(yàn)證結(jié)果進(jìn)行處理: onAuthenticationError、 onAuthenticationSuccess、 onAuthenticationFailed

淺談安卓apk加固原理和實(shí)現(xiàn)

apk加固

請例舉Android中常用布局類型,并簡述其用法以及排版效率

Android中常用布局分為傳統(tǒng)布局新型布局

傳統(tǒng)布局(編寫XML代碼、代碼生成):

? ? ? ? ?框架布局(FrameLayout)

? ? ? ? ?線性布局(LinearLayout)

? ? ? ? ?絕對布局(AbsoluteLayout)

? ? ? ? ?相對布局(RelativeLayout)

? ? ? ? ?表格布局(TableLayout)

新型布局(可視化拖拽控件、編寫XML代碼、代碼生成):

? ? ? ? ?約束布局(ConstrainLayout)

對于嵌套多層View而言,其排版效率:LinearLayout = FrameLayout >> RelativeLayout

使用過什么圖片加載庫?Glide的源碼設(shè)計(jì)哪里很微妙?

參考回答:

圖片加載庫:Fresco、Glide、Picasso

Glide的設(shè)計(jì)微妙在于:

Glide的生命周期綁定:可以控制圖片的加載狀態(tài)與當(dāng)前頁面的生命周期同步,使整個加載過程隨著頁面的狀態(tài)而啟動/恢復(fù),停止,銷毀

Glide的緩存設(shè)計(jì):通過(三級緩存,Lru算法,Bitmap復(fù)用)對Resource進(jìn)行緩存設(shè)計(jì)

Glide的完整加載過程:采用Engine引擎類暴露了一系列方法供Request操作

如何對APK瘦身?

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

META-INF/:包含CERT.SFCERT.RSA簽名文件以及MANIFEST.MF清單文件。

assets/:包含應(yīng)用可以使用AssetManager對象檢索的應(yīng)用資源。

res/:包含未編譯到的資源 resources.arsc。

lib/:第三方庫

classes.dex:包含以Dalvik / ART虛擬機(jī)可理解的DEX文件格式編譯的類。

AndroidManifest.xml:包含核心Android清單文件。該文件列出應(yīng)用程序的名稱,版本,訪問權(quán)限和引用的庫文件。

lib、class.dex和res占用了超過90%的空間,所以這三塊是優(yōu)化Apk大小的重點(diǎn)

減少res,壓縮圖文文件

我們通常會放置多套不同分辨率的圖片以適配不同的屏幕,在實(shí)際使用中,只保留一到兩套就足夠了(xxhdpi),可以使用webp格式圖片等

減少dex文件大小

添加資源混淆,代碼混淆在壓縮apk的同時,也提升了安全性。

減少lib文件大小

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

簡述多渠道打包及原理和常用操作?

根據(jù)不同的包標(biāo)識,配合自動化埋點(diǎn),應(yīng)用在請求網(wǎng)絡(luò)的時候攜帶渠道信息,方便后臺做運(yùn)營統(tǒng)計(jì),比如說統(tǒng)計(jì)我們的應(yīng)用在不同應(yīng)用市場的下載量等信息

這里以友盟統(tǒng)計(jì)為例

1、首先在manifest.xml文件中設(shè)置動態(tài)渠道變量:

<meta-data android:name="UMENG_CHANNEL" android:value="${UMENG_CHANNEL_VALUE}"></meta-data>

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

3、最后Build菜單下執(zhí)行signed APK,輸入key路徑和密碼,選擇release,選擇渠道進(jìn)行打包即可

圖片優(yōu)化,以及圖片加載框架的使用,如Picasso、 Fresco、Glide等?

1)盡量使用小的圖片,對圖片進(jìn)行壓縮,bitmapfactory.options圖片配置類,insimplesize進(jìn)行縮放,設(shè)置圖片的編碼方式;對圖片使用軟引用,內(nèi)存不夠時即時釋圖片內(nèi)存;對圖片的復(fù)用,三級緩存的使用;

即時回收不再使用的bitmap對象;

2)Picasso,不支持gif,緩存的是Argb8888的原圖,占用內(nèi)存較大,圖片的框架使用了OkHttp緩存機(jī)制,使用Http協(xié)議緩存,也是異步加載.

3)Fresco,框架是FaceBook公司推出的,適合批量加載圖片,底層是通過三級緩存(2級內(nèi)存,1級磁盤)

加載成功后自動替換成目標(biāo)圖片

4)glide,Google公司14年推出來的,可以加載GIF圖,也可以根據(jù)指定圖片清晰度,底層的原理:為Bitmap維護(hù)一個對象池,對象池的目的是通過減少對象的分配,以重用來提高性能.對象池也可以幫助提高滾動的性能。API簡潔易調(diào)用

如何對 Android 應(yīng)用進(jìn)行性能分析

如果不考慮使用其他第三方性能分析工具的話,我們可以直接使用 ddms 中的工具,其實(shí) ddms 工具已經(jīng)非常的強(qiáng)大了。ddms 中有 traceview、heap、allocation tracker 等工具都可以幫助我們分析應(yīng)用的方法執(zhí)行時間效率和內(nèi)存使用情況。

Traceview 是 Android 平臺特有的數(shù)據(jù)采集和分析工具,它主要用于分析 Android 中應(yīng)用程序的 hotspot(瓶頸)。Traceview 本身只是一個數(shù)據(jù)分析工具,而數(shù)據(jù)的采集則需要使用 AndroidSDK 中的 Debug 類或者利用 DDMS 工具。

heap 工具可以幫助我們檢查代碼中是否存在會造成內(nèi)存泄漏的地方。

allocation tracker 是內(nèi)存分配跟蹤工具

自定義View相關(guān)方法

自定義控件的實(shí)現(xiàn)有三種方式,分別是:組合控件、自繪控件和繼承控件。

1、自定義屬性的聲明和獲取

????????分析需要的自定義屬性

????????在res/values/attrs.xml定義聲明

????????在layout文件中進(jìn)行使用

????????在View的構(gòu)造方法中進(jìn)行獲取

2、測量onMeasure、布局onLayout(ViewGroup)、繪制onDraw

3、onTouchEvent、onInterceptTouchEvent(ViewGroup)

4、狀態(tài)的恢復(fù)與保存

優(yōu)化自定義 View

1、對于頻繁調(diào)用的方法,盡量減少不必要的代碼,比如onDraw方法,它運(yùn)行在UI上,使用不當(dāng)不僅會導(dǎo)致內(nèi)存緊張,還會導(dǎo)致UI卡頓

2、layout:我們都知道調(diào)用requestLayout,他會遍歷整個view層級來計(jì)算當(dāng)前view得大小,因此要較少調(diào)用次數(shù)

3、UI盡量扁平化,不要過于復(fù)雜,如果很復(fù)雜建議使用viewGroup

TCP的3次握手和四次揮手

三次握手是指,客戶端與服務(wù)端需要發(fā)送三次包

1、客戶端向服務(wù)端發(fā)送請求連接, 等待回應(yīng)

2、服務(wù)器接收到請求,并向客戶端發(fā)送相應(yīng)

3、客戶端得到服務(wù)器發(fā)送請求的相應(yīng)后,向服務(wù)器發(fā)送數(shù)據(jù)包

TCP與UDP的區(qū)別?

TCP UDP

是否連接 面向連接 面向非連接

傳輸可靠性 可靠 不可靠

應(yīng)用場合 傳輸大量數(shù)據(jù) 少量數(shù)據(jù)

速度 慢 快

HTTP與HTTPS的區(qū)別以及如何實(shí)現(xiàn)安全性

HTTP 是明文連接不安全,HTTPS是加密連接,ssl加密安全

HTTPS需要申請證書,http不需要

HTTP 速度快,HTTPS速度慢

請解釋安卓為啥要加簽名機(jī)制??談?wù)勀銓Π沧亢灻睦斫?

Android的簽名機(jī)制包含有消息摘要、數(shù)字簽名數(shù)字證書

消息摘要:在消息數(shù)據(jù)上,執(zhí)行一個單向的 Hash 函數(shù),生成一個固定長度的Hash值

數(shù)字簽名:一種以電子形式存儲消息簽名的方法,一個完整的數(shù)字簽名方案應(yīng)該由兩部分組成:簽名算法和驗(yàn)證算法

數(shù)字證書:一個經(jīng)證書授權(quán)(Certificate Authentication)中心數(shù)字簽名的包含公鑰擁有者信息以及公鑰的文件

(三)數(shù)據(jù)庫

sqlite升級,增加字段的語句

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)

升級一定要newVersion+1,否則不會走onUpgrade方法

增加字段:alter table [表名] add column [字段id] [字段類型]

(四)算法

GC算法(各種算法的優(yōu)缺點(diǎn)以及應(yīng)用場景)

1、引用計(jì)數(shù)法

? ? ? ? 每個對象頭部都會有一個counter,對象被引用一次計(jì)數(shù)器就會+1,不會引用就會-1,為0就會被gc等待回收

? ? ? ? 由循環(huán)引用的問題

2、可達(dá)性算法

? ? ? ? 以當(dāng)前節(jié)點(diǎn)為根節(jié)點(diǎn),向上搜索,如果找到父節(jié)點(diǎn)則被引用,沒有就沒有被引用,解決循環(huán)引用問題

一張Bitmap所占內(nèi)存以及內(nèi)存占用的計(jì)算

getByteCount()

public final int getByteCount() { return getRowBytes() * getHeight();}?

(五)插件化、模塊化、組件化、熱修復(fù)、增量更新、Gradle

對熱修復(fù)(熱更新)和插件化的理解

熱更新流程:

1、線上檢測驗(yàn)證的bug

2、拉出bugfix分支并在分支上修復(fù)問題

3、jenkins構(gòu)建和補(bǔ)丁生成

4、app通過推送或者拉取的方法獲取補(bǔ)丁

5、將bugfix代碼同步到主干目錄上

熱更新原理:

1、Android類加載機(jī)制

? ? ? ? PathClassLoader:主要加載系統(tǒng)的類

? ? ? ? DexClassLoader:主要加載Dex文件,jar、apk包等

2、熱修復(fù)機(jī)制

? ? ? ? 1、dexElements:放新文件和舊文件的集合

? ? ? ? 2、ClassLoader會遍歷dexElements數(shù)組

描述:在ClassLoader中創(chuàng)建一個dexElements文件的數(shù)組,根據(jù)線上的類文件,把線上的類文件打包成dex文件放到dexElements數(shù)組的最前面,ClassLoader會優(yōu)先加載最前面的dex文件,這樣就完成了新文件替換舊文件的機(jī)制

插件化原理分析

1、插件化的來源:

? ? ? ? 我們都知道app在開發(fā)維護(hù)過程中隨著版本迭代,代碼會越來越多,功能也會越來越多

? ? ? ? 銀行業(yè)務(wù)眾多,一個團(tuán)隊(duì)開發(fā)至少十幾個人,每個人都有負(fù)責(zé)一個模塊的時候,如果某個模塊更新,那么整個app? ?就會隨著更新,浪費(fèi)時間、人力。因此面對這種情況,插件化能很好的解決問提

插件化是指將 APK 分為宿主插件的部分。把需要實(shí)現(xiàn)的模塊或功能當(dāng)做一個獨(dú)立的提取出來,在 APP 運(yùn)行時,我們可以動態(tài)的載入或者替換插件部分,減少宿主的規(guī)模

宿主: 就是當(dāng)前運(yùn)行的APP。

插件: 相對于插件化技術(shù)來說,就是要加載運(yùn)行的apk類文件。

2、插件化所要解決的問題:

? ? ? ? 2.1動態(tài)加載apk:

? ? ? ? ? ? PathClassLoader:主要加載系統(tǒng)類文件

????????????DexClassLoader主要動態(tài)加載dex文件常用于熱修復(fù)機(jī)制

所謂的動態(tài)加載apk主要是通過DexClassloader加載dex類文件來實(shí)現(xiàn),并通過反射來動態(tài)的獲取dex文件的方法、屬性和類文件信息

? ? ? ? 2.2資源加載:

? ? ? ? 一個apk訪問另一個apk資源的時候,只能通過反射來訪問被訪問apk資源,通過assestManager

? ? ? ? 2.3代碼加載:

? ? ? ? 通過反射生命周期來實(shí)現(xiàn)

模塊化實(shí)現(xiàn)(好處,原因)

定義:模塊化是一種處理復(fù)雜系統(tǒng)分解為更好的可管理模塊的方式

每個團(tuán)隊(duì)負(fù)責(zé)不同的模塊,提升開發(fā),測試效率

每個模塊實(shí)際上也是一個完整的項(xiàng)目,可以進(jìn)行單獨(dú)編譯,調(diào)試

模塊功能比較單一,可在多個項(xiàng)目中使用?

項(xiàng)目組件化的理解

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

避免重復(fù)造輪子,可以節(jié)省開發(fā)和維護(hù)的成本。

可以通過組件和模塊為業(yè)務(wù)基準(zhǔn)合理地安排人力,提高開發(fā)效率。

不同的項(xiàng)目可以共用一個組件或模塊,確保整體技術(shù)方案的統(tǒng)一性。

為未來插件化共用同一套底層模型做準(zhǔn)備。

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

舉個簡單的模型例子

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

描述清點(diǎn)擊 Android Studio 的 build 按鈕后發(fā)生了什么(apk打包流程)

流程概述:

1、打包資源文件,生成R.java文件

2、處理aidl文件,生成相應(yīng)java 文件

3、編譯工程源代碼,生成相應(yīng)class 文件

4、轉(zhuǎn)換所有class文件,生成classes.dex文件

5、打包生成apk6、對apk文件進(jìn)行簽名7、對簽名后的apk文件進(jìn)行對其處理

在 AndroidStudio 工程點(diǎn)擊 Run 按鈕, 實(shí)際上做了什么操作呢?

1、檢查項(xiàng)目和讀取基本配置

2、Gradle Build

3、Apk Install & LaunchActivity

(六)架構(gòu)設(shè)計(jì)和設(shè)計(jì)模式

談?wù)勀銓ndroid設(shè)計(jì)模式的理解

什么是設(shè)計(jì)模式

????????設(shè)計(jì)模式是一種解決方案,它代表了實(shí)現(xiàn)代碼的最佳實(shí)踐

設(shè)計(jì)模式的作用

? ??????? 設(shè)計(jì)模式就是用來解決軟件設(shè)計(jì)中應(yīng)對變化,提高軟件復(fù)用性。設(shè)計(jì)模式使軟件更加可維護(hù)、可拓展、更加穩(wěn)定、可復(fù)用性強(qiáng)

常見的設(shè)計(jì)模式

? ? ? ? 單例、觀察者、工廠、狀態(tài)機(jī)模式

MVC MVP MVVM原理和區(qū)別

用到的一些開源框架,介紹一個看過源碼的,內(nèi)部實(shí)現(xiàn)過程。

從0設(shè)計(jì)一款A(yù)pp整體架構(gòu),如何去做?

1、需求分析,確定功能

2、根據(jù)功能,確定模塊化開發(fā)或者組件化開發(fā)

3、根據(jù)業(yè)務(wù)模塊確定架構(gòu)MVC、MVP、MVVM

4、根據(jù)架構(gòu)模式進(jìn)行編碼、優(yōu)化

Binder機(jī)制及底層實(shí)現(xiàn)

1、為什么要使用Binder

? ? ? ? android使用linux內(nèi)核,它里面有非常多的進(jìn)程通信機(jī)制

? ? ? ? 性能,手機(jī)注重性能,

? ? ? ? 安全,支持通信雙方進(jìn)行身份校驗(yàn)

2、Binder的通信模型

(七)性能優(yōu)化

如何對Android 應(yīng)用進(jìn)行性能分析以及優(yōu)化?

性能分析工具:traceview、heap、allocation tracker

traceview:數(shù)據(jù)采集和分析工具

heap:工具可以幫助我們檢查代碼中是否存在會造成內(nèi)存泄漏的地方

用IDE如何分析內(nèi)存泄漏?

Android Profiler內(nèi)存分析工具

通過Profiler可以查看CPU、Memory和Network的調(diào)用情況。

Java多線程引發(fā)的性能問題,怎么解決?

java中多線程除了能解決耗時操作,但是線程的開銷是非常占用資源的。

1、線程的生命周期開銷高,線程從創(chuàng)建到銷毀時間不固定

2、線程是一種有線cpu資源,過多的線程會占用更多的cpu資源

3、線程超過jvm內(nèi)存限制會引起OOM問題

解決辦法:

1、使用線程池,更好的利用資源

線程池有核心線程數(shù)、緩沖線程數(shù)、最大線程數(shù),可根據(jù)線程的輕重緩急來合理分配資源

啟動頁白屏及黑屏解決?

首先我們分析一下為什么會有黑白屏問題:

1、啟動app,系統(tǒng)進(jìn)程會創(chuàng)建一個新的進(jìn)程啟動當(dāng)前app,當(dāng)然這個啟動是有時間的。這個時間段界面呈現(xiàn)假死狀態(tài),android為我們解決的辦法是在mainfest配置文件中設(shè)置不同的主題來展示黑屏或者白屏。也就是預(yù)覽窗口

2、 針對這個問題,我的解決方案是,

????可以在drawable文件夾下定義一個啟動xml文件

? ? 添加一個主題style,設(shè)置名字為SplashAppTheme ,給android:windowBackground 指定xml文件

? ? 在清單文件中給啟動頁activity的Theme單獨(dú)設(shè)置我們剛才添加的主題

<style name="SplashAppTheme" parent="android:Theme">

????????<item name="android:windowNoTitle">true</item>

????????<item name="android:windowFullscreen">true</item>

????????<item name="android:windowBackground">@drawable/layer_splash</item>

????</style>

怎么保證應(yīng)用啟動不卡頓?

應(yīng)用卡頓的原因是界面繪制頻繁,主線程做了過多的耗時操作

如何保持應(yīng)用的穩(wěn)定性

1、用戶體驗(yàn)、流暢的運(yùn)行app

2、軟件崩潰,最主要的OOM問題

3、性能分析

RecyclerView和ListView的性能對比

ListView 回收機(jī)制基于RecyclerBin(mActivitysViews、mSpacpViews)

RecyclerView 回收機(jī)制Recycler(mCachesViews、Viewpool)

ListView的優(yōu)化

1、復(fù)用convertView

2、使convertView綁定View Holder

3、翻頁加載

4、使用緩存

Bitmap如何處理大圖,如一張30M的大圖,如何預(yù)防OOM

Bitmap加載一張30M的大圖為了避免引起OOM,需要使用采樣率進(jìn)行展示(根據(jù)屏幕不影響分辨率情況下展示),流程

1、將BitmapFactory.Options的inJustDecodeBounds設(shè)為true并加載圖片

2、從BitmapFactory.Options獲取圖片的outWidth、outHeight

3、根據(jù)采樣率的規(guī)則結(jié)合目標(biāo)View的大小和outWidth和outHeight計(jì)算出采樣率inSampleSize

4、將BitmapFactory.Options的inJustDecodeBounds設(shè)為false重新加載圖片

java中的四種引用的區(qū)別以及使用場景

強(qiáng)應(yīng)用:當(dāng)前對象如果是強(qiáng)引用,它會一直存在內(nèi)存中,生命周期跟隨程序生命周期,寧愿拋出OOM也不會被回收

軟引用:當(dāng)前對象如果是軟引用,內(nèi)存充足時不會被回收,內(nèi)存不足時會優(yōu)先回收

弱引用:不管內(nèi)存充足與否,只要被GC掃描到就會被回收。

虛引用:與弱引用一樣,隨時會被回收?

(八)NDK、jni、Binder、AIDL、進(jìn)程通信有關(guān)

請介紹一下NDK

NDK是Android提供的工具集合,通過NDK,可以更方便的使用JNI訪問本地代碼。具有如下好處:

1、提高代碼的安全性,因?yàn)閟o庫反編譯困難

2、可以很方便的使用目前C/C++開源庫

3、便于平臺間的移植

4、提高程序在某些特定情況下的執(zhí)行效率

什么是NDK庫?

一些里庫的集合,比如log庫,第三方的openssl庫,主要是方便調(diào)用

jni用過嗎?

JNI是為了java調(diào)用c、c++封裝的一層接口

JNI調(diào)用本代碼開發(fā)流程:靜態(tài)注冊、動態(tài)注冊

靜態(tài)注冊

1、在java中生命native方法

2、用c、c++代碼實(shí)現(xiàn)native方法

3、編譯運(yùn)行

動態(tài)注冊

1、我們知道Java Native函數(shù)和JNI函數(shù)時一一對應(yīng)的,JNI中就有一個叫JNINativeMethod的結(jié)構(gòu)體來保存這個對應(yīng)關(guān)系,實(shí)現(xiàn)動態(tài)注冊方就需要用到這個結(jié)構(gòu)體

JNI調(diào)用java流程:

1、先通過類名找到類

2、根據(jù)方法名找到方法id

3、直接調(diào)用,如果類為非靜態(tài)類,需要先構(gòu)造類對象

類型簽名: 類:L+包名+類名

方法:(參數(shù)類型) + 返回值類型

基本類型:[ + 類型

Java如何調(diào)用c、c++語言?

Java支持跨平臺開發(fā),android為了java和本地代碼進(jìn)行交互,定義了jni,jni是java為了調(diào)用c、c++代碼封裝的一層接口

jni如何調(diào)用java層代碼?

1、根據(jù)類名找到類

2、根據(jù)方法名找到方法id

3、直接調(diào)用方法,如果類為非靜態(tài)類,需要先構(gòu)造類對象

進(jìn)程間通信的方式?

Bundle、文件共享、ContentProvider、AIDL

Binder機(jī)制

直觀的說Binder是一個類,它實(shí)現(xiàn)了IBinder接口

簡述IPC?

什么是IPC?

IPC簡稱進(jìn)程間通信,是指兩個進(jìn)程之間進(jìn)行數(shù)據(jù)交換的過程

為什么要用IPC(從多進(jìn)程通信會造成哪些方面的問題)

1、靜態(tài)成員或單例模式失效

我們都知道Android中不同進(jìn)程系統(tǒng)會分配不同的虛擬機(jī),每個虛擬機(jī)在內(nèi)存分配中都有單獨(dú)的內(nèi)存地址,不同的虛擬機(jī)訪問同一個類對象會產(chǎn)生多分副本,因此從一個進(jìn)程改變靜態(tài)變量,在另一個進(jìn)程訪問不會發(fā)生癌變

2、線程同步完全失效。內(nèi)存不同線程鎖對象也不同

3、SharedPreferences失效,它本身不支持多進(jìn)程讀寫,容易引起數(shù)據(jù)丟失

4、Application會多次創(chuàng)建

什么是AIDL?

AIDL解決了什么問題?

AIDL如何使用?

Android 上的 Inter-Process-Communication 跨進(jìn)程通信時如何工作的?

談?wù)剬Χ噙M(jìn)程開發(fā)的理解以及多進(jìn)程應(yīng)用場景

主要談?wù)刟ndroid

android中默認(rèn)情況下,同意應(yīng)用會運(yùn)行在一個進(jìn)程中,android:process可以指定不同進(jìn)程

(九)framework層、ROM定制、Ubuntu、Linux之類的問題?

談?wù)剬vm的理解

1?虛擬機(jī)并不神秘,在操作系統(tǒng)的角度看來,它只是一個普通進(jìn)程。

2?這個叫做虛擬機(jī)的進(jìn)程比較特殊,它能夠加載我們編寫的class文件。如果把JVM比作一個人,那么class文件就是我們吃的食物。

3?加載class文件的是一個叫做類加載器的子系統(tǒng)。就好比我們的嘴巴,把食物吃到肚子里。

4?虛擬機(jī)中的執(zhí)行引擎用來執(zhí)行class文件中的字節(jié)碼指令。就好比我們的腸胃,對吃進(jìn)去的食物進(jìn)行消化。

5?虛擬機(jī)在執(zhí)行過程中,要分配內(nèi)存創(chuàng)建對象。當(dāng)這些對象過時無用了,必須要自動清理這些無用的對象。清理對象回收內(nèi)存的任務(wù)由垃圾收集器負(fù)責(zé)。就好比人吃進(jìn)去的食物,在消化之后,必須把廢物排出體外,騰出空間可以在下次餓的時候吃飯并消化食物。

對Dalvik、ART虛擬機(jī)有什么了解?

JVM是java虛擬機(jī),運(yùn)行的是java字節(jié)碼,將字節(jié)碼保存在class文件,java通過節(jié)碼class文件來執(zhí)行

Dalvik是安卓虛擬機(jī),運(yùn)行的字節(jié)碼有java字節(jié)碼轉(zhuǎn)化過來,保存在dex文件中,dev通過執(zhí)行dex文件來執(zhí)行字節(jié)碼

類加載機(jī)制

負(fù)責(zé)加載java字節(jié)碼,并將字節(jié)碼轉(zhuǎn)化成.class文件的實(shí)例

談?wù)剬lassLoader(類加載器)的理解

JVM類加載機(jī)制分為五個部分:

加載:主要在內(nèi)存中生成一個類的Class對象

驗(yàn)證:確保Class中的字節(jié)流包含的信息符合虛擬機(jī)的要求

準(zhǔn)備:為方法區(qū)中的變量分配內(nèi)存控件

解析:虛擬機(jī)將常量池中的符號引用替換為直接引用的過程

初始化:真正的執(zhí)行java代碼

談?wù)剬討B(tài)加載(OSGI)的理解

定義:動態(tài)加載就是在程序運(yùn)行過程中動態(tài)的獲取類的方法、屬性、類信息

作用:通過對類的動態(tài)加載,我們只需要關(guān)注類的改變,而不需要關(guān)注實(shí)現(xiàn)動態(tài)加載相關(guān)代碼的操作

例如:反射……

內(nèi)存對象的循環(huán)引用及避免

A被B引用,B引用C,C引用A,引用計(jì)數(shù)法不會解決循環(huán)引用,會導(dǎo)致內(nèi)存泄漏,

1、可達(dá)性回收算法

2、盡量避免循環(huán)引用

內(nèi)存回收機(jī)制、GC回收策略、GC原理時機(jī)以及GC對象

1、java內(nèi)存分配:

堆:主要存放對象和數(shù)組,gc管理

棧:虛擬機(jī)棧和本地方法棧

方法區(qū):主要是類、靜態(tài)變量、常量和編譯之后的.class字節(jié)碼

2、GC回收機(jī)制(判斷是否可以回收):

? ? 引用計(jì)數(shù)法:

? ? ? ? ? ? ????????原理:通過一個計(jì)數(shù)器對對象進(jìn)行計(jì)數(shù),對象被引用時+1,引用失效時-1;當(dāng)計(jì)數(shù)為0時則說明可以被回收;

????????????????????缺點(diǎn):很難解決對象的相互循環(huán)引用問題?

? ? 可達(dá)性算法:“GC Roots”作為對象起始點(diǎn)向下搜索,搜索所走過的路徑稱為引用鏈,當(dāng)一個對象到GC Roots沒有任何引用鏈相連時,則證明此對象是不可用的?

3、GC回收機(jī)制:(如何回收)

標(biāo)記清除算法:直接回收沒有標(biāo)記的對象,缺點(diǎn):容易產(chǎn)生碎片

標(biāo)記整理算法:將未標(biāo)記的對象移動到端最后,然后清除

復(fù)制算法:將內(nèi)存分為A、B兩塊,將A中的對象復(fù)制到B中,然后再把A中清除,缺點(diǎn):犧牲一般內(nèi)存

分代回收算法:新生代和老年代;整合了標(biāo)記整理算法和復(fù)制算法

4、GC回收機(jī)制:(執(zhí)行回收)

Scavenge GC:當(dāng)對象申請內(nèi)存失敗時出觸發(fā)

Full GC :對整個堆進(jìn)行整理

大體說清一個應(yīng)用程序安裝到手機(jī)上時發(fā)生了什么

簡述Activity啟動全部過程

1、點(diǎn)擊App圖標(biāo)后通過startActivity遠(yuǎn)程調(diào)用到AMS中,AMS中將新啟動的activity以activityrecord的結(jié)構(gòu)壓入activity棧中,并通過遠(yuǎn)程binder回調(diào)到原進(jìn)程,使得原進(jìn)程進(jìn)入pause狀態(tài),原進(jìn)程pause后通知AMS我pause了

2、此時AMS再根據(jù)棧中Activity的啟動intent中的flag是否含有new_task的標(biāo)簽判斷是否需要啟動新進(jìn)程,啟動新進(jìn)程通過startProcessXXX的函數(shù)

3、啟動新進(jìn)程后通過反射調(diào)用ActivityThread的main函數(shù),main函數(shù)中調(diào)用looper.prepar和lopper.loop啟動消息隊(duì)列循環(huán)機(jī)制。最后遠(yuǎn)程告知AMS我啟動了。AMS回調(diào)handleLauncherAcitivyt加載activity。在handlerLauncherActivity中會通過反射調(diào)用Application的onCreate和activity的onCreate以及通過handleResumeActivity中反射調(diào)用Activity的onResume

Android為每個應(yīng)用程序分配的內(nèi)存大小是多少?

起初是30M,后來google取消了這個限制,可以用過android:largeHeap="true" 來設(shè)置

進(jìn)程?;畹姆绞?/p>

1、android進(jìn)程的優(yōu)先級

前臺進(jìn)程:當(dāng)前正在與用戶操作的進(jìn)程

可見進(jìn)程:沒有其他組件,但內(nèi)容可見

服務(wù)進(jìn)程:執(zhí)行與前臺進(jìn)程相關(guān)的操作

后臺進(jìn)程:用來回收內(nèi)存,LRU算法

空進(jìn)程:

2、android進(jìn)程的回收策略

Low memory kill:比較復(fù)雜的評分機(jī)制,對進(jìn)程進(jìn)行打分,評分高的進(jìn)程為bad進(jìn)程,殺死并釋放內(nèi)存

OOM_ODJ:判斷進(jìn)程的優(yōu)先級,優(yōu)先級越低,low memory kill就會啟動

3、進(jìn)程?;罘桨?/p>

利用系統(tǒng)廣播拉活:通過廣播監(jiān)聽被殺死就立即拉活

利用startForground:調(diào)用startForground開啟一個前臺進(jìn)程,降低oom_odj值,提升進(jìn)程優(yōu)先級

目前比較有效的方法有JobScheduler :

如何保證一個后臺服務(wù)不被殺死?(相同問題:如何保證service在后臺不被kill?)比較省電的方式是什么?

1、通過android:priority = 1000提升服務(wù)的優(yōu)先級

2、在onDestroy中通過通知來重啟服務(wù)

3、通過startForground將服務(wù)至于前臺:開發(fā)者在后臺創(chuàng)建job,當(dāng)某些條件被允許時,后臺進(jìn)程開始工作。

隨著系統(tǒng)的更新,很多進(jìn)程?;罘桨甘?/p>

App中喚醒其他進(jìn)程的實(shí)現(xiàn)方式

1、自定義啟動協(xié)議:<data android:scheme="wapchief" />

2、Activity中獲取其它進(jìn)程傳遞的Data數(shù)據(jù)

3、正則匹配要跳轉(zhuǎn)的界面

4、在調(diào)用方APP使用指定協(xié)議跳轉(zhuǎn)

介紹你做過的哪些項(xiàng)目

都使用過哪些框架、平臺?

都使用過哪些自定義控件?

研究比較深入的領(lǐng)域有哪些?

最近都讀哪些書?

android開發(fā)藝術(shù)探究,希望多了解一下IPC通信方式和Binder機(jī)制。以及四大組件原理

自己最擅長的技術(shù)點(diǎn),最感興趣的技術(shù)領(lǐng)域和技術(shù)點(diǎn)

項(xiàng)目中用了哪些開源庫,如何避免因?yàn)橐腴_源庫而導(dǎo)致的安全性和穩(wěn)定性問題

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容