在上一篇文章——借助 AIDL 理解 Android Binder 機(jī)制——Binder 來(lái)龍去脈中我們已經(jīng)分析了使用 Binder 機(jī)制的原因以及分析了 Binder 機(jī)制墅冷,本章我們將繼續(xù)從 AIDL 的使用過(guò)程體驗(yàn) Binder 在應(yīng)用層的使用和原理糙麦。
AIDL 使用步驟
1.創(chuàng)建 UserManager.aidl 接口文件茉盏,聲明作為 Server 端的遠(yuǎn)程 Service 具有哪些能力
UserManager.aidl:
package com.me.guanpj.binder;
import com.me.guanpj.binder.User;
// Declare any non-default types here with import statements
interface UserManager {
void addUser(in User user);
List<User> getUserList();
}
對(duì)于對(duì)象引用揪荣,還需要引入實(shí)體類(lèi)
User.aidl:
// User.aidl
package com.me.guanpj.binder;
// Declare any non-default types here with import statements
parcelable User;
跨進(jìn)程傳輸對(duì)象必須實(shí)現(xiàn) Parcelable 接口
User.java
public class User implements Parcelable {
public int id;
public String name;
public User() {}
public User(int id, String name) {
this.id = id;
this.name = name;
}
protected User(Parcel in) {
id = in.readInt();
name = in.readString();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(name);
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<User> CREATOR = new Creator<User>() {
@Override
public User createFromParcel(Parcel in) {
return new User(in);
}
@Override
public User[] newArray(int size) {
return new User[size];
}
};
}
生成的 UserManager 類(lèi)如下:
UserManager.java:
package com.me.guanpj.binder;
// Declare any non-default types here with import statements
public interface UserManager extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.me.guanpj.binder.UserManager
{
private static final java.lang.String DESCRIPTOR = "com.me.guanpj.binder.UserManager";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.me.guanpj.binder.UserManager interface,
* generating a proxy if needed.
*/
public static com.me.guanpj.binder.UserManager asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.me.guanpj.binder.UserManager))) {
return ((com.me.guanpj.binder.UserManager)iin);
}
return new com.me.guanpj.binder.UserManager.Stub.Proxy(obj);
}
@Override public android.os.IBinder asBinder()
{
return this;
}
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
java.lang.String descriptor = DESCRIPTOR;
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(descriptor);
return true;
}
case TRANSACTION_addUser:
{
data.enforceInterface(descriptor);
com.me.guanpj.binder.User _arg0;
if ((0!=data.readInt())) {
_arg0 = com.me.guanpj.binder.User.CREATOR.createFromParcel(data);
}
else {
_arg0 = null;
}
this.addUser(_arg0);
reply.writeNoException();
return true;
}
case TRANSACTION_getUserList:
{
data.enforceInterface(descriptor);
java.util.List<com.me.guanpj.binder.User> _result = this.getUserList();
reply.writeNoException();
reply.writeTypedList(_result);
return true;
}
default:
{
return super.onTransact(code, data, reply, flags);
}
}
}
private static class Proxy implements com.me.guanpj.binder.UserManager
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
@Override public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
@Override public void addUser(com.me.guanpj.binder.User user) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
if ((user!=null)) {
_data.writeInt(1);
user.writeToParcel(_data, 0);
}
else {
_data.writeInt(0);
}
mRemote.transact(Stub.TRANSACTION_addUser, _data, _reply, 0);
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
@Override public java.util.List<com.me.guanpj.binder.User> getUserList() throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
java.util.List<com.me.guanpj.binder.User> _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getUserList, _data, _reply, 0);
_reply.readException();
_result = _reply.createTypedArrayList(com.me.guanpj.binder.User.CREATOR);
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_addUser = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_getUserList = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
}
public void addUser(com.me.guanpj.binder.User user) throws android.os.RemoteException;
public java.util.List<com.me.guanpj.binder.User> getUserList() throws android.os.RemoteException;
}
3.創(chuàng)建 Service,實(shí)現(xiàn) UserManager.Stub 類(lèi)并將該實(shí)現(xiàn)類(lèi)的實(shí)例在 onBind 方法返回
MyService.java:
public class MyService extends Service {
class UserManagerNative extends UserManager.Stub {
List<User> users = new ArrayList<>();
@Override
public void addUser(User user) {
Log.e("gpj", "進(jìn)程:" + Utils.getProcessName(getApplicationContext())
+ "懈息,線程:" + Thread.currentThread().getName() + "————" + "Server 執(zhí)行 addUser");
users.add(user);
}
@Override
public List<User> getUserList() {
Log.e("gpj", "進(jìn)程:" + Utils.getProcessName(getApplicationContext())
+ "抵屿,線程:" + Thread.currentThread().getName() + "————" + "Server 執(zhí)行 getUserList");
return users;
}
}
private UserManagerNative mUserManagerNative = new UserManagerNative();
@Override
public IBinder onBind(Intent intent) {
Log.e("gpj", "進(jìn)程:" + Utils.getProcessName(getApplicationContext())
+ ",線程:" + Thread.currentThread().getName() + "————" + "Server onBind");
return mUserManagerNative;
}
}
4.在作為 Client 端的 Activity 中奋构,綁定遠(yuǎn)程 Service 并得到 Server 的代理對(duì)象
5.通過(guò) Server 代理對(duì)象壳影,調(diào)用 Server 的具體方法
MainActivity.java:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Button btnBind;
Button btnAddUser;
Button btnGetSize;
TextView tvResult;
IUserManager mUserManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnBind = (Button) findViewById(R.id.btn_bind);
btnAddUser = (Button) findViewById(R.id.btn_add_user);
btnGetSize = (Button) findViewById(R.id.btn_get_size);
btnBind.setOnClickListener(this);
btnAddUser.setOnClickListener(this);
btnGetSize.setOnClickListener(this);
tvResult = (TextView) findViewById(R.id.txt_result);
}
@Override
protected void onDestroy() {
unbindService(mConn);
super.onDestroy();
}
private ServiceConnection mConn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.e("gpj", "進(jìn)程:" + Utils.getProcessName(getApplicationContext())
+ ",線程:" + Thread.currentThread().getName() + "————" + "Client onServiceConnected");
mUserManager = UserManagerImpl.asInterface(service);
try {
//注冊(cè)遠(yuǎn)程服務(wù)死亡通知
service.linkToDeath(mDeathRecipient, 0);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
mUserManager = null;
}
};
private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
@Override
public void binderDied() {
if (mUserManager != null) {
mUserManager.asBinder().unlinkToDeath(mDeathRecipient, 0);
mUserManager = null;
//重新綁定服務(wù)
bindService();
}
}
};
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_bind:
bindService();
break;
case R.id.btn_add_user:
if (null != mUserManager) {
try {
Log.e("gpj", "線程:" + Thread.currentThread().getName() + "————" +"Client 調(diào)用 addUser");
mUserManager.addUser(new User(111, "gpj"));
} catch (RemoteException e) {
e.printStackTrace();
}
} else {
Toast.makeText(MainActivity.this, "先綁定 Service 才能調(diào)用方法", Toast.LENGTH_LONG).show();
}
break;
case R.id.btn_get_size:
if (null != mUserManager) {
try {
Log.e("gpj", "線程:" + Thread.currentThread().getName() + "————" +"Client 調(diào)用 getUserList");
List<User> userList = mUserManager.getUserList();
tvResult.setText("getUserList size:" + userList.size());
Log.e("gpj", "線程:" + Thread.currentThread().getName() + "————" +"調(diào)用結(jié)果:" + userList.size());
} catch (RemoteException e) {
e.printStackTrace();
}
} else {
Toast.makeText(MainActivity.this, "先綁定 Service 才能調(diào)用方法", Toast.LENGTH_LONG).show();
}
break;
default:
}
}
private void bindService() {
Intent intent = new Intent();
intent.setAction("com.me.guanpj.binder");
intent.setComponent(new ComponentName("com.me.guanpj.binder", "com.me.guanpj.binder.MyService"));
Log.e("gpj", "進(jìn)程:" + Utils.getProcessName(getApplicationContext())
+ "弥臼,線程:" + Thread.currentThread().getName() + "————" + "開(kāi)始綁定服務(wù)");
bindService(intent, mConn, Context.BIND_AUTO_CREATE);
}
}
AIDL 的實(shí)現(xiàn)過(guò)程
為了便于理解宴咧,這里用一個(gè) Demo 來(lái)展示 AIDL 的實(shí)現(xiàn)過(guò)程:Activity 作為 Client 與作為 Server 端的遠(yuǎn)程 Service 實(shí)現(xiàn)數(shù)據(jù)交互,在綁定遠(yuǎn)程 Service 之后径缅,點(diǎn)擊 AddUser 后 Service 會(huì)將 Client 端傳進(jìn)來(lái)的 User 對(duì)象加入列表中掺栅,點(diǎn)擊 GetSize 后遠(yuǎn)程 Service 將會(huì)把列表的長(zhǎng)度返回給客戶端。建議在繼續(xù)閱讀之前先查看或者運(yùn)行一下項(xiàng)目源碼:
在項(xiàng)目中創(chuàng)建 UserManager.aidl 文件之后纳猪,系統(tǒng)會(huì)自動(dòng)在 build 目錄生成一個(gè)與 UserManager.java 接口類(lèi)氧卧,它繼承了 IInterface 接口,UserManager 接口只有一個(gè)靜態(tài)抽象類(lèi) Stub氏堤,Stub 繼承自 Binder 并實(shí)現(xiàn)了 UserManager 接口沙绝,Stub 里面也有一個(gè)靜態(tài)內(nèi)部類(lèi) Proxy,Proxy 也繼承了 UserManager(是不是有點(diǎn)亂鼠锈,亂就對(duì)了闪檬,我也很亂)。
如此嵌套是為了避免有多個(gè) .aidl 文件的時(shí)候自動(dòng)生成這些類(lèi)的類(lèi)名不會(huì)重復(fù)购笆,為了提高代碼可讀性粗悯,我們將生成的 UserManager 和 Stub 類(lèi) 拆解并重新命名成了 IUserManager 類(lèi)和 UserManagerImpl 類(lèi)并在關(guān)鍵方法上添加了注釋或者 Log。
IUserManager.java:
public interface IUserManager extends android.os.IInterface {
//唯一性標(biāo)識(shí)
static final java.lang.String DESCRIPTOR = "com.me.guanpj.binder.IUserManager";
//方法標(biāo)識(shí)同欠,用十六進(jìn)制表示
int TRANSACTION_addUser = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
int TRANSACTION_getUserList = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
//Server 具有的能力
void addUser(User user) throws android.os.RemoteException;
List<User> getUserList() throws android.os.RemoteException;
}
UserManagerImpl.java:
public abstract class UserManagerImpl extends Binder implements IUserManager {
/**
* Construct the mLocalStub at attach it to the interface.
*/
public UserManagerImpl() {
this.attachInterface(this, DESCRIPTOR);
}
/**
* 根據(jù) Binder 本地對(duì)象或者代理對(duì)象返回 IUserManager 接口
*/
public static IUserManager asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
//查找本地對(duì)象
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof IUserManager))) {
Log.e("gpj", "線程:" + Thread.currentThread().getName() + "————" + "返回本地對(duì)象");
return ((IUserManager) iin);
}
Log.e("gpj", "線程:" + Thread.currentThread().getName() + "————" + "返回代理對(duì)象");
return new UserManagerImpl.Proxy(obj);
}
@Override
public android.os.IBinder asBinder() {
return this;
}
@Override
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_addUser: {
Log.e("gpj", "線程:" + Thread.currentThread().getName() + "————" + "本地對(duì)象通過(guò) Binder 執(zhí)行 addUser");
data.enforceInterface(DESCRIPTOR);
User arg0;
if ((0 != data.readInt())) {
//取出客戶端傳遞過(guò)來(lái)的數(shù)據(jù)
arg0 = User.CREATOR.createFromParcel(data);
} else {
arg0 = null;
}
//調(diào)用 Binder 本地對(duì)象
this.addUser(arg0);
reply.writeNoException();
return true;
}
case TRANSACTION_getUserList: {
Log.e("gpj", "線程:" + Thread.currentThread().getName() + "————" + "本地對(duì)象通過(guò) Binder 執(zhí)行 getUserList");
data.enforceInterface(DESCRIPTOR);
//調(diào)用 Binder 本地對(duì)象
List<User> result = this.getUserList();
reply.writeNoException();
//將結(jié)果返回給客戶端
reply.writeTypedList(result);
return true;
}
default:
break;
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements IUserManager {
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote) {
mRemote = remote;
}
@Override
public android.os.IBinder asBinder() {
return mRemote;
}
public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}
@Override
public void addUser(User user) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
if (user != null) {
_data.writeInt(1);
user.writeToParcel(_data, 0);
} else {
_data.writeInt(0);
}
Log.e("gpj", "線程:" + Thread.currentThread().getName() + "————" + "代理對(duì)象通過(guò) Binder 調(diào)用 addUser");
mRemote.transact(UserManagerImpl.TRANSACTION_addUser, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public List<User> getUserList() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
List<User> _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
Log.e("gpj", "線程:" + Thread.currentThread().getName() + "————" + "代理對(duì)象通過(guò) Binder 調(diào)用 getUserList");
mRemote.transact(UserManagerImpl.TRANSACTION_getUserList, _data, _reply, 0);
_reply.readException();
_result = _reply.createTypedArrayList(User.CREATOR);
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
}
再進(jìn)行分析之前样傍,先了解幾個(gè)概念:
- IInterface : 從注釋中的說(shuō)明看出,聲明(自動(dòng)生成或者手動(dòng)創(chuàng)建)AIDL 性質(zhì)的接口必須繼承這個(gè)接口铺遂,這個(gè)接口只有一個(gè) IBinder asBinder() 方法衫哥,實(shí)現(xiàn)它的類(lèi)代表它能夠進(jìn)程跨進(jìn)程傳輸( Binder 本地對(duì)象)或者持有能夠進(jìn)程跨進(jìn)程傳輸?shù)膶?duì)象的引用(Binder 代理對(duì)象)。
- IUserManager : 它同樣是一個(gè)接口襟锐,它繼承了 IInterface 類(lèi)炕檩,并聲明了 Server 承諾給 Client 的能力
- IBinder : 它也是一個(gè)接口,實(shí)現(xiàn)這個(gè)接口的對(duì)象就具有了跨進(jìn)程傳輸?shù)哪芰Π聘诳邕M(jìn)程數(shù)據(jù)流經(jīng)驅(qū)動(dòng)的時(shí)候笛质,驅(qū)動(dòng)會(huì)識(shí)別IBinder類(lèi)型的數(shù)據(jù),從而自動(dòng)完成不同進(jìn)程Binder本地對(duì)象以及Binder代理對(duì)象的轉(zhuǎn)換捞蚂。
- Binder : 代表 Binder 本地對(duì)象妇押,BinderProxy 類(lèi)是它的內(nèi)部類(lèi),是 Server 端 Binder 對(duì)象的本地代理姓迅,它們都繼承了 IBinder 接口敲霍,因此都能跨進(jìn)程進(jìn)行傳輸,Binder 驅(qū)動(dòng)在跨進(jìn)程傳輸?shù)臅r(shí)候會(huì)將這兩個(gè)對(duì)象自動(dòng)進(jìn)行轉(zhuǎn)換丁存。
- UserManagerImpl : 它繼承了 Binder 并實(shí)現(xiàn)了 IInterface 接口肩杈,說(shuō)明它是 Server 端的 Binder 本地對(duì)象,并擁有 Server 承諾給 Client 的能力解寝。
先從 MainActivity 中綁定服務(wù)后的回調(diào)方法著手:
private ServiceConnection mConn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mUserManager = UserManagerImpl.asInterface(service);
try {
//注冊(cè)遠(yuǎn)程服務(wù)死亡通知
service.linkToDeath(mDeathRecipient, 0);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
mUserManager = null;
}
};
onServiceConnected 的參數(shù)中扩然,第一個(gè)是 Service 組件的名字,表示哪個(gè)服務(wù)被啟動(dòng)了聋伦,重點(diǎn)是類(lèi)型為 IBinder 的第二個(gè)參數(shù)夫偶,在 Service.java 中的 onBind 方法中,已經(jīng)把 Server 端的本地對(duì)象 UserManagerNative 實(shí)例返回給 Binder 驅(qū)動(dòng)了:
private UserManagerNative mUserManagerNative = new UserManagerNative();
@Override
public IBinder onBind(Intent intent) {
return mUserManagerNative;
}
因此觉增,當(dāng)該服務(wù)被綁定的時(shí)候兵拢,Binder 驅(qū)動(dòng)會(huì)為根據(jù)該服務(wù)所在的進(jìn)程決定
是返回本地對(duì)象還是代理對(duì)象給客戶端,當(dāng) Service 與 MainActivity 位于同一個(gè)進(jìn)程當(dāng)中的時(shí)候逾礁,onServiceConnected 返回 Binder 本地對(duì)象——即 UserManagerNative 對(duì)象給客戶端说铃;當(dāng) Service 運(yùn)行在不同進(jìn)程中的時(shí)候,返回的是 BinderProxy 對(duì)象嘹履。
接著腻扇,在將這個(gè) IBinder 對(duì)象傳給 UserManagerImpl 的 asInterface 方法并返回 IUserManager 接口,asInterface 方法實(shí)現(xiàn)如下:
/**
* 根據(jù) Binder 本地對(duì)象或者代理對(duì)象返回 IUserManager 接口
*/
public static IUserManager asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
//查找本地對(duì)象
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof IUserManager))) {
return ((IUserManager) iin);
}
return new UserManagerImpl.Proxy(obj);
}
首先植捎,會(huì)根據(jù) DESCRIPTOR 調(diào)用 IBinder 對(duì)象的 queryLocalInterface 方法衙解,那么就得看 IBinder 的實(shí)現(xiàn)類(lèi)怎么處理這個(gè)方法了:
在 Binder 類(lèi)中的實(shí)現(xiàn):
public @Nullable IInterface queryLocalInterface(@NonNull String descriptor) {
//判斷 mDescriptor 跟參數(shù) DESCRIPTOR 相同,返回 mOwner
if (mDescriptor != null && mDescriptor.equals(descriptor)) {
return mOwner;
}
return null;
}
那么這個(gè) mOwner 和 mDescriptor 又是什么時(shí)候被賦值的呢焰枢?答案在 Binder 的子類(lèi) UserManagerImpl 的構(gòu)造方法里面蚓峦,:
public UserManagerImpl() {
//將 UserManagerImpl 和 DESCRIPTOR 注入到父類(lèi)(Binder)
this.attachInterface(this, DESCRIPTOR);
}
在 Binder$BinderProxy 類(lèi)中的實(shí)現(xiàn):
BinderProxy 并不是 Binder 本地對(duì)象,而是 Binder 的本地代理济锄,因此 queryLocalInterface 返回的是 null:
public IInterface queryLocalInterface(String descriptor) {
return null;
}
綜上兩點(diǎn)可以看出暑椰,如果 obj.queryLocalInterface(DESCRIPTOR) 方法存在返回值并且是 IUserManager 類(lèi)型的對(duì)象荐绝,那么它就是 Binder 本地對(duì)象一汽,將它直接返回給 Client 調(diào)用;否則,使用 UserManagerImpl$Proxy 類(lèi)將其進(jìn)行包裝后再返回召夹,Proxy 類(lèi)也實(shí)現(xiàn)了 IUserManager 接口岩喷,因此,在 Client 眼中监憎,它也具有 Server 承諾給 Client 的能力纱意,那么,經(jīng)過(guò)包裝后的對(duì)象怎么和 Server 進(jìn)行交互呢鲸阔?
首先偷霉,它會(huì)把 BinderProxy 對(duì)象保存下來(lái):
Proxy(android.os.IBinder remote) {
mRemote = remote;
}
然后,實(shí)現(xiàn) IUserManager 的方法:
@Override
public void addUser(User user) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
if (user != null) {
_data.writeInt(1);
//將 user 對(duì)象的值寫(xiě)入 _data
user.writeToParcel(_data, 0);
} else {
_data.writeInt(0);
}
//通過(guò) transact 跟 Server 交互
mRemote.transact(UserManagerImpl.TRANSACTION_addUser, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public List<User> getUserList() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
List<User> _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
//通過(guò) transact 跟 Server 交互
mRemote.transact(UserManagerImpl.TRANSACTION_getUserList, _data, _reply, 0);
_reply.readException();
//獲取 Server 的返回值并進(jìn)程轉(zhuǎn)換
_result = _reply.createTypedArrayList(User.CREATOR);
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
可以看到褐筛,不管什么方法类少,都是是將服務(wù)端的方法代號(hào)、處理過(guò)的參數(shù)和接收返回值的對(duì)象等通過(guò) mRemote.transact 方法 Server 進(jìn)行交互渔扎,mRemote 是 BinderProxy 類(lèi)型硫狞,在 BinderProxy 類(lèi)中,最終調(diào)用的是 transactNative 方法:
public native boolean transactNative(int code, Parcel data, Parcel reply, int flags) throws RemoteException;
它的最終實(shí)現(xiàn)在 Native 層進(jìn)行赞警,Binder 驅(qū)動(dòng)會(huì)通過(guò) ioctl 系統(tǒng)調(diào)用喚醒 Server 進(jìn)程妓忍,并調(diào)用 Server 本地對(duì)象的 onTransact 函數(shù):
@Override
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_addUser: {
data.enforceInterface(DESCRIPTOR);
User arg0;
if ((0 != data.readInt())) {
//取出客戶端傳遞過(guò)來(lái)的數(shù)據(jù)
arg0 = User.CREATOR.createFromParcel(data);
} else {
arg0 = null;
}
//調(diào)用 Binder 本地對(duì)象
this.addUser(arg0);
reply.writeNoException();
return true;
}
case TRANSACTION_getUserList: {
data.enforceInterface(DESCRIPTOR);
//調(diào)用 Binder 本地對(duì)象
List<User> result = this.getUserList();
reply.writeNoException();
//將結(jié)果返回給客戶端
reply.writeTypedList(result);
return true;
}
default:
break;
}
return super.onTransact(code, data, reply, flags);
}
在 Server 進(jìn)程中,onTransact 會(huì)根據(jù) Client 傳過(guò)來(lái)的方法代號(hào)決定調(diào)用哪個(gè)方法愧旦,得到結(jié)果后又會(huì)通過(guò) Binder 驅(qū)動(dòng)返回給 Client世剖。
總結(jié)
回溯到 onServiceConnected 回調(diào)方法,待服務(wù)連接成功后笤虫,Client 就需要跟 Server 進(jìn)行交互了旁瘫,如果 Server 跟 Client 在同一個(gè)進(jìn)程中,Client 可以直接調(diào)用 Server 的本地對(duì)象 琼蚯,當(dāng)它們不在同一個(gè)進(jìn)程中的時(shí)候酬凳,Binder 驅(qū)動(dòng)會(huì)自動(dòng)將 Server 的本地對(duì)象轉(zhuǎn)換成 BinderProxy 代理對(duì)象,經(jīng)過(guò)一層包裝之后遭庶,返回一個(gè)新的代理對(duì)象給 Client宁仔。這樣,整個(gè) IPC 的過(guò)程就完成了峦睡。
參考文章
寫(xiě)給 Android 應(yīng)用工程師的 Binder 原理剖析
文章中的代碼已經(jīng)上傳至我的 Github翎苫,如果你對(duì)文章內(nèi)容有疑問(wèn)或者有不同的意見(jiàn),歡迎留言榨了,我們一同探討煎谍。