真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

談?wù)凙ndroidBinder機(jī)制及AIDL使用

Binder原理
1、概述

Android系統(tǒng)中,涉及到多進(jìn)程間的通信底層都是依賴于Binder IPC機(jī)制。例如當(dāng)進(jìn) 程A中的Activity要向進(jìn)程B中的Service通信,這便需要依賴于Binder IPC。不僅于 此,整個(gè)Android系統(tǒng)架構(gòu)中,大量采用了Binder機(jī)制作為IPC(進(jìn)程間通信, Interprocess Communication)方案。

創(chuàng)新互聯(lián)建站專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作、上饒網(wǎng)絡(luò)推廣、微信平臺(tái)小程序開(kāi)發(fā)、上饒網(wǎng)絡(luò)營(yíng)銷、上饒企業(yè)策劃、上饒品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)建站為所有大學(xué)生創(chuàng)業(yè)者提供上饒建站搭建服務(wù),24小時(shí)服務(wù)熱線:18982081108,官方網(wǎng)址:www.cdcxhl.com

當(dāng)然也存在部分其他的IPC方式,如管道、SystemV、Socket等。那么Android為什 么不使用這些原有的技術(shù),而是要使開(kāi)發(fā)一種新的叫Binder的進(jìn)程間通信機(jī)制呢?

順手留下GitHub鏈接,需要獲取相關(guān)面試等內(nèi)容的可以自己去找
https://github.com/xiangjiana/Android-MS
(VX:mm14525201314)

為什么要使用Binder?
性能方面 在移動(dòng)設(shè)備上(性能受限制的設(shè)備,比如要省電),廣泛地使用跨進(jìn)程通信對(duì)通信 機(jī)制的性能有嚴(yán)格的要求,Binder相對(duì)于傳統(tǒng)的Socket方式,更加高效。Binder數(shù) 據(jù)拷貝只需要一次,而管道、消息隊(duì)列、Socket都需要2次,共享內(nèi)存方式一次內(nèi) 存拷貝都不需要,但實(shí)現(xiàn)方式又比較復(fù)雜。

安全方面
傳統(tǒng)的進(jìn)程通信方式對(duì)于通信雙方的身份并沒(méi)有做出嚴(yán)格的驗(yàn)證,比如Socket通信 的IP地址是客戶端手動(dòng)填入,很容易進(jìn)行偽造。然而,Binder機(jī)制從協(xié)議本身就支 持對(duì)通信雙方做身份校檢,從而大大提升了安全性。

2、 Binder

IPC原理
從進(jìn)程角度來(lái)看IPC(Interprocess Communication)機(jī)制
談?wù)凙ndroid Binder機(jī)制及AIDL使用
每個(gè)Android的進(jìn)程,只能運(yùn)行在自己進(jìn)程所擁有的虛擬地址空間。例如,對(duì)應(yīng)一 個(gè)4GB的虛擬地址空間,其中3GB是用戶空間,1GB是內(nèi)核空間。當(dāng)然內(nèi)核空間的 大小是可以通過(guò)參數(shù)配置調(diào)整的。對(duì)于用戶空間,不同進(jìn)程之間是不能共享的,而 內(nèi)核空間卻是可共享的。Client進(jìn)程向Server進(jìn)程通信,恰恰是利用進(jìn)程間可共享 的內(nèi)核內(nèi)存空間來(lái)完成底層通信工作的。Client端與Server端進(jìn)程往往采用ioctl等方 法與內(nèi)核空間的驅(qū)動(dòng)進(jìn)行交互。

Binder原理
Binder通信采用C/S架構(gòu),從組件視角來(lái)說(shuō),包含Client、Server、ServiceManager 以及Binder驅(qū)動(dòng),其中ServiceManager用于管理系統(tǒng)中的各種服務(wù)。架構(gòu)圖如下所 示:
談?wù)凙ndroid Binder機(jī)制及AIDL使用
Binder通信的四個(gè)角色

