都說衣不如新人不如故,技術是學新不學舊的?IPC+view+Handler+線程。

剛剛過去2019,新的一年2020年。都說衣不如新人不如故,技術是學新不學舊的?但是舊的知識不鞏固,根基不固很容易在面試或者實戰遇到很大的問題的

如下知識點PDF版後續可見
java

更多面試內容等等
(更多完整項目下載。未完待續。源碼。圖文知識後續上傳github。)
(VX:mm14525201314)
https://github.com/xiangjiana...android

一丶線程篇

一、線程池的好處? 四種線程池的使用場景,線程池的幾個參數的理解?

參考答案
使用線程池的好處是減小在建立和銷燬線程上所花的時間以及系統資源的開銷,解決資源不足的問題。若是不使用線程池,有可能形成系統建立大量同類線程而致使消耗完內存或則「過分切換」的問題,概括總結就是git

  • 重用存在的線程,減小對象建立、消亡的開銷,性能佳。
  • 可有效控制最大併發線程數,提升系統資源的使用率,同時避免過多資源競爭,避免堵塞
  • 提供定時執行、按期執行、單線程、併發數控制等功能。

Android 中的線程池都是直接或間接經過配置
ThreadPoolExecutor 來實現不一樣特性的線程池.Android 中最多見的類具備不一樣特性的線程池分別爲:github

  • newCachedThreadPool 只有非核心線程,最大線程數很是大,全部線程都活動時會爲新任務建立新線程,不然會利用空閒線程 ( 60s 空閒時間,過了就會被回收,因此線程池中有 0 個線程的可能 )來處理任務.

優勢: 任何任務都會被當即執行(任務隊列SynchronousQuue 至關於一個空集合);比較適合執行大量的耗時較少的任務.面試

  • newFixedThreadPool 只有核心線程,而且數量固定的,全部線程都活動時,由於隊列沒有限制大小,新任務會等待執行,當線程池空閒時不會釋放工做線程,還會佔用必定的系統資源。

優勢: 更快的響應外界請求算法

  • newScheduledThreadPool 核心線程數固定,非核心線程(閒着沒活幹會被當即回收數)沒有限制.

優勢: 執行定時任務以及有固定週期的重複任務編程

  • newSingleThreadExecutor 只有一個核心線程,確保全部的任務都在同一線程中按序完成

優勢: 不須要處理線程同步的問題緩存

經過源碼能夠了解到上面的四種線程池實際上仍是利用ThreadPoolExecutor 類實現的安全

