主目录见:Android高级进阶知识(这是总目录索引)
为什么要突然讲这一章呢?因为后面要开始讲Framework的代码,有太多应用到AIDL机制了。所以想在这里给大家介绍清楚这个,但是我不能保证我讲的很清楚,不过希望大家自己能学懂,为后面的打下基础,下面可能有块硬骨头要啃,我们上图休息一下:
一.目标
今天讲这个的原因前面已经讲了,我们今天的目标就是搞懂AIDL的生成文件,然后明白调用过程,所以目标如下:
1.清楚AIDL生成文件的代码结构;
2.从bindService的过程来了解调用过程。
二.AIDL生成文件分析
为了分析AIDL生成文件,我们首先得来看看AIDL要怎么应用,就是怎么个写法,我们这里还是以[LRouter]项目中的跨进程部分来讲。首先我们来看看我们是怎么写的:
1.首先要编写aidl文件用于自动生成代码
package com.lenovohit.lrouter_api;
import com.lenovohit.lrouter_api.core.LRouterRequest;
interface IRemoteRouterAIDL {
boolean stopRouter(String processName);
boolean checkIfLocalRouterAsync(String processName,in LRouterRequest routerRequset);
String navigation(String processName,in LRouterRequest routerRequest);
}
2.接着我们要编写一个服务,然后把Stub绑定到这个服务上
public final class RemoteRouterService extends Service {
private static final String TAG = "RemoteRouterService";
public static final String PROCESS_NAME = "process_name";
@Override
public void onCreate() {
super.onCreate();
if (!(getApplication() instanceof LRouterAppcation)) {
throw new LRException("请检查你的AndroidManifest.xml和applicaiton是LRouterApplicaiton");
}
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_NOT_STICKY;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
.....
return mStub;
}
IRemoteRouterAIDL.Stub mStub = new IRemoteRouterAIDL.Stub() {
//省略实现的方法
......
};
}
3.编写ServiceConnection在onServiceConnected得到远程服务代理对象
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mRemoteRouterAIDL = IRemoteRouterAIDL.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
mRemoteRouterAIDL = null;
}
};
4.最后绑定服务
Intent bindRemoteRouterServiceIntent = new Intent(mLRouterAppcation,RemoteRouterService.class);
bindRemoteRouterServiceIntent.putExtra(RemoteRouterService.PROCESS_NAME,processName);
mLRouterAppcation.bindService(bindRemoteRouterServiceIntent,mServiceConnection, BIND_AUTO_CREATE);
到这里我们的使用就已经完成了,当然有些小细节没有说,不过没关系,这篇不是为了讲具体的使用方法的,大家应该要已经知道怎么使用了。
1.bindService
要想把这一整套流程都讲清楚就得从绑定服务开始,这里不像系统服务的启动和注册需要ServiceManager
管理。这里我们应用的服务直接从bindService开始讲就可以。我们看到前面绑定服务的时候是Application
里面的bindService()方法,但是查找的时候会发现这里面没有这个方法,而且在基类ContextWrapper
中:
@Override
public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
return mBase.bindService(service, conn, flags);
}
这里的mBase是个ContextImpl
对象,于是调用ContextImpl
的bindService方法:
@Override
public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
warnIfCallingFromSystemProcess();
return bindServiceCommon(service, conn, flags, mMainThread.getHandler(),
Process.myUserHandle());
}
我们看到这里调用了bindServiceCommon()方法:
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler
handler, UserHandle user) {
IServiceConnection sd;
if (conn == null) {
throw new IllegalArgumentException("connection is null");
}
if (mPackageInfo != null) {
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
} else {
throw new RuntimeException("Not supported in system context");
}
validateServiceIntent(service);
try {
....
int res = ActivityManagerNative.getDefault().bindService(
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, getOpPackageName(), user.getIdentifier());
.....
return res != 0;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
前面的mMainThread是一个ActivityThread
对象,通过他的getHandler()方法得到一个Handler对象,有了这个Handler
对象,就可以把消息发送到ActivityThread
所在线程的消息队列中了。然后我们看到最终会把这个handler放进ServiceDispatcher
中去。这里的mPackageInfo就是我们的LoadedApk对象,所以我们看到LoadedApk
的getServiceDispatcher()方法:
public final IServiceConnection getServiceDispatcher(ServiceConnection c,
Context context, Handler handler, int flags) {
synchronized (mServices) {
LoadedApk.ServiceDispatcher sd = null;
ArrayMap map = mServices.get(context);
if (map != null) {
sd = map.get(c);
}
if (sd == null) {
sd = new ServiceDispatcher(c, context, handler, flags);
if (map == null) {
map = new ArrayMap();
mServices.put(context, map);
}
map.put(c, sd);
} else {
sd.validate(context, handler);
}
return sd.getIServiceConnection();
}
}
我们看到这里主要就是将ServiceConnection
的对象,handler等传给ServiceDispatcher对象,我们看下ServiceDispatcher
类是长啥样的:
static final class ServiceDispatcher {
private final ServiceDispatcher.InnerConnection mIServiceConnection;
private final ServiceConnection mConnection;
private final Context mContext;
private final Handler mActivityThread;
private final ServiceConnectionLeaked mLocation;
private final int mFlags;
private RuntimeException mUnbindLocation;
private boolean mForgotten;
private static class ConnectionInfo {
IBinder binder;
IBinder.DeathRecipient deathMonitor;
}
private static class InnerConnection extends IServiceConnection.Stub {
final WeakReference mDispatcher;
InnerConnection(LoadedApk.ServiceDispatcher sd) {
mDispatcher = new WeakReference(sd);
}
public void connected(ComponentName name, IBinder service) throws RemoteException {
LoadedApk.ServiceDispatcher sd = mDispatcher.get();
if (sd != null) {
sd.connected(name, service);
}
}
}
.......
ServiceDispatcher(ServiceConnection conn,
Context context, Handler activityThread, int flags) {
mIServiceConnection = new InnerConnection(this);
mConnection = conn;
mContext = context;
mActivityThread = activityThread;
mLocation = new ServiceConnectionLeaked(null);
mLocation.fillInStackTrace();
mFlags = flags;
}
.......
}
我们看到ServiceDispatcher
内部还创建了一个InnerConnection
对象,这是一个Binder对象,一会是要传递给ActivityManagerService
的,ActivityManagerServic
后续就是要通过这个Binder对象和ServiceConnection通信的。
函数getServiceDispatcher最后就是返回了一个InnerConnection对象给ContextImpl.bindService函数。回到ContextImpl.bindService函数中,它接着就要调用ActivityManagerService
的远程接口来进一步处理了。接着我们程序会调用 ActivityManagerNative.getDefault().bindService()方法来访问远程服务:
public int bindService(IApplicationThread caller, IBinder token,
Intent service, String resolvedType, IServiceConnection connection,
int flags, String callingPackage, int userId) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
data.writeStrongBinder(token);
service.writeToParcel(data, 0);
data.writeString(resolvedType);
data.writeStrongBinder(connection.asBinder());
data.writeInt(flags);
data.writeString(callingPackage);
data.writeInt(userId);
mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0);
reply.readException();
int res = reply.readInt();
data.recycle();
reply.recycle();
return res;
}
这个函数通过Binder驱动程序就进入到ActivityManagerService
的bindService函数去了。我们紧接着看ActivityManagerService.bindService方法:
public int bindService(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, IServiceConnection connection, int flags, String callingPackage,
int userId) throws TransactionTooLargeException {
......
synchronized(this) {
return mServices.bindServiceLocked(caller, token, service,
resolvedType, connection, flags, callingPackage, userId);
}
}
我们看到这个方法最后直接调用了mServices.bindServiceLocked()方法,这个mServices就是ActiveServices类:
int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, final IServiceConnection connection, int flags,
String callingPackage, final int userId) throws TransactionTooLargeException {
.......
final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
......
ActivityRecord activity = null;
if (token != null) {
activity = ActivityRecord.isInStackLocked(token);
.......
}
int clientLabel = 0;
PendingIntent clientIntent = null;
final boolean isCallerSystem = callerApp.info.uid == Process.SYSTEM_UID;
.....
ServiceLookupResult res =
retrieveServiceLocked(service, resolvedType, callingPackage, Binder.getCallingPid(),
Binder.getCallingUid(), userId, true, callerFg, isBindExternal);
.....
AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
ConnectionRecord c = new ConnectionRecord(b, activity,
connection, flags, clientLabel, clientIntent);
IBinder binder = connection.asBinder();
ArrayList clist = s.connections.get(binder);
if (clist == null) {
clist = new ArrayList();
s.connections.put(binder, clist);
}
clist.add(c);
b.connections.add(c);
if (activity != null) {
if (activity.connections == null) {
activity.connections = new HashSet();
}
activity.connections.add(c);
}
b.client.connections.add(c);
if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
b.client.hasAboveClient = true;
}
if ((c.flags&Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
s.whitelistManager = true;
}
if (s.app != null) {
updateServiceClientActivitiesLocked(s.app, c, true);
}
clist = mServiceConnections.get(binder);
if (clist == null) {
clist = new ArrayList();
mServiceConnections.put(binder, clist);
}
clist.add(c);
if ((flags&Context.BIND_AUTO_CREATE) != 0) {
s.lastActivity = SystemClock.uptimeMillis();
if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
permissionsReviewRequired) != null) {
return 0;
}
}
.........
return 1;
}
首先传进来的token就是Application在AcitivityManagerService中的令牌,通过token就可以将对应的ActivityRecord取回。
接着通过retrieveServiceLocked函数,得到一个ServiceRecord,这个ServiceReocrd
描述的是一个Service对象,这个service这里就是说的我们的RemoteRouterService
对象。这是根据传进来的参数service的内容获得的。我们前面说的绑定服务那里可以看出:
Intent bindRemoteRouterServiceIntent = new Intent(mLRouterAppcation,RemoteRouterService.class);
bindRemoteRouterServiceIntent.putExtra(RemoteRouterService.PROCESS_NAME,processName);
mLRouterAppcation.bindService(bindRemoteRouterServiceIntent,mServiceConnection, BIND_AUTO_CREATE);
这里的参数service,就是上面的bindIntent了,它里面设置了RemoteRouterService
类的信息(RemoteRouterService.class),因此,这里可以通过它来把RemoteRouterService
的信息取出来,并且保存在ServiceRecord对象s中。
接下来,就是把传进来的参数connection封装成一个ConnectionRecord
对象。注意,这里的参数connection是一个Binder对象,它的类型是LoadedApk.ServiceDispatcher.InnerConnection,后续ActivityManagerService
就是要通过它来告诉Application,RemoteRouterService
已经启动起来了,因此,这里要把这个ConnectionRecord
变量c保存下来,它保在在好几个地方,都是为了后面要用时方便地取回来的,这里就不仔细去研究了,只要知道ActivityManagerService
要使用它时就可以方便地把它取出来就可以了,具体后面我们再分析。
最后,传进来的参数flags的位Context.BIND_AUTO_CREATE为1。最后程序会调用ActiveServices
类的bringUpServiceLocked继续处理:
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
.......
final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
final String procName = r.processName;
ProcessRecord app;
if (!isolated) {
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
.....
if (app != null && app.thread != null) {
try {
app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
realStartServiceLocked(r, app, execInFg);
return null;
} catch (TransactionTooLargeException e) {
throw e;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting service " + r.shortName, e);
}
}
} else {
app = r.isolatedProc;
}
if (app == null && !permissionsReviewRequired) {
if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
"service", r.name, false, isolated, false)) == null) {
.......
return msg;
}
if (isolated) {
r.isolatedProc = app;
}
}
.......
return null;
}
我们如果在AndroidManifest.xml中有设置process的话,那么这里procName就会是我们设置的字符串。如果没有的话就会默认是包名。配合这uid会获取到ProcessRecord
对象。如果这个ProcessRecord为null的话就是说还没有这个进程存在,所以后面会调用startProcessLocked()方法来创建一个新的进程然后在这个进程里面把这个服务启动。不然就调用realStartServiceLocked()方法在应用程序进程中启动应用Service,我们来看下这个方法:
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
......
r.app = app;
r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
final boolean newService = app.services.add(r);
.......
boolean created = false;
try {
......
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
.....
} catch (DeadObjectException e) {
.....
} finally {
.....
}
.....
requestServiceBindingsLocked(r, execInFg);
.....
}
这个方法里面有两个重要的方法scheduleCreateService和requestServiceBindingsLocked,这两个方法分别是启动服务和绑定服务(会调用Service的onBind方法)操作。
2.scheduleCreateService启动服务
我们看到上面程序调用了 app.thread的scheduleCreateService方法,这里的app.thread是一个bind远程对象,类型为ApplicationThreadProxy
,每一个Android应用程序进程里面都有一个ActivtyThread
对象和一个ApplicationThread
对象,其中是ApplicationThread对象是ActivityThread对象的一个成员变量,是ActivityThread
与ActivityManagerService
之间用来执行进程间通信的。所以我们看看这个ApplicationThreadProxy(这个类在ApplicationThreadNative里面)的scheduleCreateService干了什么:
public final void scheduleCreateService(IBinder token, ServiceInfo info,
CompatibilityInfo compatInfo, int processState) throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
data.writeStrongBinder(token);
info.writeToParcel(data, 0);
compatInfo.writeToParcel(data, 0);
data.writeInt(processState);
try {
mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,
IBinder.FLAG_ONEWAY);
} catch (TransactionTooLargeException e) {
Log.e("CREATE_SERVICE", "Binder failure starting service; service=" + info);
throw e;
}
data.recycle();
}
这里通过了Bind机制就调用到了ActivityThread的scheduleCreateService函数中去了:
public final void scheduleCreateService(IBinder token,
ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
updateProcessState(processState, false);
CreateServiceData s = new CreateServiceData();
s.token = token;
s.info = info;
s.compatInfo = compatInfo;
sendMessage(H.CREATE_SERVICE, s);
}
这里可以看到主要是发送了一个消息,消息最终会调用到这个sendMessage()方法:
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
if (DEBUG_MESSAGES) Slog.v(
TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
+ ": " + arg1 + " / " + obj);
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}
我们这个消息是发送到mH中了,这个mH又是什么呢?这里是H
类,我们看他里面的handleMessage()方法:
public void handleMessage(Message msg) {
switch (msg.what) {
....
case CREATE_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
handleCreateService((CreateServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
......
}
}
我们看到这个主要就是调用handleCreateService()方法,这个方法就是创建的Service了:
private void handleCreateService(CreateServiceData data) {
unscheduleGcIdler();
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = (Service) cl.loadClass(data.info.name).newInstance();
} catch (Exception e) {
......
try {
......
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
Application app = packageInfo.makeApplication(false, mInstrumentation);
service.attach(context, this, data.info.name, data.token, app,
ActivityManagerNative.getDefault());
service.onCreate();
mServices.put(data.token, service);
try {
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} catch (Exception e) {
.....
}
}
我们看到这个方法用类加载器把service加载进内存,然后调用了service的onCreate()方法,到这里我们的服务已经启动起来了。我们接下来看看服务的绑定。
3.requestServiceBindingsLocked 服务的绑定
前面我们的服务已经启动且调用了Service的onCreate方法,那么接下来绑定的过程就会调用服务的onBind()方法,那么我们接下来来看绑定的方法即ActiveServices
的requestServiceBindingsLocked:
private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg)
throws TransactionTooLargeException {
for (int i=r.bindings.size()-1; i>=0; i--) {
IntentBindRecord ibr = r.bindings.valueAt(i);
if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
break;
}
}
}
private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
boolean execInFg, boolean rebind) throws TransactionTooLargeException {
........
if ((!i.requested || rebind) && i.apps.size() > 0) {
try {
.........
r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
r.app.repProcState);
........
} catch (TransactionTooLargeException e) {
.........
} catch (RemoteException e) {
.........
}
}
return true;
}
这里传进来的ServiceRecord
就是我们的RemoteRouterService服务,函数requestServiceBindingsLocked调用了requestServiceBindingLocked函数来处理绑定服务的操作,然后requestServiceBindingLocked方法会调用r.app.thread.scheduleBindService来绑定服务,跟上面的启动过程类似。我们就直接跳到ActivityThread
的handleBindService来讲解:
private void handleBindService(BindServiceData data) {
Service s = mServices.get(data.token);
.......
if (s != null) {
try {
data.intent.setExtrasClassLoader(s.getClassLoader());
data.intent.prepareToEnterProcess();
try {
if (!data.rebind) {
IBinder binder = s.onBind(data.intent);
ActivityManagerNative.getDefault().publishService(
data.token, data.intent, binder);
} else {
s.onRebind(data.intent);
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
}
ensureJitEnabled();
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
} catch (Exception e) {
.......
}
}
}
执行ActivityThread.handleCreateService函数中,已经将这个RemoteRouterService
实例保存在mServices中,因此,这里首先通过data.token值将它取回来,保存在本地变量s中,接着执行了两个操作,一个操作是调用s.onBind,即RemoteRouterService.onBind获得一个Binder对象,另一个操作就是把这个Binder对象传递给ActivityManagerService。
到这里我们Service的onCreate和onBind都已经调用完毕,onBind返回的是我们的IRemoteRouterAIDL#Stub()
,得到这个对象之后程序就调用publishService()方法,同样的,这里是调用ActivityManagerProxy
的publishService通知mLRouterAppcation(Application对象),Service已经启动完毕:
public void publishService(IBinder token,
Intent intent, IBinder service) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(token);
intent.writeToParcel(data, 0);
data.writeStrongBinder(service);
mRemote.transact(PUBLISH_SERVICE_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
reply.recycle();
}
这里通过Binder驱动程序就进入到ActivityManagerService
的publishService函数中去了:
public void publishService(IBinder token, Intent intent, IBinder service) {
// Refuse possible leaked file descriptors
if (intent != null && intent.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
synchronized(this) {
if (!(token instanceof ServiceRecord)) {
throw new IllegalArgumentException("Invalid service token");
}
mServices.publishServiceLocked((ServiceRecord)token, intent, service);
}
}
我们看到这个方法里面主要是调用了mServices即ActiveServices对象,所以我们跟进ActiveServices的publishServiceLocked()方法:
void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
final long origId = Binder.clearCallingIdentity();
try {
........
if (r != null) {
Intent.FilterComparison filter
= new Intent.FilterComparison(intent);
IntentBindRecord b = r.bindings.get(filter);
if (b != null && !b.received) {
b.binder = service;
b.requested = true;
b.received = true;
for (int conni=r.connections.size()-1; conni>=0; conni--) {
ArrayList clist = r.connections.valueAt(conni);
for (int i=0; i
在之前ActiveServices
的bindServiceLocked()方法的时候,我们已经将一个ConnectionRecord对象放进ServiceRecord.connections列表中了:
ConnectionRecord c = new ConnectionRecord(b, activity,
connection, flags, clientLabel, clientIntent);
IBinder binder = connection.asBinder();
ArrayList clist = s.connections.get(binder);
if (clist == null) {
clist = new ArrayList();
s.connections.put(binder, clist);
}
clist.add(c);
b.connections.add(c);
publishServiceLocked()里面就是将这个ConnectionRecord取出来,然后调用他的connected()方法。那么这里的ConnectionRecord的conn又是什么呢?这个是我们之前ServiceDispatcher的InnerConnection对象,因此,这里执行c.conn.connected函数后就会进入到ServiceDispatcher.InnerConnection#connected
函数中去了:
private static class InnerConnection extends IServiceConnection.Stub {
......
public void connected(ComponentName name, IBinder service) throws RemoteException {
LoadedApk.ServiceDispatcher sd = mDispatcher.get();
if (sd != null) {
sd.connected(name, service);
}
}
......
}
}
这里转发给了ServiceDispatcher的connected方法:
public void connected(ComponentName name, IBinder service) {
if (mActivityThread != null) {
mActivityThread.post(new RunConnection(name, service, 0));
} else {
doConnected(name, service);
}
}
这里的mActivityThread 是之前通过ActivityThread.getHandler函数得到的,因此,调用它的post函数后,就会把一个消息放到ActivityThread
的消息队列中去了。如果不明白消息机制的建议看下Handler,MessageQueue,与Looper三者关系分析,我们最终post的消息会调用到RunConnection中的run方法:
public void run() {
if (mCommand == 0) {
doConnected(mName, mService);
} else if (mCommand == 1) {
doDeath(mName, mService);
}
}
这里的mCommand值为0,于是就执行ServiceDispatcher
的doConnected方法来进一步操作了:
public void doConnected(ComponentName name, IBinder service) {
ServiceDispatcher.ConnectionInfo old;
ServiceDispatcher.ConnectionInfo info;
synchronized (this) {
.......
// If there was an old service, it is now disconnected.
if (old != null) {
mConnection.onServiceDisconnected(name);
}
// If there is a new service, it is now connected.
if (service != null) {
mConnection.onServiceConnected(name, service);
}
}
到这里我们可以看到我们调用了mConnection的onServiceConnected()方法。这个mConnection就是我们bindService之前传进来的ServiceConnection对象mServiceConnection:
private ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mRemoteRouterAIDL = IRemoteRouterAIDL.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
mRemoteRouterAIDL = null;
}
};
所以我们这里就到了onServiceConnected方法里面,我们这里调用了IRemoteRouterAIDL.Stub.asInterface(service),终于我们要开始AIDL生成的源码的分析了。
4.asInterface
我们看到绑定完成会回调ServiceConnection的onServiceConnected方法然后会调用这个方法,这个方法在AIDL文件生成的源码中:
public static com.lenovohit.lrouter_api.IRemoteRouterAIDL asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.lenovohit.lrouter_api.IRemoteRouterAIDL))) {
return ((com.lenovohit.lrouter_api.IRemoteRouterAIDL)iin);
}
return new com.lenovohit.lrouter_api.IRemoteRouterAIDL.Stub.Proxy(obj);
}
这个方法主要用于将服务端的Binder对象转换成客户端所需的AIDL接口类型的对象,这种转换过程是区分进程的 [如果客户端和服务端位于同一进程,那么此方法返回的就是服务端的Stub对象本身,否则返回的是系统封装后的Stub.proxy对象]。所以如果我们客户端要跨进程调用远程服务的时候,我们都是通过这个proxy代理来访问,这里举例我们要调用stopRouter方法,我们的代理是怎么访问的呢?
@Override public boolean stopRouter(java.lang.String processName) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
boolean _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(processName);
mRemote.transact(Stub.TRANSACTION_stopRouter, _data, _reply, 0);
_reply.readException();
_result = (0!=_reply.readInt());
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
我们看到这里这个方法通过Binder机制调用远程RemoteRouterService的stopRouter()方法,因为mRemote就是绑定服务时候传回来的IRemoteRouterAIDL.Stub()的IBinder对象。然后服务端接受到消息的时候就会调用生成文件里面的onTransact方法里面对应的方法:
case TRANSACTION_stopRouter:
{
data.enforceInterface(DESCRIPTOR);
java.lang.String _arg0;
_arg0 = data.readString();
boolean _result = this.stopRouter(_arg0);
reply.writeNoException();
reply.writeInt(((_result)?(1):(0)));
return true;
}
到这里就会调用到了RemoteRouterService
中IRemoteRouterAIDL.Stub
的stopRouter()方法了。好了到这里我们整个流程也就讲完了,其实AIDL文件生成的代码并不难,难的是要明白整个调用过程。
总结:今天讲的内容还是比较多的,结合了bindService的过程来把整个AIDL生成的源代码的流程串了起来,如果感觉比较费劲的话就只要明白这里面的几个角色就行了,不需要整个流程明白,希望我们后面的framework之旅愉快。