Client進(jìn)程:使用服務(wù)的進(jìn)程。
Server進(jìn)程:提供服務(wù)的進(jìn)程。
ServiceManager進(jìn)程:ServiceManager的作用是將字符形式的Binder名字轉(zhuǎn)化成 Client中對(duì)該Binder的引用,使得Client能夠通過(guò)Binder名字獲得對(duì)Server中Binder 實(shí)體的引用。
Binder驅(qū)動(dòng):驅(qū)動(dòng)負(fù)責(zé)進(jìn)程之間Binder通信的建立,Binder在進(jìn)程之間的傳遞, Binder引用計(jì)數(shù)管理,數(shù)據(jù)包在進(jìn)程之間的傳遞和交互等一系列底層支持。

Binder運(yùn)行機(jī)制
圖中Client/Server/ServiceManage之間的相互通信都是基于Binder機(jī)制。既然基于 Binder機(jī)制通信,那么同樣也是C/S架構(gòu),則圖中的3大步驟都有相應(yīng)的Client端與 Server端。

注冊(cè)服務(wù)(addService):Server進(jìn)程要先注冊(cè)Service到ServiceManager。該過(guò) 程:Server是客戶端,ServiceManager是服務(wù)端。
獲取服務(wù)(getService):Client進(jìn)程使用某個(gè)Service前,須先向ServiceManager中 獲取相應(yīng)的Service。該過(guò)程:Client是客戶端,ServiceManager是服務(wù)端。
使用服務(wù):Client根據(jù)得到的Service信息建立與Service所在的Server進(jìn)程通信的通 路,然后就可以直接與Service交互。該過(guò)程:Client是客戶端,Server是服務(wù)端。

圖中的Client,Server,Service Manager之間交互都是虛線表示,是由于它們彼此 之間不是直接交互的,而是都通過(guò)與Binder驅(qū)動(dòng)進(jìn)行交互的,從而實(shí)現(xiàn)IPC通信 (Interprocess Communication)方式。其中Binder驅(qū)動(dòng)位于內(nèi)核空間,Client, Server,Service Manager位于用戶空間。Binder驅(qū)動(dòng)和Service Manager可以看做 是Android平臺(tái)的基礎(chǔ)架構(gòu),而Client和Server是Android的應(yīng)用層,開(kāi)發(fā)人員只需自 定義實(shí)現(xiàn)Client、Server端,借助Android的基本平臺(tái)架構(gòu)便可以直接進(jìn)行IPC通 信。

Binder運(yùn)行的實(shí)例解釋
首先我們看看我們的程序跨進(jìn)程調(diào)用系統(tǒng)服務(wù)的簡(jiǎn)單示例,實(shí)現(xiàn)浮動(dòng)窗口部分代 碼:

  //獲取WindowManager服務(wù)引用 
  WindowManager wm = (WindowManager) getSystemService(getApplicati on().WINDOW_SERVICE); 
  //布局參數(shù)layoutParams相關(guān)設(shè)置略... 
  View view = LayoutInflater.from(getApplication()).inflate(R.layo ut.float_layout, null); 
  //添加view 
  wm.addView(view, layoutParams);

注冊(cè)服務(wù)(addService):在Android開(kāi)機(jī)啟動(dòng)過(guò)程中,Android會(huì)初始化系統(tǒng)的各種 Service,并將這些Service向ServiceManager注冊(cè)(即讓ServiceManager管理)。 這一步是系統(tǒng)自動(dòng)完成的。
獲取服務(wù)(getService):客戶端想要得到具體的Service直接向ServiceManager要 即可。客戶端首先向ServiceManager查詢得到具體的Service引用,通常是Service 引用的代理對(duì)象,對(duì)數(shù)據(jù)進(jìn)行一些處理操作。即第2行代碼中,得到的wm是 WindowManager對(duì)象的引用。
使用服務(wù):通過(guò)這個(gè)引用向具體的服務(wù)端發(fā)送請(qǐng)求,服務(wù)端執(zhí)行完成后就返回。即 第6行調(diào)用WindowManageraddView函數(shù),將觸發(fā)遠(yuǎn)程調(diào)用,調(diào)用的是運(yùn)行在 systemServer進(jìn)程中的WindowManageraddView函數(shù)。
使用服務(wù)的具體執(zhí)行過(guò)程
談?wù)凙ndroid Binder機(jī)制及AIDL使用

  1. Client通過(guò)獲得一個(gè)Server的代理接口,對(duì)Server進(jìn)行調(diào)用。
  2. 代理接口中定義的方法與Server中定義的方法是一一對(duì)應(yīng)的。
  3. Client調(diào)用某個(gè)代理接口中的方法時(shí),代理接口的方法會(huì)將Client傳遞的參數(shù)打 包成Parcel對(duì)象。
  4. 代理接口將Parcel發(fā)送給內(nèi)核中的Binder Driver。
  5. Server會(huì)讀取Binder Driver中的請(qǐng)求數(shù)據(jù),如果是發(fā)送給自己的,解包Parcel 對(duì)象,處理并將結(jié)果返回。
  6. 整個(gè)的調(diào)用過(guò)程是一個(gè)同步過(guò)程,在Server處理的時(shí)候,Client會(huì)Block住。因 此Client調(diào)用過(guò)程不應(yīng)在主線程。