//詳細介紹課參考Executors.java類
  public static ExecutorService newCachedThreadpool () {
         return new ThreadPoolExecutor (0,Integer.MAX_VALUE
                                        60L,TimeUnit.SECONDS,
                                        new SynchronousQueue<Runnable>());
  }
  ThreadPoolExecutor(int corepoolSize,int maxmumpoolSize,
                     long keepAliveTime,TimeUnit unit,
                     Blockingqueue<Runnable>workqueue,RejectedExecutionHandler handler
二、Android 中還了解哪些方便線程切換的類?

參考回答:服務器

  • AsyncTask 底層封裝了線程池和 Handler,便於執行後臺任務以及在子線程中進行 UI 操做。
  • HandlerThread 一種具備消息循環的線程,其內部可以使用Handler。
  • IntentService 是一種異步、會自動中止的服務,內部採用HandlerThread
三、 AsyncTask 的原理

參考回答:

  • AsyncTask 中有兩個線程池(SerialExecutor 和THREAD_POOL_EXECUTOR)和一個 Handler(InternalHandler),其中線程池 SerialExecutor 用於任務的排隊,而線程池THREAD_POOL_EXECUTOR 用於真正地執行任務,InternalHandler 用於將執行環境從線程池切換到主線程。
  • 靜態的 Handler 對象,爲了可以將執行環境切換到主線程,這就要求 這個對象必須在主線程建立。因爲靜態成員會在加載類的時候進行初始化,所以這就變相要求 AsyncTask 的類必須在主線程中加載,不然同一個進程中的 AsyncTask 都將沒法正常工做。
四、IntentService 有什麼用 ?

IntentService 可用於執行後臺耗時的任務,當任務執行完成後會自動中止,同時因爲 IntentService 是服務的緣由,不一樣於普通 Service,IntentService 可自動建立子線程來執行任務,這致使它的優先級比單純的線程要高,不容易被系統殺死,因此IntentService 比較適合執行一些高優先級的後臺任務。

五、直接在 Activity 中建立一個 thread 跟在 service 中建立一個 thread 之間的區別?

參考回答:

  • 在 Activity 中被建立: 該 Thread 的就是爲這個 Activity 服務的,完成這個特定的 Activity 交代的任務,主動通知該 Activity一些消息和事件,Activity 銷燬後,該 Thread 也沒有存活的意義了
  • 在 Service 中被建立: 這是保證最長生命週期的 Thread 的惟一方式,只要整個 Service 不退出,Thread 就能夠一直在後臺執行,通常在 Service 的 onCreate()中建立,在 onDestroy()中銷燬。因此,在 Service 中建立的 Thread,適合長期執行一些獨立於 APP 的後臺任務,比較常見的就是:在 Service 中保持與服務器端的長鏈接。
六、ThreadPoolExecutor 的工做策略 ?

參考回答: ThreadPoolExecutor 執行任務時會遵循以下規則

  • 若是線程池中的線程數量未達到核心線程的數量,那麼會直接啓動一個核心線程來執行任務。
  • 若是線程池中的線程數量已經達到或則超過核心線程的數量,那麼任務會被插入任務隊列中排隊等待執行。
  • 若是在第 2 點沒法將任務插入到任務隊列中,這每每是因爲任務隊列已滿,這個時候若是在線程數量未達到線程池規定的最大值,那麼會馬上啓動一個非核心線程來執行任務。
  • 若是第 3 點中線程數量已經達到線程池規定的最大值,那麼就拒絕執行此任務,ThreadPoolExecutor 會調用RejectedExecutionHandlerrejectedExecution 方法來通知調用者。
七、Handler、Thread 和 HandlerThread 的差異?

參考回答:

  • Handler: 在 android 中負責發送和處理消息,經過它能夠實現其餘支線線程與主線程之間的消息通信。
  • Thread: Java 進程中執行運算的最小單位,亦即執行處理機調度的基本單位。某一進程中一路單獨運行的程序。
  • HandlerThread: 一個繼承自 Thread 的類 HandlerThread,Android 中沒有對 Java 中的 Thread 進行任何封裝,而是提供了一個繼承自 Thread 的類 HandlerThread 類,這個類對 Java的 Thread 作了不少便利的封裝。HandlerThread 繼承於Thread,因此它本質就是個 Thread。與普通 Thread 的差異就在於,它在內部直接實現了 Looper 的實現,這是 Handler 消息機制必不可少的。有了本身的 looper,可讓咱們在本身的線程中分發和處理消息。若是不用 HandlerThread 的話,須要手動去調用 Looper.prepare()Looper.loop()這些方法。
八、ThreadLocal 的原理

參考回答:
ThreadLocal 是一個關於建立線程局部變量的類。使用場景以下所示:

  • 實現單個線程單例以及單個線程上下文信息存儲,好比交易 id 等
  • 實現線程安全,非線程安全的對象使用 ThreadLocal 以後就會變得線程安全,由於每一個線程都會有一個對應的實例。 承載一些線程相關的數據,避免在方法中來回傳遞參數。

當須要使用多線程時,有個變量恰巧不須要共享,此時就沒必要使用 synchronized 這麼麻煩的關鍵字來鎖住,每一個線程都至關於在堆內存中開闢一個空間,線程中帶有對共享變量的緩衝區,經過緩衝區將堆內存中的共享變量進行讀取和操做,ThreadLocal 至關於線程內的內存,一個局部變量。每次能夠對線程自身的數據讀取和操做,並不須要經過緩衝區與 主內存中的變量進行交互。並不會像 synchronized 那樣修改主內存的數據,再將主內存的數據複製到線程內的工做內存。ThreadLocal 可讓線程獨佔資源,存儲於線程內部,避免線程堵塞形成 CPU 吞吐降低。

在每一個 Thread 中包含一個 ThreadLocalMapThreadLocalMap 的 key 是 ThreadLocal 的對象,value 是獨享數據。

九、多線程是否必定會高效(優缺點)

參考回答:
多線程的優勢:

  • 方便高效的內存共享 - 多進程下內存共享比較不便,且會抵消掉多進程編程的好處
  • 較輕的上下文切換開銷 - 不用切換地址空間,不用更改CR3 寄存器,不清空 TLB
  • 線程上的任務執行完後自動銷燬

多線程的缺點:

  • 開啓線程須要佔用必定的內存空間(默認狀況下,每個線程都佔 512KB)
  • 若是開啓大量的線程,會佔用大量的內存空間,下降程序的性能
  • 線程越多,cpu 在調用線程上的開銷就越大
  • 程序設計更加複雜,好比線程間的通訊、多線程的數據共享

綜上得出,多線程不必定能提升效率,在內存空間緊張的狀況下反而是一種負擔,所以在平常開發中,應儘可能

  • 不要頻繁建立,銷燬線程,使用線程池
  • 減小線程間同步和通訊(最爲關鍵)
  • 避免須要頻繁共享寫的數據
  • 合理安排共享數據結構,避免僞共享(false sharing)
  • 使用非阻塞數據結構/算法
  • 避免可能產生可伸縮性問題的系統調用(好比 mmap)
  • 避免產生大量缺頁異常,儘可能使用 Huge Page
  • 能夠的話使用用戶態輕量級線程代替內核線程
十、多線程中,讓你作一個單例,你會怎麼作

參考回答:

  • 多線程中創建單例模式考慮的因素有不少,好比線程安全 -延遲加載-代碼安全:如防止序列化攻擊,防止反射攻擊(防止反射進行私有方法調用) -性能因素
  • 實現方法有多種,餓漢,懶漢(線程安全,線程非安全),雙重檢查(DCL),內部類,以及枚舉
//OkHttp例子
  private static volatile OkHttpHelper SInstance;
  
  public static OkHttpHelper getInstance() {
         if (sInstance =null) {
             synchronized (OkHttpHelper.class) {
                if (sInstance =null) {
                    sInstance = new OkHttpHelper();
                }
             }
          }
     return sInstance;
  }
十一、除了 notify 還有什麼方式能夠喚醒線程

參考回答:

  • 當一個擁有 Object 鎖的線程調用 wait()方法時,就會使當前線程加入 object.wait 等待隊列中,而且釋放當前佔用的 Object鎖,這樣其餘線程就有機會獲取這個 Object 鎖,得到 Object鎖的線程調用 notify()方法,就能在 Object.wait 等待隊列中隨機喚醒一個線程(該喚醒是隨機的與加入的順序無關,優先級高的被喚醒機率會高)
  • 若是調用 notifyAll()方法就喚醒所有的線程。注意:調用notify()方法後並不會當即釋放 object 鎖,會等待該線程執行完畢後釋放 Object 鎖。
十二、什麼是 ANR ? 什麼狀況會出現 ANR ?如何避免 ? 在不看代碼的狀況下如何快速定位出現 ANR 問題所在 ?

參考回答:

  • ANR(Application Not Responding,應用無響應):當操做在一段時間內系統沒法處理時,會在系統層面會彈出 ANR 對話框
  • 產生 ANR 多是由於 5s 內無響應用戶輸入事件、10s 內未結束BroadcastReceiver、20s 內未結束 Service
  • 想要避免 ANR 就不要在主線程作耗時操做,而是經過開子線程,方法好比繼承 Thread 或實現 Runnable 接口、使用AsyncTask IntentServiceHandlerThread

二丶Handler篇

一、談談消息機制 Handler 做用 ?有哪些要素 ?流程是怎樣的 ?

參考回答:
負責跨線程通訊,這是由於在主線程不能作耗時操做,而子線程不能更新 UI,因此當子線程中進行耗時操做後須要更新 UI時,經過 Handler 將有關 UI 的操做切換到主線程中執行。

具體分爲四大要素

  • Message(消息): 須要被傳遞的消息,消息分爲硬件產生的消息(如按鈕、觸摸)和軟件生成的消息。
  • MessageQueue(消息隊列): 負責消息的存儲與管理,負責管理由 Handler 發送過來的 Message。讀取會自動刪除消息,單鏈表維護,插入和刪除上有優點。在其 next()方法中會無限循環,不斷判斷是否有消息,有就返回這條消息並移除。
  • Handler(消息處理器): 負責 Message 的發送及處理。主要向消息池發送各類消息事件(Handler.sendMessage())和處理相應消息事件(Handler.handleMessage()),按照先進先出執行,內部使用的是單鏈表的結構。
  • Looper(消息池): 負責關聯線程以及消息的分發,在該線程下從 MessageQueue 獲取 Message,分發給Handler,Looper 建立的時候會建立一個MessageQueue,調用 loop()方法的時候消息循環開

始,其中會不斷調用 messageQueuenext()方法,當有消息就處理,不然阻塞在 messageQueuenext()方法中。當 Looperquit()被調用的時候會調用messageQueuequit(),此時 next()會返回 null,而後 loop()方法也就跟着退出。

流程:

  • 在主線程建立的時候會建立一個 Looper,同時也會在在Looper 內部建立一個消息隊列。而在創鍵 Handler 的時候取出當前線程的 Looper,並經過該 Looper 對象得到消息隊列,而後 Handler 在子線程中經過MessageQueue.enqueueMessage 在消息隊列中添加一條 Message。
  • 經過 Looper.loop() 開啓消息循環不斷輪詢調用MessageQueue.next(),取得對應的 Message 而且經過 Handler.dispatchMessage 傳遞給 Handler,最終調用 Handler.handlerMessage 處理消息。
二、一個線程可否建立多個 Handler,Handler 跟 Looper 之間的對應關係 ?

參考回答:

  • 一個 Thread 只能有一個 Looper,一個 MessageQueen,能夠有多個 Handler
  • 以一個線程爲基準,他們的數量級關係是: Thread(1) :Looper(1) : MessageQueue(1) : Handler(N)
三、軟引用跟弱引用的區別

參考回答:

  • 軟引用(SoftReference): 若是一個對象只具備軟引用,則內存空間充足時,垃圾回收器就不會回收它;若是內存空間不足了,就會回收這些對象的內存。只要垃圾回收器沒有回收它,該對象就能夠一直被程序使用。
  • 弱引用(WeakReference): 若是一個對象只具備弱引用,那麼在垃圾回收器線程掃描的過程當中,一旦發現了只具備弱引用的對象,無論當前內存空間足夠與否,都會回收它的內存。
  • 二者之間根本區別在於: 只具備弱引用的對象擁有更短暫的生命週期,可能隨時被回收。而只具備軟引用的對象只有當內存不夠的時候才被回收,在內存足夠的時候,一般不被回收。

四、Handler 引發的內存泄露緣由以及最佳解決方案

參考回答:
泄露緣由:Handler 容許咱們發送延時消息,若是在延時期間用戶關閉了 Activity,那麼該 Activity 會泄露。 這個泄露是由於 Message 會持有 Handler,而又由於 Java 的特性,內部類會持有外部類,使得 Activity 會被Handler 持有,這樣最終就致使 Activity 泄露。

解決方案:將 Handler 定義成靜態的內部類,在內部持有Activity 的弱引用,並在 AcitivityonDestroy()中調用 handler.removeCallbacksAndMessages(null)及時移除全部消息。

五、爲何系統不建議在子線程訪問 UI?

參考回答:
Android 的 UI 控件不是線程安全的,若是在多線程中併發訪問可能會致使 UI 控件處於不可預期的狀態

這時你可能會問爲什麼系統不對 UI 控件的訪問加上鎖機制呢?由於

  • 加鎖機制會讓 UI 訪問邏輯變的複雜
  • 加鎖機制會下降 UI 的訪問效率,由於加鎖會阻塞某些線程的執行

六、Looper 死循環爲何不會致使應用卡死?

參考回答:

  • 主線程的主要方法就是消息循環,一旦退出消息循環,那麼你的應用也就退出了,Looer.loop()方法可能會引發主線程的阻塞,但只要它的消息循環沒有被阻塞,能一直處理事件就不會產生 ANR 異常。
  • 形成 ANR 的不是主線程阻塞,而是主線程的 Looper 消息處理過程發生了任務阻塞,沒法響應手勢操做,不能及時刷新 UI。
  • 阻塞與程序無響應沒有必然關係,雖然主線程在沒有消息可處理的時候是阻塞的,可是隻要保證有消息的時候可以馬上處理,程序是不會無響應的。
七、使用 Handler 的 postDealy 後消息隊列會有什麼變化?

參考回答:
若是隊列中只有這個消息,那麼消息不會被髮送,而是計算到時喚醒的時間,先將 Looper 阻塞,到時間就喚醒它。但若是此時要加入新消息,該消息隊列的對頭跟 delay 時間相比更長,則插入到頭部,按照觸發時間進行排序,隊頭的時間最小、隊尾的時間最大

八、能夠在子線程直接 new 一個 Handler 嗎?怎麼作?

參考回答:
不能夠,由於在主線程中,Activity 內部包含一個 Looper 對象,它會自動管理 Looper,處理子線程中發送過來的消息。而對於子線程而言,沒有任何對象幫助咱們維護 Looper 對象,因此須要咱們本身手動維護。因此要在子線程開啓 Handler 要先建立 Looper,並開啓 Looper 循環

//代碼示例
  new Thread(new Runnable() {
             @Override
             public void run() {
                looper.prepare();
                new Handler() {
                    @Override
                     public void handlerMessage(Message msg) {
                        super.handleMessage(msg);
                     }
                     looper.loop();
                }
     }).start();
九、Message 能夠如何建立?哪一種效果更好,爲何?

參考回答: 能夠經過三種方法建立:

  • 直接生成實例 Message m = new Message
  • 經過 Message m = Message.obtain
  • 經過 Message m = mHandler.obtainMessage()

後二者效果更好,由於 Android 默認的消息池中消息數量是 10,然後
二者是直接在消息池中取出一個 Message 實例,這樣作就能夠避免多
生成 Message 實例。

三丶IPC

1 丶Android 中進程和線程的關係和區別?

參考回答:

  • 線程是 CPU 調度的 最小單元,同時線程是一種 有限的系統資源
  • 進程通常指一個執行單元,在 PC 和移動設備上一個程序或則一個應用
  • 通常來講,一個 App 程序 至少有一個進程,一個進程 至少有一個線程(包含與被包含的關係), 通俗來說就是,在App 這個工廠裏面有一個進程,線程就是裏面的生產線,但主線程(主生產線)只有一條,而子線程(副生產線)能夠有多個
  • 進程有本身獨立的地址空間,而進程中的線程共享此地址空間,均可以 併發執行
2 、如何開啓多進程 ? 應用是否能夠開啓 N 個進程 ?

參考回答:

  • AndroidMenifest 中給四大組件指定屬性android:process 開啓多進程模式
  • 在內存容許的條件下能夠開啓 N 個進程
3 、爲什麼須要 IPC ?多進程通訊可能會出現的問題?

參考回答:
全部運行在不一樣進程的四大組件(Activity、Service、Receiver丶ContentProvider)共享數據都會失敗,這是因爲 Android 爲每一個應用分配了獨立的虛擬機,不一樣的虛擬機在內存分配上有不一樣的地址空間,這會致使在不一樣的虛擬機中訪問同一個類的對象會產生多份副本。好比經常使用例子( 經過開啓多進程獲取更大內存空間、兩個或則多個應用之間共享數據、微信全家桶)

通常來講,使用多進程通訊會形成以下幾方面的問題

  • 靜態成員和單例模式徹底失效: 獨立的虛擬機形成
  • 線程同步機制徹底實效: 獨立的虛擬機形成
  • SharedPreferences 的可靠性降低: 這是由於 Sp 不支持兩個進程併發進行讀寫,有必定概率致使數據丟失
  • Application 會屢次建立: Android 系統在建立新的進程會分配獨立的虛擬機,因此這個過程其實就是啓動一個應用的過程,天然也會建立新的Application
4 丶Android 中 IPC 方式、各類方式優缺點,爲何選擇 Binder

參考回答:

與 Linux 上傳統的 IPC 機制,好比 System V,Socket 相比,Binder 好在哪呢?
傳輸效率高、可操做性強: 傳輸效率主要影響因素是內存拷貝的次數,拷貝次數越少,傳輸速率越高。從 Android進程架構角度分析:對於消息隊列、Socket 和管道來講,數據先從發送方的緩存區拷貝到內核開闢的緩存區中,再從內核緩存區拷貝到接收方的緩存區,一共兩次拷貝,如圖:

而對於 Binder 來講,數據從發送方的緩存區拷貝到內核的緩存區,而接收方的緩存區與內核的緩存區是映射到同一塊物理地址的,節省了一次數據拷貝的過程,如圖:

因爲共享內存操做複雜,綜合來看,Binder 的傳輸效率是最好的。

實現 C/S 架構方便: Linux 的衆 IPC 方式除了 Socket 之外都不是基於 C/S 架構,而 Socket 主要用於網絡間的通訊且傳輸效率較低。Binder 基於 C/S 架構 ,Server 端與Client 端相對獨立,穩定性較好。
安全性高: 傳統 Linux IPC 的接收方沒法得到對方進程可靠的 UID/PID,從而沒法鑑別對方身份;而 Binder 機制爲每一個進程分配了 UID/PID 且在 Binder 通訊時會根據UID/PID 進行有效性檢測。

5 、Binder機制的左右和原理

參考回答:
Linux 系統將一個進程分爲 用戶空間和 內核空間。對於進程之間來講,用戶空間的數據不可共享,內核空間的數據可共享,爲了保證安全性和獨立性,一個進程不能直接操做或者訪問另外一個進程,即 Android 的進程是相互獨立、隔離的,這就須要跨進程之間的數據通訊方式

一次完整的 Binder IPC 通訊過程一般是這樣:

  • 首先 Binder 驅動在內核空間建立一個數據接收緩存區;
  • 接着在內核空間開闢一塊內核緩存區,創建內核緩存區和內核中數據接收緩存區之間的映射關係,以及內核中數據接收緩存區和接收進程用戶空間地址的映射關係;
  • 發送方進程經過系統調用 copyfromuser() 將數據 copy 到內核中的內核緩存區,因爲內核緩存區和接收進程的用戶空間存在內存映射,所以也就至關於把數據發送到了接收進程的用戶空間,這樣便完成了一次進程間的通訊。

6 、Binder 框架中 ServiceManager的做用

參考回答:

  • Binder 框架 是基於 C/S 架構的。由一系列的組件組成,包括 Client、Server、ServiceManager、Binder 驅動,其中Client、Server、Service Manager 運行在用戶空間,Binder 驅動運行在內核空間

  • Server&Client: 服務器&客戶端。在 Binder 驅動和Service Manager 提供的基礎設施上,進行 Client-Server 之間的通訊。
  • ServiceManager(如同 DNS 域名服務器)服務的管理者,將 Binder 名字轉換爲 Client 中對該 Binder的引用,使得 Client 能夠經過 Binder 名字得到Server 中 Binder 實體的引用。
  • Binder 驅動(如同路由器): 負責進程之間 binder通訊的創建,傳遞,計數管理以及數據的傳遞交互等底層支持

7丶Bundle 傳遞對象爲何須要序列化?Serialzable 和 Parcelable

參考回答:

  • 由於 bundle 傳遞數據時只支持基本數據類型,因此在傳遞對象時須要序列化轉換成可存儲或可傳輸的本質狀態(字節流)。序列化後的對象能夠在網絡、IPC(好比啓動另外一個進程的 Activity、Service 和 Reciver)之間進行傳輸,也能夠存儲到本地。
  • 序列化實現的兩種方式:實現 Serializable/Parcelable接口。不一樣點如圖:

8 、講講 AIDL ?原理是什麼?如何優化多模塊都使用 AIDL

參考回答:
AIDL(Android Interface Definition Language,Android接口定義語言):若是在一個進程中要調用另外一個進程中對象的方法,可以使用 AIDL 生成可序列化的參數,AIDL 會生成一個服務端對象的代理類,經過它客戶端實現間接調用服務端對象的方法

AIDL 的本質是系統提供了一套可快速實現 Binder 的工具。關鍵類和方法:

  • AIDL 接口: 繼承 Interface
  • Stub 類: Binder 的實現類,服務端經過這個類來提供服務。
  • Proxy 類: 服務器的本地代理,客戶端經過這個類調用服務器的方法。
  • asInterface() 客戶端調用,將服務端的返回的Binder 對象,轉換成客戶端所須要的 AIDL 接口類型對象。若是客戶端和服務端位於統一進程,則直接返回 Stub 對象自己,不然返回系統封裝後的Stub.proxy 對象
  • asBinder()根據當前調用狀況返回代理 Proxy 的Binder 對象。
  • onTransact() 運行服務端的 Binder 線程池中,當客戶端發起跨進程請求時,遠程請求會經過系統底層封裝後交由此方法來處理。
  • transact() 運行在客戶端,當客戶端發起遠程請求的同時將當前線程掛起。以後調用服務端的onTransact()直到遠程請求返回,當前線程才繼續執行。

當有多個業務模塊都須要 AIDL 來進行 IPC,此時須要爲每一個模塊建立特定的 aidl 文件,那麼相應的 Service 就會不少。必然會出現系統資源耗費嚴重、應用過分重量級的問題。解決辦法是創建 Binder 鏈接池,即將每一個業務模塊的Binder 請求統一轉發到一個遠程 Service 中去執行,從而避免重複建立 Service。

工做原理: 每一個業務模塊建立本身的 AIDL 接口並實現此接口,而後向服務端提供本身的惟一標識和其對應的 Binder 對象。服務端只須要一個 Service,服務器提供一個 queryBinder 接口,它會根據業務模塊的特徵來返回相應的 Binder 對象,不一樣的業務模塊拿到所需的 Binder 對象後就可進行遠程方法的調用了

查看完整的PDF版
(更多完整項目下載。未完待續。源碼。圖文知識後續上傳github。)
能夠聯繫我獲取完整PDF
https://github.com/xiangjiana/Android-MS
(VX:mm14525201314)

相關文章
相關標籤/搜索