【最新Android高級面試知識點乾貨分享(六)】
轉載請註明出處!
九、Android事件分發機制
事件分發機制是個必考點,網上也有很多很好的文章,在複習的過程中,建議按照源碼自己動手動畫畫,下圖就是我自己整理的,有不對或不完整的地方,歡迎留言,我將確認後更改更新。
注意:Android事件從ACTION_DOWN開始往下傳,依次ACTION_MOVE---->ACTION_UP,如果某一個事件被截斷,不再往下傳,則會生成一個ACTION_CANCEL事件傳下去。
十、 Handler消息處理機制
下圖是我根據源碼整理的筆記圖。
公供參考,希望讀者也自己整理一遍,加深理解記憶。
$10.1、 Looper循環實現原理
- 在Looper.prepare()裏面創建了MessageQueue、Thread對象;
- 在Looper.loop()方法裏面用while無限循環從MessageQueue中取出。
十一、Android Binder機制
進程間通信
基於傳輸性能與安全的考慮,安卓建立了一套有別於傳統IPC的進程間通信。
它是一套通信機制,下面是基於此整理的幾個分開的知識點。
$11.1、 Linux 中mmap內存映射
-
Linux中Page Cache頁緩存概念
指將磁盤數據讀取到內核空間的一塊緩存空間
-
標準IO、直接IO與mmap區別
-
標準IO(又稱緩存IO):2次CPU拷貝,
-
直接IO:1次CPU拷貝,但沒有緩存,適用於數據庫系統
-
mmap:1次CPU拷貝,有內核緩存(內部採用延遲機制,會將數據回寫進磁盤)
-
page:計算機虛擬內存分頁機制
(圖片來源於網絡)
-
關於【內存映射】:
計算機上有個頁表,將虛擬內存上的頁號與
物理內存上的頁幀號對應起來的過程就是內存映射。
$11.2、 Parcelable與Serializable
二者都是序列化與反序列化類,區別如下:
序列化方式 | 開發者 | 原理 | 性能 | 實現方式 |
---|---|---|---|---|
Serializable | Java | 通過標準IO流進行數據讀寫 | 慢 | 實現 Serializable接口 |
Parcelable | Android | 底層採用Binder通信機制,利用mmap內存映射實現數據讀寫 | 快 | 實現Parcelable接口,並實現writeToParcel、describeContents函數以及靜態的CREATOR變量 |
$11.3、 AIDL
接口編程語言
可牽涉的知識面或者知識點:JVM編譯或者apk打包流程、動態代理等
原理:編寫interface,利用JVM在編譯時,將xx.aidl文件(以IPerson.aidl爲例)自動生成爲java文件,且繼承自android.os.Interface。
自動生成的IPerson.java接口文件裏面,自動生成了2個靜態內部類:Stub、Proxy
Stub:是抽像類,繼承自android.os.Binder,同時實現IPerson:
/****
**自動生成的interface接口類
**
*/
public interface IPerson extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements ext.sunny.com.activitylifedemo.IPerson
{
private static final java.lang.String DESCRIPTOR = "ext.sunny.com.activitylifedemo.IPerson";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
因此,應用層(服務端,比如Service)只需實例化Stub對像,就可以實現aidl接口的方法
val mBinder: Stub = object : Stub() {
override fun getName(): String {
return "SunnyAIDL:$userName"
}
override fun setName(name: String?) {
userName = name
}
}
同時自動生成的這個類,還提供了asInterface(object:IBinder?)方法,以便獲取接口對像,內部採用Proxy代理模式實現,主要是方便客戶端調用接口方法:
(在Android中,主要是ServiceConnection中實現)
/***
* 開始綁定Service
*/
fun startAIDL(view: View) {
var aidlIntent = Intent(this,personService!!::class.java)
this.bindService(aidlIntent,object :ServiceConnection{
override fun onServiceDisconnected(name: ComponentName?) {
iPerson=null
}
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
iPerson = IPerson.Stub.asInterface(service)
}
}, Context.BIND_AUTO_CREATE)
}
十二、Apk打包流程
整體流程圖如下(圖片來源於Android開發者文檔):
$12.1、 AAPT
Android資源打包工具。
工具路徑:
D:\developer\Android\sdk\build-tools\28.0.3\aapt2.exe
可以通過aapt package 命令來對項目中的資源文件進行打包,會生成R.java文件。
同時也可以用aapt l等命令對apk中的信息【如:資源信息、應用版本信息,包名。。。】進行查詢。
【注】:從AndroidStudio3.0開始,默認啓用AAPT2,而AAPT已被棄用。AAPT2對比AAPT,前者在資源格式規則校驗上更加嚴格,不再以忽略或警告來提示,而是直接以Error的形式出現。詳情可見:https://developer.android.google.cn/studio/command-line/aapt2
$12.2、 AIDL工具
工具路徑:
D:\developer\Android\sdk\build-tools\28.0.3\aidl.exe
作用:
編譯aidl文件成爲 Java接口。具體可見上面。
(下一篇將整理分享關於Android第三方開源庫的複習筆記)