AIDL的使用
1.AIDL的簡(jiǎn)介

AIDL (Android Interface Definition Language) 是一種接口定義語(yǔ)言,用于生成可以 在Android設(shè)備上兩個(gè)進(jìn)程之間進(jìn)行進(jìn)程間通信(Interprocess Communication, IPC) 的代碼。如果在一個(gè)進(jìn)程中(例如Activity)要調(diào)用另一個(gè)進(jìn)程中(例如Service) 對(duì)象的操作,就可以使用AIDL生成可序列化的參數(shù),來(lái)完成進(jìn)程間通信。

簡(jiǎn)言之,AIDL能夠?qū)崿F(xiàn)進(jìn)程間通信,其內(nèi)部是通過(guò)Binder機(jī)制來(lái)實(shí)現(xiàn)的,后面會(huì) 具體介紹,現(xiàn)在先介紹AIDL的使用。

2.AIDL的具體使用

AIDL的實(shí)現(xiàn)一共分為三部分,一部分是客戶端,調(diào)用遠(yuǎn)程服務(wù)。一部分是服務(wù)端, 提供服務(wù)。最后一部分,也是最關(guān)鍵的是AIDL接口,用來(lái)傳遞的參數(shù),提供進(jìn)程間 通信。
先在服務(wù)端創(chuàng)建AIDL部分代碼。
AIDL文件 通過(guò)如下方式新建一個(gè)AIDL文件
談?wù)凙ndroid Binder機(jī)制及AIDL使用
默認(rèn)生成格式

  interface IBookManager { 
      /**
       * Demonstrates some basic types that you can use as paramet ers 
       * and return values in AIDL. 
       */ 
     void basicTypes(int anInt, long aLong, boolean aBoolean, flo at aFloat, double aDouble, String aString);
   }

默認(rèn)如下格式,由于本例要操作Book類,實(shí)現(xiàn)兩個(gè)方法,添加書(shū)本和返回書(shū)本列 表。
定義一個(gè)Book類,實(shí)現(xiàn)Parcelable接口。

  public class Book implements Parcelable { 
     public int bookId; 
     public String bookName; 

     public Book() { 
     }

     public Book(int bookId, String bookName) { 
        this.bookId = bookId; 
        this.bookName = bookName; 
     }

     public int getBookId() { 
        return bookId; 
     }

     public void setBookId(int bookId) { 
        this.bookId = bookId; 
     }
     public String getBookName() { 
        return bookName; 
     }
     public void setBookName(String bookName) { 
        this.bookName = bookName; 
     }

     @Override 
     public int describeContents() { 
        return 0; 
     }

     @Override 
     public void writeToParcel(Parcel dest, int flags) { 
        dest.writeInt(this.bookId); 
        dest.writeString(this.bookName); 
     }

     protected Book(Parcel in) { 
        this.bookId = in.readInt(); 
        this.bookName = in.readString(); 
     }
     public static final Parcelable.Creator CREATOR = new P arcelable.Creator() {
        @Override 
        public Book createFromParcel(Parcel source) { 
           return new Book(source); 
        }

        @Override 
        public Book[] newArray(int size) { 
           return new Book[size]; 
        } 
    }; 
  }

