Android service启动流程分析.
1、概述.
@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, mUser);
}
private ComponentName startServiceCommon(Intent service, UserHandle user) {
try {
validateServiceIntent(service);
service.prepareToLeaveProcess();
//跨境进程的时候,调用到ActivityManagerProxy中的startService.
ComponentName cn = ActivityManagerNative.getDefault().startService(
mMainThread.getApplicationThread(), service,
service.resolveTypeIfNeeded(getContentResolver()), 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) {
return null;
}
}
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, 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.writeInt(userId);
//此处最终会调用管道AMS的startService当中.
mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
reply.readException();
ComponentName res = ComponentName.readFromParcel(reply);
data.recycle();
reply.recycle();
return res;
}
case START_SERVICE_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder b = data.readStrongBinder();
//此时是在AMS所在的进程了!!!!!!!它作为客户端,拿到了ApplicationThread Binder的代理对象.
//此时已经由Binder驱动的传递,b = android.os.BinderProxy@1f1ce01d.获取了一个ApplicationThread的Binder代理对象.
android.util.Log.d("zy_ser","START_SERVICE_TRANSACTION b = "+b);//
IApplicationThread app = ApplicationThreadNative.asInterface(b);
if(app!=null){//那么拿到这个app必然就是ApplicationThreadProxy.
android.util.Log.d("zy_ser","START_SERVICE_TRANSACTION app = "+app.asBinder());
}
Intent service = Intent.CREATOR.createFromParcel(data);
String resolvedType = data.readString();
int userId = data.readInt();
ComponentName cn = startService(app, service, resolvedType, userId);
reply.writeNoException();
ComponentName.writeToParcel(cn, reply);
return true;
}
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, int userId) {//到AMS进程中了.
......
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, userId);
Binder.restoreCallingIdentity(origId);
return res;
}
}
ComponentName startServiceLocked(IApplicationThread caller,
Intent service, String resolvedType,
int callingPid, int callingUid, int userId) {
......
final boolean callerFg;//当时前台进程启动的时候,最终应该是为true.
if (caller != null) {
//mAm 是ActivityManagerService.
final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
if (callerApp == null) {
throw new SecurityException(
"Unable to find app for caller " + caller
+ " (pid=" + Binder.getCallingPid()
+ ") when starting service " + service);
}
callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
} else {
callerFg = true;
}
// 必须先通过retrieveServiceLocked()找到(或创建)一个ServiceRecord节点
//毕竟是用这个ServiceRecord节点来管理service的.
//这样它里面就有ServiceRecord了,而ServiceRecord又通过ServiceInfo实例化了很多东西
ServiceLookupResult res =
retrieveServiceLocked(service, resolvedType,
callingPid, callingUid, userId, true, callerFg);
if (res == null) {
return null;
}
if (res.record == null) {//权限拒绝.
return new ComponentName("!", res.permission != null
? res.permission : "private to package");
}
ServiceRecord r = res.record;
.......
r.lastActivity = SystemClock.uptimeMillis();
r.startRequested = true;
r.delayedStop = false;
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
service, neededGrants));
final ServiceMap smap = getServiceMap(r.userId);
boolean addToStarting = false;
......//根据各种条件为addToStarting赋相应的值.
return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
}
private ServiceLookupResult retrieveServiceLocked(Intent service,
String resolvedType, int callingPid, int callingUid, int userId,
boolean createIfNeeded, boolean callingFromFg) {//注意createIfNeeded为true,
ServiceRecord r = null;
ServiceMap smap = getServiceMap(userId);
final ComponentName comp = service.getComponent();
//任何一个只要存在就算是以前创建过.(下面这么多集合)
if (comp != null) {
r = smap.mServicesByName.get(comp);
}
if (r == null) {
Intent.FilterComparison filter = new Intent.FilterComparison(service);
r = smap.mServicesByIntent.get(filter);
}
//总之希望在AMS内部的相关表格里找到对应的ServiceRecord节点,如果找不到,就创建一个新节点,并插入到相应的表格中.
if (r == null) {//实在找不到的时候.
try {
// 从PKMS处查到ServiceInfo.(解析这个应用的时候实例化的)。
//看来是需要利用安装解析时的资源,交互起作用啊.
ResolveInfo rInfo =
AppGlobals.getPackageManager().resolveService(
service, resolvedType,
ActivityManagerService.STOCK_PM_FLAGS, userId);+
ServiceInfo sInfo =
rInfo != null ? rInfo.serviceInfo : null;
if (sInfo == null) {//没有在manifest中注册的时候此处救护为null.
Slog.w(TAG, "Unable to start service " + service + " U=" + userId +
": not found");
return null;
}
ComponentName name = new ComponentName(
sInfo.applicationInfo.packageName, sInfo.name);
if (userId > 0) {
if (mAm.isSingleton(sInfo.processName, sInfo.applicationInfo,
sInfo.name, sInfo.flags)
&& mAm.isValidSingletonCall(callingUid, sInfo.applicationInfo.uid)) {
userId = 0;
smap = getServiceMap(0);
}
sInfo = new ServiceInfo(sInfo);
sInfo.applicationInfo = mAm.getAppInfoForUser(sInfo.applicationInfo, userId);
}
r = smap.mServicesByName.get(name);
if (r == null && createIfNeeded) {//需要创建并且这个集合中没有的时候.
Intent.FilterComparison filter
= new Intent.FilterComparison(service.cloneFilter());
ServiceRestarter res = new ServiceRestarter();
BatteryStatsImpl.Uid.Pkg.Serv ss = null;
BatteryStatsImpl stats = mAm.mBatteryStatsService.getActiveStatistics();
synchronized (stats) {
ss = stats.getServiceStatsLocked(
sInfo.applicationInfo.uid, sInfo.packageName,
sInfo.name);
}
//此处新建的ServiceRecord.!!!!
r = new ServiceRecord(mAm, ss, name, filter, sInfo, callingFromFg, res);
res.setService(r);
//分别放入到两个集合当中
smap.mServicesByName.put(name, r);
smap.mServicesByIntent.put(filter, r);
// Make sure this component isn't in the pending list.
......
}
} catch (RemoteException ex) {
}
}
if (r != null) {//当成功的新建或者查询到一个ServiceRecord的时候.(第二次进入的时候会直接走到这里!)
if (mAm.checkComponentPermission(r.permission,
callingPid, callingUid, r.appInfo.uid, r.exported)
!= PackageManager.PERMISSION_GRANTED) {
if (!r.exported) {//不允许外部进程调用!此处进行限制.
return new ServiceLookupResult(null, "not exported from uid "
+ r.appInfo.uid);
}
......//权限拒绝
return new ServiceLookupResult(null, r.permission);
}
......
return new ServiceLookupResult(r, null);//正常的时候返回这个.
}
return null;
}
//就封装了ServiceRecord和所需权限permission.
private final class ServiceLookupResult {
final ServiceRecord record;
final String permission;
ServiceLookupResult(ServiceRecord _record, String _permission) {
record = _record;
permission = _permission;
}
}
ResolveInfo rInfo =
AppGlobals.getPackageManager().resolveService(service, resolvedType,
ActivityManagerService.STOCK_PM_FLAGS, userId);
ServiceInfo sInfo =
rInfo != null ? rInfo.serviceInfo : null;
if (sInfo == null) {
Slog.w(TAG, "Unable to start service " + service + " U=" + userId +
": not found");
return null;
}
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service,
ServiceRecord r, boolean callerFg, boolean addToStarting) {
......
//真正开启service的地方。
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
//注意此处反回值是null的时候,证明没有异常.
if (error != null) {
return new ComponentName("!!", error);
}
......
return r.name;
}
private final String bringUpServiceLocked(ServiceRecord r,
int intentFlags, boolean execInFg, boolean whileRestarting) {
......
//第一次启动的逻辑到这里的时候r.app此时还为null!!!!
//当你再次执行startService的时候,此时下面条件会符合,因为当前进程已经存在了.
if (r.app != null && r.app.thread != null) {//证明以前已经启动过了,不走create了,直接取走onStartCommand
sendServiceArgsLocked(r, execInFg, false);
return null;
}
......
// Service is now being launched, its package can't be stopped.
try {
AppGlobals.getPackageManager().setPackageStoppedState(
r.packageName, false, r.userId);
} catch (RemoteException e) {
} catch (IllegalArgumentException e) {
}
final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
final String procName = r.processName;
ProcessRecord app;
if (!isolated) {
//默认的时候这个进程名字和包名字一样,这样的话.
就不需要新建(一般,因为这个进程一般都早已启动),
//不一样的话自己配置过process,那么就需要新建了.
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
//此处是假如要运行service组件的进程已经启动的话.(注意不一定关联),直接调用realStartServiceLocked.
//默认没有在manifest中配置process的时候就会启动因为已经在当前进程中起来了.
if (app != null && app.thread != null) {
try {
app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
//不需要再去开启进程,直接去启动服务.
realStartServiceLocked(r, app, execInFg);
return null;
} catch (RemoteException e) {
}
}
} else {
app = r.isolatedProc;
}
//到这的时候还这个service组件想要运行的进程还没启动,那么我们要启动这个进程.
//但是有一个问题,我们这个组件需要放到某个地方,当进程启动个完毕的时候回去执行它,加载它对应的生命周期.
if (app == null) {
if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
"service", r.name, false, isolated, false)) == null) {
......
return msg;
}
if (isolated) {
r.isolatedProc = app;
}
}
if (!mPendingServices.contains(r)) {
mPendingServices.add(r);
}
......
return null;
}
private void attach(boolean system) {
......
if (!system) {
......
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
}
} else {
......
}
}
public void attachApplication(IApplicationThread app) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(app.asBinder());//
app显然是ApplicationThreadNative对象,不是远程代理.
mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
reply.recycle();
}
case ATTACH_APPLICATION_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
//此时又从新建的进程中走到了AMS的进程中了的!!!
IApplicationThread app = ApplicationThreadNative.asInterface(
data.readStrongBinder());
//所以出来的时候已经是代理了IApplicationThread
if (app != null) {
attachApplication(app);
}
reply.writeNoException();
return true;
}
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
......
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid);
}
} else {
app = null;
}
app.makeActive(thread, mProcessStats);
......
boolean badApp = false;
boolean didSomething = false;
// See if the top visible activity is waiting to run in this process...
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
// Find any services that should be running in this process...
if (!badApp) {
try {
didSomething |= mServices.attachApplicationLocked(app, processName);//zy
} catch (Exception e) {
}
}
return true;
}
synchronized (mPidsSelfLocked) {
this.mPidsSelfLocked.put(startResult.pid, app);
if (isActivityProcess) {
Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
msg.obj = app;
mHandler.sendMessageDelayed(msg, startResult.usingWrapper
? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
}
}
boolean attachApplicationLocked(ProcessRecord proc, String processName)
throws RemoteException {
boolean didSomething = false;
// Collect any services that are waiting for this process to come up.
if (mPendingServices.size() > 0) {//如果有服务需要(第一次启动)
ServiceRecord sr = null;
try {
for (int i=0; i<mPendingServices.size(); i++) {
sr = mPendingServices.get(i);
if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
|| !processName.equals(sr.processName))) {
continue;
}
mPendingServices.remove(i);
i--;
//在当前进程中添加当前的组件.
proc.addPackage(sr.appInfo.packageName, sr.appInfo.versionCode,
mAm.mProcessStats);
//从调用下面方法Oncreate开始.
realStartServiceLocked(sr, proc, sr.createdFromFg);
didSomething = true;
}
} catch (RemoteException e) {
}
}
if (mRestartingServices.size() > 0) {//mRestartingServices需要重启的服务.
ServiceRecord sr = null;
for (int i=0; i<mRestartingServices.size(); i++) {
......
}
}
return didSomething;
}
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
r.app = app;//在此处对进程和ServiceRecord进行关联.!!!!
r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
//放入到ProcessRecord内的成员变量services.
//final ArraySet<ServiceRecord> services = new ArraySet<ServiceRecord>();存放着目前看是所通过startService启动
//的service组件.
app.services.add(r);
......
boolean created = false;
try {
......
//通过进程的ProcessRecord的thread.(和AMS交互的Binder)
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
r.postNotification();
created = true;
} catch (DeadObjectException e) {
} finally {
......
}
......
//开始执行onsttartcommand.
sendServiceArgsLocked(r, execInFg, true);
......
}
public final void scheduleCreateService(IBinder token,
ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
//跑到了当前Service组件要运行的进程中
updateProcessState(processState, false);
//就是简单的通过CreateServiceData封装了一下.
CreateServiceData s = new CreateServiceData();
s.token = token;
s.info = info;
s.compatInfo = compatInfo;
sendMessage(H.CREATE_SERVICE, s);
}
case CREATE_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
handleCreateService((CreateServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
private void handleCreateService(CreateServiceData data) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
java.lang.ClassLoader cl = packageInfo.getClassLoader();
//实例化service,可以看出来当不是service组件实例会报错.
service = (Service) cl.loadClass(data.info.name).newInstance();
} catch (Exception e) {
}
try {
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
//每实例化一个service就是实例化一个context然后把这个service设置为它的OuterContext
context.setOuterContext(service);
Application app = packageInfo.makeApplication(false, mInstrumentation);
//就是初始化Service的一些变量.
service.attach(context, this, data.info.name, data.token, app,
ActivityManagerNative.getDefault());
service.onCreate();
mServices.put(data.token, service);
......
} catch (Exception e) {
......
}
}
public interface ServiceConnection {
public void onServiceConnected(ComponentName name, IBinder service);
public void onServiceDisconnected(ComponentName name);
}
@Override
public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
warnIfCallingFromSystemProcess();
return bindServiceCommon(service, conn, flags, Process.myUserHandle());
}
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
UserHandle user) {
IServiceConnection sd;
......
if (mPackageInfo != null) {
//在Android平台上,要和其他进程建立逻辑连接往往都需要利用binder机制。
//注意这个获取的位置,很早!还没进入AMS之前就搞定了.startService就没有,
//就是获取在ServiceDispatcher构造中实例化的内部类InnerConnection
//getOuterContext:这个outer是当前进程所在的界面的service或者activity的context.
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
mMainThread.getHandler(), flags);
//最终在
publishServiceLocked方法中有用到sd,为什么要是一个binder那?此时的它是一个类的对象把,想调用它的方法,
} else {
throw new RuntimeException("Not supported in system context");
}
validateServiceIntent(service);
try {
IBinder token = getActivityToken();
if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
&& mPackageInfo.getApplicationInfo().targetSdkVersion
< android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
flags |= BIND_WAIVE_PRIORITY;
}
service.prepareToLeaveProcess();
int res = ActivityManagerNative.getDefault().bindService(
mMainThread.getApplicationThread(), getActivityToken(),
service, service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, user.getIdentifier());//zy 注意这个sd.writeStrongBinder写入
......
return res != 0;
} catch (RemoteException e) {
return false;
}
}
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 mDied;
private boolean mForgotten;
private static class ConnectionInfo {
IBinder binder;
IBinder.DeathRecipient deathMonitor;
}
//ActivityManagerServic后续就是要通过这个Binder对象和ServiceConnection通信的。
private static class InnerConnection extends IServiceConnection.Stub {
final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;
InnerConnection(LoadedApk.ServiceDispatcher sd) {//!!注意它的构造传入的参数.
mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
}
public void connected(ComponentName name, IBinder service) throws RemoteException {
LoadedApk.ServiceDispatcher sd = mDispatcher.get();//这个get是什么意思?难道是弱引用的一种使用?
if (sd != null) {
sd.connected(name, service);
}
}
}
private final ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo> mActiveConnections
= new ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo>();
ServiceDispatcher(ServiceConnection conn,
Context context, Handler activityThread, int flags) {
//并且每一个ServiceDispatcher内部都有一个private mIServiceConnection.1对1.
mIServiceConnection = new InnerConnection(this);
mConnection = conn;
mContext = context;
mActivityThread = activityThread;
mLocation = new ServiceConnectionLeaked(null);
mLocation.fillInStackTrace();
mFlags = flags;
}
......
ServiceConnection getServiceConnection() {
return mConnection;
}
IServiceConnection getIServiceConnection() {
return mIServiceConnection;
}
int getFlags() {
return mFlags;
}
public void connected(ComponentName name, IBinder service) {
if (mActivityThread != null) {
mActivityThread.post(new RunConnection(name, service, 0));
} else {
doConnected(name, service);
}
}
public void doConnected(ComponentName name, IBinder service) {
ServiceDispatcher.ConnectionInfo old;
ServiceDispatcher.ConnectionInfo info;
synchronized (this) {
if (mForgotten) {
// We unbound before receiving the connection; ignore
// any connection received.
return;
}
old = mActiveConnections.get(name);
if (old != null && old.binder == service) {
// Huh, already have this one. Oh well!
return;
}
if (service != null) {
// A new service is being connected... set it all up.
mDied = false;
info = new ConnectionInfo();
info.binder = service;
info.deathMonitor = new DeathMonitor(name, service);
try {
service.linkToDeath(info.deathMonitor, 0);
mActiveConnections.put(name, info);
} catch (RemoteException e) {
// This service was dead before we got it... just
// don't do anything with it.
mActiveConnections.remove(name);
return;
}
} else {
// The named service is being disconnected... clean up.
mActiveConnections.remove(name);
}
if (old != null) {
old.binder.unlinkToDeath(old.deathMonitor, 0);
}
}
// If there was an old service, it is not disconnected.
if (old != null) {
mConnection.onServiceDisconnected(name);
}
// If there is a new service, it is now connected.
if (service != null) {
//这里的mConnection变量的类型的ServiceConnection,它是在前面的Step 4中设置好的.
mConnection.onServiceConnected(name, service);//zy 最终回调到这里.
}
}
......
private final class RunConnection implements Runnable {
RunConnection(ComponentName name, IBinder service, int command) {
mName = name;
mService = service;
mCommand = command;
}
public void run() {
if (mCommand == 0) {
doConnected(mName, mService);
} else if (mCommand == 1) {
doDeath(mName, mService);
}
}
final ComponentName mName;
final IBinder mService;
final int mCommand;
}
private final class DeathMonitor implements IBinder.DeathRecipient
{
//检测service是否挂掉了,挂掉的话,最终调用到传入的mConnection.onServiceDisconnected(name);
}
}
//ActivityManagerServic后续就是要通过这个Binder对象和ServiceConnection通信的。
private static class InnerConnection extends IServiceConnection.Stub {
final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;
InnerConnection(LoadedApk.ServiceDispatcher sd) {//!!注意它的构造传入的参数.
mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
}
public void connected(ComponentName name, IBinder service) throws RemoteException {
LoadedApk.ServiceDispatcher sd = mDispatcher.get();//这个get是什么意思?那那倒是弱引用的一种使用?
if (sd != null) {
sd.connected(name, service);
}
}
}
public final IServiceConnection getServiceDispatcher(ServiceConnection c,
Context context, Handler handler, int flags) {
synchronized (mServices) {
LoadedApk.ServiceDispatcher sd = null;
//context 以context为一个实例.
android.util.Log.d("zy_bind","LoadPak getServiceDispatcher context= " + context);
//所以一个services 对应一个map.第二次bindservice的时候此处就不为null了
ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);// 第一次应该是null
if (map != null) {
sd = map.get(c);
}
if (sd == null) {
//实例化
ServiceDispatcher
sd = new ServiceDispatcher(c, context, handler, flags);
if (map == null) {
map = new ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>();
mServices.put(context, map);//BinderService在此处放入相应的集合.
}
map.put(c, sd);//放入对应的集合.
} else {
sd.validate(context, handler);
}
return sd.getIServiceConnection();
}
}
public int bindService(IApplicationThread caller, IBinder token,
Intent service, String resolvedType,
IServiceConnection connection, int flags, int userId) {
......
synchronized(this) {
//和startService一样经过驱动到这里以后,IApplicationThread caller就为BinderProxy了。
return mServices.bindServiceLocked(caller, token, service, resolvedType,
connection, flags, userId);
}
}
int bindServiceLocked(IApplicationThread caller, IBinder token,
Intent service, String resolvedType,
IServiceConnection connection, int flags, int userId) {
......
final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
ActivityRecord activity = null;
//发起绑定动作是activity的时候,此处不为null
if (token != null) {
activity = ActivityRecord.isInStackLocked(token);
if (activity == null) {
Slog.w(TAG, "Binding with unknown activity: " + token);
return 0;
}
}
//那要是在service当中启动的service是不是就null?
int clientLabel = 0;
PendingIntent clientIntent = null;
......
ServiceLookupResult res =
retrieveServiceLocked(service, resolvedType,
Binder.getCallingPid(), Binder.getCallingUid(), userId, true, callerFg);
......
ServiceRecord s = res.record;//这个来源和startService的一样.
final long origId = Binder.clearCallingIdentity();
try {
//相对于一个Service而言,有多少应用和它建立了绑定关系,就会有多少个AppBindRecord节点.
//当然,一个应用里可以有多个地方发起绑定动作,
//所以AppBindRecord里需要用一个ArraySet<ConnectionRecord>记录下每个绑定动作对应的逻辑连接节点。
AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
//每当用户调用bindService()时,
最终的表现是向ServiceRecord内部的某张映射表里添加一个新的ConnectionRecord节点.
//在实际运作时,这个节点还会记录进其他几个映射表里(比如系统总映射表),可能是方便以后的查询等动作吧
//实例化ConnectionRecord把IServiceConnection代理端记录到ConnectionRecord节点里.
ConnectionRecord c = new ConnectionRecord(b, activity,
connection, flags, clientLabel, clientIntent);
IBinder binder = connection.asBinder();
ArrayList<ConnectionRecord> clist = s.connections.get(binder);
if (clist == null) {
clist = new ArrayList<ConnectionRecord>();
s.connections.put(binder, clist);
}
clist.add(c);
b.connections.add(c);
if (activity != null) {
if (activity.connections == null) {
activity.connections = new HashSet<ConnectionRecord>();
}
activity.connections.add(c);
}
b.client.connections.add(c);
clist = mServiceConnections.get(binder);//这个表应该是比较重要的.
if (clist == null) {
clist = new ArrayList<ConnectionRecord>();
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) != null) {
return 0;
}
}
......
if (s.app != null && b.intent.received) {
// Service is already running, so we can immediately
// publish the connection.
try {
//直接调用connected.
c.conn.connected(s.name, b.intent.binder);
} catch (Exception e) {
Slog.w(TAG, "Failure sending service " + s.shortName
+ " to connection " + c.conn.asBinder()
+ " (in " + c.binding.client.processName + ")", e);
}
// If this is the first app connected back to this binding,
// and the service had previously asked to be told when
// rebound, then do so.
if (b.intent.apps.size() == 1 && b.intent.doRebind) {
//该函数主要是向目标service发起绑定的请求,
requestServiceBindingLocked(s, b.intent, callerFg, true);
}
} else if (!b.intent.requested) {
requestServiceBindingLocked(s, b.intent, callerFg, false);
}
......
} finally {
Binder.restoreCallingIdentity(origId);
}
return 1;
}
public AppBindRecord retrieveAppBindingLocked(Intent intent,
ProcessRecord app) {
Intent.FilterComparison filter = new Intent.FilterComparison(intent);
IntentBindRecord i = bindings.get(filter);
if (i == null) {
i = new IntentBindRecord(this, filter);
bindings.put(filter, i);
}
AppBindRecord a = i.apps.get(app);
if (a != null) {
return a;
}
a = new AppBindRecord(this, i, app);
i.apps.put(app, a);
return a;
}
final class IntentBindRecord {
/** The running service. */
final ServiceRecord service;
/** The intent that is bound.*/
final Intent.FilterComparison intent; //
/** All apps that have bound to this Intent. */
final ArrayMap<ProcessRecord, AppBindRecord> apps
= new ArrayMap<ProcessRecord, AppBindRecord>();
/** Binder published from service. */
IBinder binder;//并没有实例化它.最终是吧自己实现的Service放到了这里.
......
IntentBindRecord(ServiceRecord _service, Intent.FilterComparison _intent) {
service = _service;
intent = _intent;
}
}
final class AppBindRecord {
final ServiceRecord service; // The running service.
final IntentBindRecord intent; // The intent we are bound to.
final ProcessRecord client; // Who has started/bound the service.
final ArraySet<ConnectionRecord> connections = new ArraySet<>();
// All ConnectionRecord for this client.
AppBindRecord(ServiceRecord _service, IntentBindRecord _intent,
ProcessRecord _client) {
service = _service;
intent = _intent;
client = _client;
}
}
final class ConnectionRecord {
final AppBindRecord binding; // The application/service binding.
final ActivityRecord activity; // If non-null, the owning activity.
final IServiceConnection conn; // The client connection.
final int flags; // Binding options.
final int clientLabel; // String resource labeling this client.
final PendingIntent clientIntent; // How to launch the client.
String stringName; // Caching of toString.
boolean serviceDead; // Well is it?
......
ConnectionRecord(AppBindRecord _binding, ActivityRecord _activity,
IServiceConnection _conn, int _flags,
int _clientLabel, PendingIntent _clientIntent) {
binding = _binding;
activity = _activity;
conn = _conn;
flags = _flags;
clientLabel = _clientLabel;
clientIntent = _clientIntent;
}
......
}
ArrayList<ConnectionRecord> clist = s.connections.get(binder);
if (clist == null) {
clist = new ArrayList<ConnectionRecord>();
s.connections.put(binder, clist);
}
clist.add(c);
b.connections.add(c)
clist = mServiceConnections.get(binder);
if (clist == null) {
clist = new ArrayList<ConnectionRecord>();
mServiceConnections.put(binder, clist);
}
clist.add(c);
private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg) {
for (int i=r.bindings.size()-1; i>=0; i--) {//当是单纯的startService的时候,此处不符合条件就不会再进一步的执行.
IntentBindRecord ibr = r.bindings.valueAt(i);//zy bindings什么时候实例化的啊?
if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
break;
}
}
}
private final boolean requestServiceBindingLocked(ServiceRecord r,
IntentBindRecord i, boolean execInFg, boolean rebind) {
......
if ((!i.requested || rebind) && i.apps.size() > 0) {
try {
......
r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
r.app.repProcState);
if (!rebind) {
i.requested = true;
}
i.hasBound = true;
i.doRebind = false;
} catch (RemoteException e) {
}
}
return true;
}
public final void scheduleBindService(IBinder token, Intent intent,
boolean rebind, int processState) {
updateProcessState(processState, false);
BindServiceData s = new BindServiceData();//用来封装service信息
s.token = token;//还是ServiceRecord
s.intent = intent;
s.rebind = rebind;
......
sendMessage(H.BIND_SERVICE, s);
}
case BIND_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
handleBindService((BindServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
private void handleBindService(BindServiceData data) {
Service s = mServices.get(data.token);//在create的时候添加进去的!
if (s != null) {
try {
try {
if (!data.rebind) {//不是重新绑定的时候走这里
IBinder binder = s.onBind(data.intent);//返回这个我们在onBind中得到的binder对象.
ActivityManagerNative.getDefault().publishService(
data.token, data.intent, binder);//传入onBinder返回的Binder.
} else {
s.onRebind(data.intent);
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
}
ensureJitEnabled();
} catch (RemoteException ex) {......
}
} catch (Exception e) {......
}
}
}
public void publishService(IBinder token, Intent intent, IBinder service) {
......
synchronized(this) {
......
//service是我们自己的Service组件的onBinder方法返回的.
//也正是因为返回的是一个Binder对象才能来回传递,此时拿的应该是一个BinderProxy.
mServices.publishServiceLocked((ServiceRecord)token, intent, service);
}
}
void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {//zy
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;//实例化IntentBindRecord.binder成员变量.
b.requested = true;
b.received = true;//直到此处置为true.
for (int conni=r.connections.size()-1; conni>=0; conni--) {
//先从对应的表中取出来.valueAt(.)从最后一个索引开始拿
ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
for (int i=0; i<clist.size(); i++) {
ConnectionRecord c = clist.get(i);
......
try {
//c.conn就是LoadedApk.ServiceDispatcher.InnerConnection对象
//此处就用到了把,假如不是一个Binder对象它也没办法来回传输啊.(因为是在启动的那个进程中实例化的
//而此时是在AMS所在的进程)
c.conn.connected(r.name, service);//调用到InnerConnection 的connected方法.
} catch (Exception e) {......
}
}
}
}
serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
}
} finally {
Binder.restoreCallingIdentity(origId);
}
}
public void connected(ComponentName name, IBinder service) throws RemoteException {
LoadedApk.ServiceDispatcher sd = mDispatcher.get();//感觉是弱引用的一种使用.
if (sd != null) {
sd.connected(name, service);
}
}
public void connected(ComponentName name, IBinder service) {
if (mActivityThread != null) {
mActivityThread.post(new RunConnection(name, service, 0));
} else {
doConnected(name, service);
}
}
public void run() {
if (mCommand == 0) {
doConnected(mName, mService);
} else if (mCommand == 1) {//检测到死亡的时候发送这个.
doDeath(mName, mService);
}
}
public void doConnected(ComponentName name, IBinder service) {
synchronized (this) {
if (service != null) {
// A new service is being connected... set it all up.
mDied = false;
info = new ConnectionInfo();
info.binder = service;
info.deathMonitor = new DeathMonitor(name, service);
try {
service.linkToDeath(info.deathMonitor, 0);
mActiveConnections.put(name, info);
} catch (RemoteException e) {
}
} else {
// The named service is being disconnected... clean up.
mActiveConnections.remove(name);
}
......
}
......
// If there is a new service, it is now connected.
if (service != null) {
//这里的mConnection变量的类型的ServiceConnection,它是在前面的Step 4中设置好的.
mConnection.onServiceConnected(name, service);//zy 最终回调到这里.
}
}
oneway interface IServiceConnection {
void connected(in ComponentName name, IBinder service);
}
public String resolveTypeIfNeeded(ContentResolver resolver) {
if (mComponent != null) {
return mType;
}
return resolveType(resolver);
}
if (service != null) {
mConnection.onServiceConnected(name, service);
}
@Override
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
throw new ReceiverCallNotAllowedException(
"BroadcastReceiver components are not allowed to bind to services");
}
public static final class FilterComparison {
private final Intent mIntent;
private final int mHashCode;
public FilterComparison(Intent intent) {
mIntent = intent;
mHashCode = intent.filterHashCode();
}
public Intent getIntent() {
return mIntent;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof FilterComparison) {
Intent other = ((FilterComparison)obj).mIntent;
return mIntent.filterEquals(other);
}
return false;
}
@Override
public int hashCode() {
return mHashCode;
}
}
class ContextImpl extends Context {
private ContextImpl(......) {
......
}
private Context mOuterContext;
final void setOuterContext(Context context) {
mOuterContext = context;
}
final Context getOuterContext() {
return mOuterContext;
}
}
private void handleCreateService(CreateServiceData data) {
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
//在应用进程启动的时候,handleBindApplication mInstrumentation.
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);//在create的时候添加进去的,onBind时候会用.
}
public final void attach(
Context context,ActivityThread thread, String className, IBinder token,
Application application, Object activityManager) {
attachBaseContext(context);//mBase = base;
......
}
protected void attachBaseContext(Context base) {
if (mBase != null) {
throw new IllegalStateException("Base context already set");
}
mBase = base;
}
private Context createBaseContextForActivity(ActivityClientRecord r,
final Activity activity) {
ContextImpl appContext = ContextImpl.createActivityContext(this, r.packageInfo, r.token);
appContext.setOuterContext(activity);
Context baseContext = appContext;
......
return baseContext;
}
Android service启动流程分析.相关推荐
- Android -- Wifi启动流程分析
Android -- Wifi启动流程分析 Android网络各个模式中,Wifi应该是目前最常用的一种网络方式了:下面就简单介绍下Android中Wifi的启动流程. 当我在Setting菜单里点击 ...
- 【SemiDrive源码分析】【X9芯片启动流程】27 - AP1 Android Preloader启动流程分析(加载atf、tos、bootloader镜像后进入BL31环境)
[SemiDrive源码分析][X9芯片启动流程]27 - AP1 Android Preloader启动流程分析(加载atf.tos.bootloader镜像后进入BL31环境) 一.Android ...
- android app启动流程分析,Android应用开发之Android 7.0 Launcher3的启动和加载流程分析...
本文将带你了解Android应用开发Android 7.0 Launcher3的启动和加载流程分析,希望本文对大家学Android有所帮助. Android 7.0 Launcher3的启动和加载流程 ...
- Android | Activity 启动流程分析
前言 Activity 类是 android 应用的关键组件,在日常开发中,绝对少不了组件.既然用了这么久,你知道他的启动流程
- 【SemiDrive源码分析】【X9芯片启动流程】30 - AP1 Android Kernel 启动流程 start_kernel 函数详细分析(一)
[SemiDrive源码分析][X9芯片启动流程]30 - AP1 Android Kernel 启动流程 start_kernel 函数详细分析(一) 一.Android Kernel 启动流程分析 ...
- c++builder启动了怎么停止_App 竟然是这样跑起来的 —— Android App/Activity 启动流程分析...
在我的上一篇文章: AJie:按下电源键后竟然发生了这一幕 -- Android 系统启动流程分析zhuanlan.zhihu.com 我们分析了系统在开机以后的一系列行为,其中最后一阶段 AMS( ...
- Android系统开机到Launcher启动流程分析
本文基于Android10.0的源码. 由于google团队在对framework层代码进行大量重构,所以代码变动还是挺大的. 常见基础问题: SystemServer系统服务进程是如何创建的?Lau ...
- android 开机向导加载过程,开机向导启动流程分析
开机向导启动流程 首先来看Android启动流程: 1.Bootloader(系统启动加载器,将Linux加载到RAM): 2.Kernel 3.init进程 4.Zygote(Zygote进程是整个 ...
- Android开机向导启动流程分析
Android开机向导启动流程 首先来看Android启动流程: 1.Bootloader(系统启动加载器,将Linux加载到RAM): 2.Kernel 3.init进程 4.Zygote(Zygo ...
最新文章
- java字符串 大括号_string.format格式化字符串中转义大括号“{}”
- 浙江大学远程教育计算机应用基础第4次,浙江大学远程教育计算机应用基础5.Powerpoint知识题.docx...
- 一篇文章教你如何制作二次元角色建模!
- 工作329:uni-数据为空不显示
- java jstat结果分析_JVM调优总结 + jstat 分析
- spark在集群上运行
- 昔年浅谈电商服务业务应如何推广
- 转:单片机C语言中的data,idata,xdata,pdata,code
- 应用+技术!闪马智能惊艳亮相WAIC!斩获AIWIN双料大奖!
- 简练网软考知识点整理-项目需求跟踪及需求跟踪矩阵
- matlab神经网络
- [转载]快速实现微信扫码关注公众号/用户注册并登陆
- 计算机表格制作ppt,计算机基础使用excel2003制作表格.ppt
- 如何在linux下安装一个音乐播放器
- 【ORB_SLAM3源码解读】IMU基础介绍、IMU姿态、速度、位置解算以及误差方程、坐标系
- 程序员常用的经典算法和OJ网站
- python字符串前面u、r、b含义以及str、bytes互转
- 2022 IDEA全家桶使用最新主题(免申请)
- js内置对象处理-打印学生成绩单
- 三十年变迁,我们大前端正青春!
热门文章
- 蓝桥杯嵌入式第一篇 点亮LED灯开启成功之路
- 【Ubuntu】Linux系统安装python3.6
- 写在2020.10.16
- 山东高考六选三学计算机选什么,2020年山东实行新高考“6选3”模式 所学科目合格后才能参加高考!...
- win 10电源正在计算机,win10系统提示当前没有可用的电源选项解决办法
- ubuntu wine安装微信中文显示方框
- 省市区 字母排序json数据
- 单板计算机(SBC)市场现状研究分析与发展前景预测报告
- vue入门到启动_一篇超完整的Vue新手入门指导教程
- js中json字符串解析