Service两次IPC过程
Service 启动
我们知道开启Service有两种,一种是 直接startService(intent); 另外一种是bindService(intent,mConn, Service.BIND_AUTO_CREATE);
startService()
先看看startService()是如果启动Service。在Activity中直接startService(),是直接ContextWapper中的startService(Intent service)。
ContextWapper.java
@Override
public ComponentName startService(Intent service) {
return mBase.startService(service);
}
这里的 mBase 是在Activity启动的时候通过 attachBaseContext进来的一个Context的实现,实际上是ContextImpl。
也就是说实际上是调用ContextImpl中的startService(service)。
ContextImpl.java
@Override
public ComponentName startService(Intent service) {
//判断警告是否是系统进程直接调用方法。
warnIfCallingFromSystemProcess();
return startServiceCommon(service, mUser);
}
private ComponentName startServiceCommon(Intent service, UserHandle user) {
try {
//验证service是否为空。
validateServiceIntent(service);
//准备intent leave app process。
service.prepareToLeaveProcess();
//正在启动的是通过AMS启动.
ComponentName cn = ActivityManagerNative.getDefault().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), getOpPackageName(), user.getIdentifier());
if (cn != null) {
if (cn.getPackageName().equals("!")) {
throw new SecurityException(
"Not allowed to start service " + service
+ " without permission " + cn.getClassName());
} else if (cn.getPackageName().equals("!!")) {
throw new SecurityException(
"Unable to start service " + service
+ ": " + cn.getClassName());
}
}
return cn;
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
}
这边通过ContextImpl中的startService(service)最后调用startServiceCommon()的方法。
注意startServiceCommon()中的ActivityManagerNative.getDefault().startService() 我们看一下ActivityManagerNative 是什么东西.
ActivityManagerNative类的定义是这样的:
public abstract class ActivityManagerNative extends Binder implements IActivityManager{}
这边ActivityManagerNative是一个典型的Binder对象,继承Binder并实现一个接口。这边如果不理解Binder,建议先去学习了解Binder,了解Android的IPC机制。4大组件底层的启动大部分都是通过Binder进行关联启动。
如果了解Binder,那我们继续下去,我们在写AIDL的时候,IDE自动帮我们生成Binder代码,我们知道Binder有两个内容,一个是Stub,用来服务端通信的,还有一个Proxy代理用来客户端信息。而ActivityManagerNative本身就是一个Stub,它是由Google自己写的一个Binder。ActivityManagerNative 里面也有一个Proxy。就是ActivityManagerProxy。
class ActivityManagerProxy implements IActivityManager{
private IBinder mRemote;
public ActivityManagerProxy(IBinder remote)
{
mRemote = remote;
}
public IBinder asBinder()
{
return mRemote;
}
.....
}
看这个跟IDE自动生成的代码是一样的。
我们接着上面的分析,在ContextImpl中ActivityManagerNative.getDefault(),实际上是一由一个自己封装Singleton单例对象。在get()的时候如果是第一次则会调用create().
static public IActivityManager getDefault() {
return gDefault.get();
}
private static final Singleton gDefault = new Singleton() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
Singleton.java
public abstract class Singleton {
private T mInstance;
protected abstract T create();
public final T get() {
synchronized (this) {
if (mInstance == null) {
mInstance = create();
}
return mInstance;
}
}
}
在这里将获取的IBinder转成IActivityManager 对象。ActivityManagerNative.getDefault().startService()实际上是调用IActivityManager.startService(). 由上面分析的Binder,我们可以知道IActivityManager.startService()就是从客户端调用startService,也就是在Proxy里面调用startService()。
ActivityManagerProxy.startService:
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, 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);
service.writeToParcel(data, 0);
data.writeString(resolvedType);
data.writeString(callingPackage);
data.writeInt(userId);
mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
reply.readException();
ComponentName res = ComponentName.readFromParcel(reply);
data.recycle();
reply.recycle();
return res;
}
注意这句:mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
通过transact调用Binder的服务端的方法。
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
...
case START_SERVICE_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder b = data.readStrongBinder();
IApplicationThread app = ApplicationThreadNative.asInterface(b);
Intent service = Intent.CREATOR.createFromParcel(data);
String resolvedType = data.readString();
String callingPackage = data.readString();
int userId = data.readInt();
ComponentName cn = startService(app, service, resolvedType, callingPackage, userId);
reply.writeNoException();
ComponentName.writeToParcel(cn, reply);
return true;
}
...
}
}
这里的startService(app, service, resolvedType, callingPackage, userId);具体实现实际上有ActivityManagerService子类实现的。
ActivityManagerService.java
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, String callingPackage, int userId)
throws TransactionTooLargeException {
enforceNotIsolatedCaller("startService");
// Refuse possible leaked file descriptors
if (service != null && service.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
if (callingPackage == null) {
throw new IllegalArgumentException("callingPackage cannot be null");
}
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
"startService: " + service + " type=" + resolvedType);
synchronized(this) {
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
ComponentName res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid, callingPackage, userId);
Binder.restoreCallingIdentity(origId);
return res;
}
}
接着调用mServices.startServiceLocked()方法,mServices是ActiveServices。
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, String callingPackage, int userId)
throws TransactionTooLargeException {
....
return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
}
startServiceInnerLocked:
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
....
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
if (error != null) {
return new ComponentName("!!", error);
}
...
}
这里调用bringUpServiceLocked,而在它的内部实际调用了realStartServiceLocked()方法。
private final String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting) throws TransactionTooLargeException {
...
if (!isolated) {
...
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) {
}
...
}
看一下realStartServiceLocked():
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
if (app.thread == null) {
throw new RemoteException();
}
try {
...
//回调onCreate
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
r.postNotification();
created = true;
} catch (DeadObjectException e) {
...
}
...
//回调onStartCommand
sendServiceArgsLocked(r, execInFg, true);
...
}
这边重点看app.thread.scheduleCreateService() ,这里的app.thread是IApplicationThread。而在ActivityManagerNative里的START_SERVICE_TRANSACTION有这句:
IApplicationThread app = ApplicationThreadNative.asInterface(b); 我们的这个app.thread也是ApplicationThreadNative里的Binder。这边又是一个Binder对象。
同样ApplicationThreadNative也是一个Stub,里面的ApplicationThreadProxy是一个Proxy。所以这里app.thread.scheduleCreateService()实际是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();
}
调用 mRemote.transact(),则回调Proxy里的SCHEDULE_CREATE_SERVICE_TRANSACTION这个code。
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
...
case SCHEDULE_CREATE_SERVICE_TRANSACTION: {
data.enforceInterface(IApplicationThread.descriptor);
IBinder token = data.readStrongBinder();
ServiceInfo info = ServiceInfo.CREATOR.createFromParcel(data);
CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
int processState = data.readInt();
scheduleCreateService(token, info, compatInfo, processState);
return true;
}
...
}
ApplicationThreadNative的具体实现是ApplicationThread:
private class ApplicationThread extends ApplicationThreadNative {
...
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()发送消息,由H来处理,H是系统的Handler。
private class H extends Handler {
public void handleMessage(Message msg) {
...
case CREATE_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
handleCreateService((CreateServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
...
}
}
在这里接着调用handleCreateService()。
private void handleCreateService(CreateServiceData data) {
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
java.lang.ClassLoader cl = packageInfo.getClassLoader();
//反射获取Service
service = (Service) cl.loadClass(data.info.name).newInstance();
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
"Unable to instantiate service " + data.info.name
+ ": " + e.toString(), e);
}
}
try {
if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
//创建ContextImpl对象。
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
Application app = packageInfo.makeApplication(false, mInstrumentation);
//service attach操作
service.attach(context, this, data.info.name, data.token, app,
ActivityManagerNative.getDefault());
//这里就是最终调用onCreate().
service.onCreate();
mServices.put(data.token, service);
try {
//至此调用服务完成.
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch (RemoteException e) {
// nothing to do.
}
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
"Unable to create service " + data.info.name
+ ": " + e.toString(), e);
}
}
}
到这里Service的onCreate()方法回调了。按照Service的生命周期,用startService方式启动Service接着会调用onStartCommand(),那这个是在哪里回调的?其实是在realStartServiceLocked()里的sendServiceArgsLocked。
private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
boolean oomAdjusted) throws TransactionTooLargeException {
...
while (r.pendingStarts.size() > 0) {
...
try {
...
r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
}
...
}
}
同样到了ApplicationThread的scheduleServiceArgs().
public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
int flags ,Intent args) {
ServiceArgsData s = new ServiceArgsData();
s.token = token;
s.taskRemoved = taskRemoved;
s.startId = startId;
s.flags = flags;
s.args = args;
sendMessage(H.SERVICE_ARGS, s);
}
这样就又到了H里面了
case SERVICE_ARGS:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart");
handleServiceArgs((ServiceArgsData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
private void handleServiceArgs(ServiceArgsData data) {
Service s = mServices.get(data.token);
if (s != null) {
try {
if (data.args != null) {
data.args.setExtrasClassLoader(s.getClassLoader());
data.args.prepareToEnterProcess();
}
int res;
if (!data.taskRemoved) {
//至此onStartCommand 回调完成。
res = s.onStartCommand(data.args, data.flags, data.startId);
} else {
s.onTaskRemoved(data.args);
res = Service.START_TASK_REMOVED_COMPLETE;
}
QueuedWork.waitToFinish();
try {
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
} catch (RemoteException e) {
// nothing to do.
}
ensureJitEnabled();
} catch (Exception e) {
if (!mInstrumentation.onException(s, e)) {
throw new RuntimeException(
"Unable to start service " + s
+ " with " + data.args + ": " + e.toString(), e);
}
}
}
}