由于AIDL只支持?jǐn)?shù)據(jù)類型:基本類型(int,long,char,boolean等),String, CharSequence,List,Map,其他類型必須使用import導(dǎo)入,即使它們可能在同一 個(gè)包里,比如上面的Book。 最終IBookManager.aidl 的實(shí)現(xiàn)

  // Declare any non-default types here with import statements import com.lvr.aidldemo.Book; 
  interface IBookManager { 
     /**
       * Demonstrates some basic types that you can use as paramet ers 
       * and return values in AIDL. 
       */ 
    void basicTypes(int anInt, long aLong, boolean aBoolean, flo at aFloat, double aDouble, String aString); 
    void addBook(in Book book); List getBookList(); 
  }

注意:如果自定義的Parcelable對(duì)象,必須創(chuàng)建一個(gè)和它同名的AIDL文件,并在其 中聲明它為parcelable類型。

Book.aidl

  // Book.aidl 
  package com.lvr.aidldemo; 

  parcelable Book;

以上就是AIDL部分的實(shí)現(xiàn),一共三個(gè)文件。 然后Make Project ,SDK為自動(dòng)為我們生成對(duì)應(yīng)的Binder類。 在如下路徑下:
談?wù)凙ndroid Binder機(jī)制及AIDL使用
其中該接口中有個(gè)重要的內(nèi)部類Stub ,繼承了Binder 類,同時(shí)實(shí)現(xiàn)了 IBookManager接口。 這個(gè)內(nèi)部類是接下來(lái)的關(guān)鍵內(nèi)容。

public static abstract class Stub extends android.os.Binder impl ements com.lvr.aidldemo.IBookManager{}

服務(wù)端 服務(wù)端首先要?jiǎng)?chuàng)建一個(gè)Service用來(lái)監(jiān)聽(tīng)客戶端的連接請(qǐng)求。然后在Service 中實(shí)現(xiàn)Stub 類,并定義接口中方法的具體實(shí)現(xiàn)。

  //實(shí)現(xiàn)了AIDL的抽象函數(shù) 
  private IBookManager.Stub mbinder = new IBookManager.Stub() { 
     @Override 
     public void basicTypes(int anInt, long aLong, boolean aBoole an, float aFloat, double aDouble, String aString) throws RemoteE xception {
        //什么也不做 
     }

     @Override 
     public void addBook(Book book) throws RemoteException { 
        //添加書(shū)本 
        if (!mBookList.contains(book)) { 
             mBookList.add(book); } 
     }

     @Override 
     public List getBookList() throws RemoteException { 
       return mBookList; 
    } 
  };

當(dāng)客戶端連接服務(wù)端,服務(wù)端就會(huì)調(diào)用如下方法:

  public IBinder onBind(Intent intent) { 
     return mbinder; 
  }

就會(huì)把Stub實(shí)現(xiàn)對(duì)象返回給客戶端,該對(duì)象是個(gè)Binder對(duì)象,可以實(shí)現(xiàn)進(jìn)程間通 信。 本例就不真實(shí)模擬兩個(gè)應(yīng)用之間的通信,而是讓Service另外開(kāi)啟一個(gè)進(jìn)程來(lái) 模擬進(jìn)程間通信。

   
       
           
           
       
  

android:process=":remote"設(shè)置為另一個(gè)進(jìn)程。 <action android:name="com.lvr.aidldemo.MyService"/> 是為了能讓其他apk隱式 bindService。通過(guò)隱式調(diào)用的方式來(lái)連接service,需要把category設(shè)為default, 這是因?yàn)?,隱式調(diào)用的時(shí)候,intent中的category默認(rèn)會(huì)被設(shè)置為default。

客戶端
首先將服務(wù)端工程中的aidl文件夾下的內(nèi)容整個(gè)拷貝到客戶端工程的對(duì)應(yīng)位置下, 由于本例的使用在一個(gè)應(yīng)用中,就不需要拷貝了,其他情況一定不要忘記這一步。
客戶端需要做的事情比較簡(jiǎn)單,首先需要綁定服務(wù)端的Service。

  Intent intentService = new Intent(); 
  intentService.setAction("com.lvr.aidldemo.MyService"); 
  intentService.setPackage(getPackageName()); 
  intentService.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
  MyClient.this.bindService(intentService, mServiceConnection, BIN 
  D_AUTO_CREATE); 
  Toast.makeText(getApplicationContext(), "綁定了服務(wù)", Toast.LENGTH _SHORT).show();

將服務(wù)端返回的Binder對(duì)象轉(zhuǎn)換成AIDL接口所屬的類型,接著就可以調(diào)用AIDL中的 方法了。

  if (mIBookManager != null) { 
     try {
          mIBookManager.addBook(new Book(18, "新添加的書(shū)")); 
          Toast.makeText(getApplicationContext(), mIBookManager.ge 
  tBookList().size() + "", Toast.LENGTH_SHORT).show(); 
     } catch (RemoteException e) {
     e.printStackTrace(); 
     } 
  }
3.AIDL的工作原理

Binder機(jī)制的運(yùn)行主要包括三個(gè)部分:注冊(cè)服務(wù)、獲取服務(wù)和使用服務(wù)。 其中注冊(cè) 服務(wù)和獲取服務(wù)的流程涉及C的內(nèi)容,由于個(gè)人能力有限,就不予介紹了。
本篇文章主要介紹使用服務(wù)時(shí),AIDL的工作原理。

①.Binder對(duì)象的獲取
Binder是實(shí)現(xiàn)跨進(jìn)程通信的基礎(chǔ),那么Binder對(duì)象在服務(wù)端和客戶端是共享的,是 同一個(gè)Binder對(duì)象。在客戶端通過(guò)Binder對(duì)象獲取實(shí)現(xiàn)了IInterface接口的對(duì)象來(lái)調(diào) 用遠(yuǎn)程服務(wù),然后通過(guò)Binder來(lái)實(shí)現(xiàn)參數(shù)傳遞。

那么如何維護(hù)實(shí)現(xiàn)了IInterface接口的對(duì)象和獲取Binder對(duì)象呢?
服務(wù)端獲取Binder對(duì)象并保存IInterface接口對(duì)象 Binder中兩個(gè)關(guān)鍵方法:

  public class Binder implement IBinder { 
     void attachInterface(IInterface plus, String descriptor) 
     IInterface queryLocalInterface(Stringdescriptor) //從IBinder 中繼承而來(lái) 
    ......
   }

Binder具有被跨進(jìn)程傳輸?shù)哪芰κ且驗(yàn)樗鼘?shí)現(xiàn)了IBinder接口。系統(tǒng)會(huì)為每個(gè)實(shí)現(xiàn)了 該接口的對(duì)象提供跨進(jìn)程傳輸,這是系統(tǒng)給我們的一個(gè)很大的福利。

Binder具有的完成特定任務(wù)的能力是通過(guò)它的IInterface的對(duì)象獲得的,我們可以 簡(jiǎn)單理解attachInterface方法會(huì)將(descriptor,plus)作為(key,value)對(duì)存入 Binder對(duì)象中的一個(gè)Map對(duì)象中,Binder對(duì)象可通過(guò)attachInterface方法持有一個(gè) IInterface對(duì)象(即plus)的引用,并依靠它獲得完成特定任務(wù)的能力。 queryLocalInterface方法可以認(rèn)為是根據(jù)key值(即參數(shù) descriptor)查找相應(yīng)的 IInterface對(duì)象。 在服務(wù)端進(jìn)程,通過(guò)實(shí)現(xiàn) private IBookManager.Stub mbinder = new IBookManager.Stub() {}抽象類,獲得Binder對(duì)象。 并保存了IInterface對(duì)象。

  public Stub() { 
     this.attachInterface(this, DESCRIPTOR); 
  }

客戶端獲取Binder對(duì)象并獲取IInterface接口對(duì)象 通過(guò)bindService獲得Binder對(duì)象

  MyClient.this.bindService(intentService, mServiceConnection, BIN D_AUTO_CREATE);

然后通過(guò)Binder對(duì)象獲得IInterface對(duì)象。

  private ServiceConnection mServiceConnection = new ServiceConnec tion() { 
     @Override 
     public void onServiceConnected(ComponentName name, IBinder b inder) {
       //通過(guò)服務(wù)端onBind方法返回的binder對(duì)象得到IBookManager的實(shí)例, 得到實(shí)例就可以調(diào)用它的方法了 
       mIBookManager = IBookManager.Stub.asInterface(binder); 
     }
     @Override 
     public void onServiceDisconnected(ComponentName name) { 
     mIBookManager = null; 
     } 
  };

其中 asInterface(binder)方法如下:

  public static com.lvr.aidldemo.IBookManager asInterface(android. os.IBinder obj) { 
     if ((obj == null)) { 
         return null; 
     }
     android.os.IInterface iin = obj.queryLocalInterface(DESCRIPT OR);
     if (((iin != null) && (iin instanceof com.lvr.aidldemo.IBook Manager))) { 
         return ((com.lvr.aidldemo.IBookManager) iin); 
     }
     return new com.lvr.aidldemo.IBookManager.Stub.Proxy(obj); 
   }

先通過(guò) queryLocalInterface(DESCRIPTOR);查找到對(duì)應(yīng)的IInterface對(duì)象,然后 判斷對(duì)象的類型,如果是同一個(gè)進(jìn)程調(diào)用則返回IBookManager對(duì)象,由于是跨進(jìn) 程調(diào)用則返回Proxy對(duì)象,即Binder類的代理對(duì)象。

②.調(diào)用服務(wù)端方法
獲得了Binder類的代理對(duì)象,并且通過(guò)代理對(duì)象獲得了IInterface對(duì)象,那么就可以 調(diào)用接口的具體實(shí)現(xiàn)方法了,來(lái)實(shí)現(xiàn)調(diào)用服務(wù)端方法的目的。 以addBook方法為例,調(diào)用該方法后,客戶端線程掛起,等待喚醒:

  @Override public void addBook(com.lvr.aidldemo.Book book) th rows android.os.RemoteException 
  { 
      .......... 
      //第一個(gè)參數(shù):識(shí)別調(diào)用哪一個(gè)方法的ID 
     //第二個(gè)參數(shù):Book的序列化傳入數(shù)據(jù) 
     //第三個(gè)參數(shù):調(diào)用方法后返回的數(shù)據(jù) //最后一個(gè)不用管 
     mRemote.transact(Stub.TRANSACTION_addBook, _data, _reply , 0); 
     _reply.readException(); 
     }
     .......... 
  }

省略部分主要完成對(duì)添加的Book對(duì)象進(jìn)行序列化工作,然后調(diào)用 transact 方 法。

Proxy對(duì)象中的transact調(diào)用發(fā)生后,會(huì)引起系統(tǒng)的注意,系統(tǒng)意識(shí)到Proxy對(duì)象想 找它的真身Binder對(duì)象(系統(tǒng)其實(shí)一直存著B(niǎo)inder和Proxy的對(duì)應(yīng)關(guān)系)。于是系統(tǒng) 將這個(gè)請(qǐng)求中的數(shù)據(jù)轉(zhuǎn)發(fā)給Binder對(duì)象,Binder對(duì)象將會(huì)在onTransact中收到Proxy 對(duì)象傳來(lái)的數(shù)據(jù),于是它從data中取出客戶端進(jìn)程傳來(lái)的數(shù)據(jù),又根據(jù)第一個(gè)參數(shù) 確定想讓它執(zhí)行添加書(shū)本操作,于是它就執(zhí)行了響應(yīng)操作,并把結(jié)果寫(xiě)回reply。代 碼概略如下:

  case TRANSACTION_addBook: { 
      data.enforceInterface(DESCRIPTOR); 
      com.lvr.aidldemo.Book _arg0; 
      if ((0 != data.readInt())) { 
          _arg0 = com.lvr.aidldemo.Book.CREATOR.createFromParcel(d ata);
      } else { 
          _arg0 = null; 
      }
     //這里調(diào)用服務(wù)端實(shí)現(xiàn)的addBook方法 
     this.addBook(_arg0); 
     reply.writeNoException(); 
     return true; 
  }

然后在 transact 方法獲得 _reply 并返回結(jié)果,本例中的addList方法沒(méi)有返回 值。

客戶端線程被喚醒。因此調(diào)用服務(wù)端方法時(shí),應(yīng)開(kāi)啟子線程,防止UI線程堵塞,導(dǎo) 致ANR。
順手留下GitHub鏈接,需要獲取相關(guān)面試等內(nèi)容的可以自己去找
https://github.com/xiangjiana/Android-MS
(VX:mm14525201314)

PDF和源碼獲取

談?wù)凙ndroid Binder機(jī)制及AIDL使用


網(wǎng)站欄目:談?wù)凙ndroidBinder機(jī)制及AIDL使用
網(wǎng)站網(wǎng)址:http://weahome.cn/article/ieeosh.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部