Android中的Service#bindService流程分析
一、概述
环境:android7.1.2
android里面可以通过bindService来启动一个Service,然后和这个Service进行绑定,我们现在来分析下这个流程
这个流程涉及两个进程间的通信,用的是binder
设计的类主要包括:ContextImpl、IActivityManager、ActivityManagerNative、ActivityThread、IApplicationThread、ApplicationThreadNaitve、ActivityManagerService、ActiveService
ContextImpl:这个是Context这个抽象类的实现类,Context是android的上下文,里面可以获取资源还有服务
IActivityManager:这个类是一个接口,定义了一些和AMS(ActivityManagerService)通信的接口,这些接口主要是调用AMS的一些方法接口
ActivityManagerNative:这个是IActivityManager的实现类,继承自Binder,说明这个类是负责binder通信的
,这个类实际上负责app进程和AMS之间Binder通信的实现,他们的读写都是在这里完成的,ActivityManagerProxy是这个类的内部类实现了IActivityManager接口,构造方法中传入一个远程(AMS)的binder,负责实际的App进程端发送消息任务
高版本的android比如android10 这个类已经去掉了,统一使用了aidl来自动生成的,这个类变成了IActivityManager.Stub,还有ApplicationThreadNaitve也是这样 都去掉了,改用aidl来实现
ActivityManagerService:这个是整个android系统的核心服务,负责四大组件的管理和调度状态的存储,比如activity,service的启动和关闭,生命周期的维护等,非常重要
ActivityThread:如果AMS远程服务端端的服务总管,那么ActivityThread就是客户端的调度总管,负责客户端的activity,server的调度任务,和AMS保持密切的联系,和AMS的联系是通过ActivityManagerNative和ApplicationThreadNaitve来实现通信的,ActivityManagerNative负责发消息,ActivityThread内部的ApplicationThread类负责接受AMS的消息,ApplicationThread继承自ApplicationThreadNaitve
IApplicationThread:这个是app进程和AMS进程通信的接口,这些接口主要是AMS调用ActivityThread的一些方法接口
ApplicationThreadNaitve:这个是IApplicationThread的实现类,ApplicationThreadNaitve是继承自Binder的,可以实现Binder通信,ApplicationThreadNaitve主要做了两件事,1:接受AMS发的消息,在onTransact做的处理,2、ApplicationThreadNaitve#ApplicationThreadProxy的代理类是AMS中向ActivitThread发送消息的实际调用的地方,给AMS提供了发送消息到客户端提供了方法实现,说白了ApplicationThreadProxy是AMS发送消息的代理
ActiveService:这个是AMS服务内部的处理Service事务的工具类,很多的工作AMS没有实际的去做,都交给了ActiveService,ActiveService持有了AMS的引用
大致了解了上面这些类后,我们分析流程的时候心里就有个底,知道这个类的作用了,到了哪一步,废话不多少,我们开始走流程吧。
二、流程分析
1、Context#bindService
Context:
public abstract class Context {
/*
xxxxxxx
代码省略
xxxxxxx
*/
public abstract boolean bindService(@RequiresPermission Intent service,
@NonNull ServiceConnection conn, @BindServiceFlags int flags);
/*
xxxxxxx
代码省略
xxxxxxx
*/
}
我们看到Context其实是个抽象类的,bindService方法没有实现,Context的实现类是ContextImpl
我们看下这几个参数:
Intent service:这个是要启动的那个服务,是一个目的,在android5.0之后,google建议使用隐式调用,就是要设置ComponentName、PackageName来调用
ServiceConnection:这个是binder的连接和断开连接的回调
flags:这个是连接的flag,是一中连接的操作选项,一般都是BIND_AUTO_CREATE,服务没有开启要自动创建服务
2、ContextImpl#bindService
@Override
public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
warnIfCallingFromSystemProcess();
return bindServiceCommon(service, conn, flags, mMainThread.getHandler(),
Process.myUserHandle());
}
mMainThread.getHandler:这个是主线程的Handler
Process.myUserHandle() :这个要获取UserHandle 最终从这里获取程序的uid,
这里多说下:
uid是每个程序安装之后,系统给默认分配的一个id,用户id
pid:是进程id,每个程序只有一个uid,但是每个程序可以有1个或者多个pid,因为每个程序可以有多个进程
继续调用bindServiceCommon
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler
handler, UserHandle user) {
//这个IServiceConnection 其实是几个binder,是对ServiceConnection的转化,最后要通过
//binder传入到AMS。然后被回调的,
IServiceConnection sd;
if (conn == null) {
throw new IllegalArgumentException("connection is null");
}
//这个mPackageInfo是LoadedApk,当前这个已经安装了的apk的描述,里面有关于安装的位置,cloassload,各种资源等,关于apk的信息
if (mPackageInfo != null) {
//这里主要是做了ServiceConnection 转这个IServiceConnection,注册了转这个IServiceConnection回调,IServiceConnection回调会触发ServiceConnection,传递个app,
//还有关于解绑回调的处理,就不往里深究了
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
} else {
//如果这个是null,说明app都不存在,信息没有,抛出异常
throw new RuntimeException("Not supported in system context");
}
//这个就是android5.0之后Intent需要设置ComponentName 还有package启动服务的校验
validateServiceIntent(service);
try {
//获取当前activity的token,这个token主要是鉴别作用,AMS要知道是哪个activity发起的,然后做处理,相当于这个token是activity的身份证
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;
}
//Intent 在离开这个进程的时候做一些处理
service.prepareToLeaveProcess(this);
//进程间通信,到AMS中的bindService,然后返回结果
int res = ActivityManagerNative.getDefault().bindService(
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, getOpPackageName(), user.getIdentifier());
if (res < 0) {
//小于0 bind失败
throw new SecurityException(
"Not allowed to bind to service " + service);
}
return res != 0;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
3、ActivityManagerNative#getDefault().bindService
ActivityManagerNative:
static public IActivityManager getDefault() {
return gDefault.get();
}
============================================
//gDefault,这个是一个单例模式获取的
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
//关键:从ServiceManager中获取AMS服务的Binder,这个过程也是进程间通信
//这个是向serviceManager 发消息 GET_SERVICE,获取AMS的服务
//因为系统启动的时候所有的服务到会注册到serviceManager中被管理起来
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
//连接到下面的asInterface
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
============================================
//最终获取到的是ActivityManagerProxy的实列
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IActivityManager in =
(IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ActivityManagerProxy(obj);
}
4、ActivityManagerProxy#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();
//发送了binder验证字符串,这里是“activitymanager”
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;
}
我们可以看到这里是真正的发消息的地方,向AMS发消息,发送了一个操作命令BIND_SERVICE_TRANSACTION
1、binder的发消息写数据的时候是有顺序的,写和读要类型顺序一致才可以
2、这里写入数据后,直接读取返回值 int res = reply.readInt();,这里binder通信是同步的返回,当然Binder也可以异步
那么我们继续看AMS如何接受这个消息的
5、ActivityManagerService
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rudu1Woq-1637946523711)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20211126153048675.png)]
我们可以看到ActivityManagerService是继承自ActivityManagerNative的 说明AMS的接受消息是在AMN中完成的,这样说来ActivityManagerNative发送和接受的代码都在这个类里面,只不过ActivityManagerNative是两个副本在不同的进程中执行的
继续看AMN接收消息的部分
6、ActivityManagerNative#onTransact
@Override
//这里是AMS接收消息的地方
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
//代码省略
**************
//按照客户端发的消息顺序依次读取
case BIND_SERVICE_TRANSACTION: {
//验证binder的描述符,之前传的是"activitymanager"如果这个验证不成功就抛异常了
data.enforceInterface(IActivityManager.descriptor);
//这个是binder是客户端那边的binder,说白了是ActivityThread#ApplicationThread
//ApplicationThread 是一个binder
IBinder b = data.readStrongBinder();
//这个其实是ApplicationThreadNative里的内部代理类,ApplicationThreadProxy
//以后AMS要向客户端发消息就是通过ApplicationThreadProxy来实际操作发送的
IApplicationThread app = ApplicationThreadNative.asInterface(b);
//这个是activity里面的token,鉴别之用
IBinder token = data.readStrongBinder();
//获取要启动的service的Intent
Intent service = Intent.CREATOR.createFromParcel(data);
String resolvedType = data.readString();
//这个是那个回调Binder,
b = data.readStrongBinder();
int fl = data.readInt();
String callingPackage = data.readString();
//获取uid
int userId = data.readInt();
//转成IServiceConnection
IServiceConnection conn = IServiceConnection.Stub.asInterface(b);
//这里是关键函数了,调用了AMS的bindService
int res = bindService(app, token, service, resolvedType, conn, fl,
callingPackage, userId);
reply.writeNoException();
reply.writeInt(res);
return true;
}
**************
}
7、ActivityManagerService#bindService
public int bindService(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, IServiceConnection connection, int flags, String callingPackage,
int userId) throws TransactionTooLargeException {
enforceNotIsolatedCaller("bindService");
// 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");
}
synchronized(this) {
//调用了ActiveService 来做处理,并将参数传入进去
return mServices.bindServiceLocked(caller, token, service,
resolvedType, connection, flags, callingPackage, userId);
}
}
8、ActiveService#bindServiceLocked
//这个方法比较长 我做了简略写法,写关键函数
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);
if (callerApp == null) {
//当前进程==null就直接抛异常了
throw new SecurityException(
"Unable to find app for caller " + caller
+ " (pid=" + Binder.getCallingPid()
+ ") when binding service " + service);
}
ActivityRecord activity = null;
if (token != null) {
//如果这个activity没有在栈中就直接返回了,启动不了service
activity = ActivityRecord.isInStackLocked(token);
if (activity == null) {
Slog.w(TAG, "Binding with unknown activity: " + token);
return 0;
}
}
//这里要通过Intent 去查看这个Service,把查询的结果返回到ServiceLookupResult中
//里面做了很多的验证工作,比如果这个service不存在就抛异常,
//还有保存这些信息到缓存中
//比如这个service的intent的componentName是null的会设置进去
//ServiceLookupResult 里面有ServiceRecord对象,记录者关于Service的信息,这里持有一些外部信息比如ams
//总结来说:这里就是查询这个启动的这个服务是否合法,是否完成,是否可以启动,如果可以就设置信息,组装成最终结果ServiceLookupResult返回,如果有问题里面就抛异常或者返回null
ServiceLookupResult res =
retrieveServiceLocked(service, resolvedType, callingPackage, Binder.getCallingPid(),
Binder.getCallingUid(), userId, true, callerFg, isBindExternal); //如果null 就不启动,返回0 启动失败了
if (res == null) {
return 0;
}
----------分割线(1)--------------
boolean permissionsReviewRequired = false;
// If permissions need a review before any of the app components can run,
// we schedule binding to the service but do not start its process, then
// we launch a review activity to which is passed a callback to invoke
// when done to start the bound service's process to completing the binding.
if (mAm.mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) {
if (mAm.getPackageManagerInternalLocked().isPermissionsReviewRequired(
s.packageName, s.userId)) {
permissionsReviewRequired = true;
// Show a permission review UI only for binding from a foreground app
if (!callerFg) {
Slog.w(TAG, "u" + s.userId + " Binding to a service in package"
+ s.packageName + " requires a permissions review");
return 0;
}
final ServiceRecord serviceRecord = s;
final Intent serviceIntent = service;
RemoteCallback callback = new RemoteCallback(
new RemoteCallback.OnResultListener() {
@Override
public void onResult(Bundle result) {
synchronized(mAm) {
final long identity = Binder.clearCallingIdentity();
try {
if (!mPendingServices.contains(serviceRecord)) {
return;
}
// If there is still a pending record, then the service
// binding request is still valid, so hook them up. We
// proceed only if the caller cleared the review requirement
// otherwise we unbind because the user didn't approve.
if (!mAm.getPackageManagerInternalLocked()
.isPermissionsReviewRequired(
serviceRecord.packageName,
serviceRecord.userId)) {
try {
bringUpServiceLocked(serviceRecord,
serviceIntent.getFlags(),
callerFg, false, false);
} catch (RemoteException e) {
/* ignore - local call */
}
} else {
unbindServiceLocked(connection);
}
} finally {
Binder.restoreCallingIdentity(identity);
}
}
}
});
final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
intent.putExtra(Intent.EXTRA_PACKAGE_NAME, s.packageName);
intent.putExtra(Intent.EXTRA_REMOTE_CALLBACK, callback);
if (DEBUG_PERMISSIONS_REVIEW) {
Slog.i(TAG, "u" + s.userId + " Launching permission review for package "
+ s.packageName);
}
mAm.mHandler.post(new Runnable() {
@Override
public void run() {
mAm.mContext.startActivityAsUser(intent, new UserHandle(userId));
}
});
}
}
----------分割线(1)--------------
上面分割线(1)里要做的就是对这个服务启动的权限申请,启动的服务是否满足应该有的权限,发个Intent,然后弹出UI动态申请权限,如果用户统一了,就在RemoteCallback 里面继续执行bringUpServiceLocked 唤醒服务的核心函数
如果上面的权限满足,就不走上面的流程
/*
*
*
代码省略了
*
*
*/
//如果含有BIND_AUTO_CREATE的flag
if ((flags&Context.BIND_AUTO_CREATE) != 0) {
s.lastActivity = SystemClock.uptimeMillis();
//唤醒Service 这个是核心方法
if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
permissionsReviewRequired) != null) {
return 0;
}
}
}
if (s.app != null && b.intent.received) {
// Service is already running, so we can immediately
// publish the connection.
try {
//如果启动service成功了,就回调那个connect回调函数,回调函数通过binder 传入到app那边,然后回调app的那边的connect回调接口onServiceConnected方法
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) {
requestServiceBindingLocked(s, b.intent, callerFg, true);
}
} else if (!b.intent.requested) {
requestServiceBindingLocked(s, b.intent, callerFg, false);
}
9、ActiveService#bringUpServiceLocked
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
//Slog.i(TAG, "Bring up service:");
//r.dump(" ");
if (r.app != null && r.app.thread != null) {
//如果这个service已经启动了就执行Service的onStartCommand方法
//这些都是最终通过binder通信到ActivityThread中执行的
sendServiceArgsLocked(r, execInFg, false);
return null;
}
if (!whileRestarting && r.restartDelay > 0) {
//如果当前这个服务正在等待被重启中,这个状态下,什么都不做
// If waiting for a restart, then do nothing.
return null;
}
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bringing up " + r + " " + r.intent);
// We are now bringing the service up, so no longer in the
// restarting state.
//重启服务的列表重构移除这个服务,ServiceRecord
if (mRestartingServices.remove(r)) {
r.resetRestartCounter();
clearRestartingIfNeededLocked(r);
}
// Make sure this service is no longer considered delayed, we are starting it now.
if (r.delayed) {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (bring up): " + r);
getServiceMap(r.userId).mDelayedStartList.remove(r);
r.delayed = false;
}
// Make sure that the user who owns this service is started. If not,
// we don't want to allow it to run.
//启动这个服务之前 先确保这个服务所在的程序已经启动了
//这个就是要求我们启动某个服务之前 先把程序拉起来才可以
//应为uid是程序的唯一id,mAm.mUserController保存了启动程序的id
if (!mAm.mUserController.hasStartedUserState(r.userId)) {
String msg = "Unable to launch app "
+ r.appInfo.packageName + "/"
+ r.appInfo.uid + " for service "
+ r.intent.getIntent() + ": user " + r.userId + " is stopped";
Slog.w(TAG, msg);
//解绑服务,
bringDownServiceLocked(r);
return msg;
}
// Service is now being launched, its package can't be stopped.
try {
//这个服务要启动起来了,这个app不能关闭,当前给这个app的状态就是不会被杀的状态
AppGlobals.getPackageManager().setPackageStoppedState(
r.packageName, false, r.userId);
} catch (RemoteException e) {
} catch (IllegalArgumentException e) {
Slog.w(TAG, "Failed trying to unstop package "
+ r.packageName + ": " + e);
}
final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
final String procName = r.processName;
ProcessRecord app;
//这个标志意思是service会运行在一个特殊的进程中
//我们现在只考虑 运行在自己的app线程中情况
if (!isolated) {
//获取当前的进程对象
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
+ " app=" + app);
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);
}
// If a dead object exception was thrown -- fall through to
// restart the application.
}
} else {
// If this service runs in an isolated process, then each time
// we call startProcessLocked() we will get a new isolated
// process, starting another process if we are currently waiting
// for a previous process to come up. To deal with this, we store
// in the service any current isolated process it is running in or
// waiting to have come up.
app = r.isolatedProc;
}
// Not running -- get it started, and enqueue this service record
// to be executed when the app comes up.
if (app == null && !permissionsReviewRequired) {
//如果是隔离进程中启动服务的话,就先等待,然后开启一个新的进程,等那个新的进程启动了 在启动这个服务
if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
"service", r.name, false, isolated, false)) == null) {
//新的进程启动不了 就报错,然后关闭这个服务,这个服务以后有可能还会被唤醒
String msg = "Unable to launch app "
+ r.appInfo.packageName + "/"
+ r.appInfo.uid + " for service "
+ r.intent.getIntent() + ": process is bad";
Slog.w(TAG, msg);
bringDownServiceLocked(r);
return msg;
}
if (isolated) {
r.isolatedProc = app;
}
}
if (!mPendingServices.contains(r)) {
//将这个服务添加到 PendingServices中,达到某个条件后 然乎启动
//比如onstartcommand 的返回值 flag模式,会重启启动服务
mPendingServices.add(r);
}
if (r.delayedStop) {
// Oh and hey we've already been asked to stop!
r.delayedStop = false;
if (r.startRequested) {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,
"Applying delayed stop (in bring up): " + r);
stopServiceLocked(r);
}
}
return null;
}
9、ActiveService#realStartServiceLocked
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
if (app.thread == null) {
throw new RemoteException();
}
if (DEBUG_MU)
Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
+ ", ProcessRecord.uid = " + app.uid);
r.app = app;
r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
final boolean newService = app.services.add(r);
//发送一个延迟启动服务的消息
bumpServiceExecutingLocked(r, execInFg, "create");
mAm.updateLruProcessLocked(app, false, null);
mAm.updateOomAdjLocked();
boolean created = false;
try {
if (LOG_SERVICE_START_STOP) {
String nameTerm;
int lastPeriod = r.shortName.lastIndexOf('.');
nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName;
EventLogTags.writeAmCreateService(
r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);
}
synchronized (r.stats.getBatteryStats()) {
//开启耗电统计服务,BatteryStatsImpl 这个是实现类
r.stats.startLaunchedLocked();
}
mAm.notifyPackageUse(r.serviceInfo.packageName,
PackageManager.NOTIFY_PACKAGE_USE_SERVICE);
app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
//binder通信,通知ActivityThread 创建Service 然后启动
//这里我们跳转到ActivityThread的创建方法
//但是这个消息的发送是通过ApplicationThreadProxy发送消息的,里面的binder是ActivityThread中ApplicationThread这个binder
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
r.postNotification();
created = true;
} catch (DeadObjectException e) {
Slog.w(TAG, "Application dead when creating service " + r);
mAm.appDiedLocked(app);
throw e;
} finally {
if (!created) {
// Keep the executeNesting count accurate.
final boolean inDestroying = mDestroyingServices.contains(r);
serviceDoneExecutingLocked(r, inDestroying, inDestroying);
// Cleanup.
if (newService) {
//如果是新启动的Service 先清除ServiceRecord
app.services.remove(r);
r.app = null;
}
// Retry.
if (!inDestroying) {
//如果没有创建 就尝试重新启动服务
scheduleServiceRestartLocked(r, false);
}
}
}
if (r.whitelistManager) {
app.whitelistManager = true;
}
//这个是要等待service 启动了runing了 才去bind 最终会回调Service的onBind方法
//这些都是通过binder通信 通知activityThread 执行的
requestServiceBindingsLocked(r, execInFg);
updateServiceClientActivitiesLocked(app, null, true);
// If the service is in the started state, and there are no
// pending arguments, then fake up one so its onStartCommand() will
// be called.
if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
null, null));
}
//这个最终会回调Service的onstartCommand方法,这些都是通过binder通信 通知activityThread 执行的
sendServiceArgsLocked(r, execInFg, true);
if (r.delayed) {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (new proc): " + r);
getServiceMap(r.userId).mDelayedStartList.remove(r);
r.delayed = false;
}
if (r.delayedStop) {
// Oh and hey we've already been asked to stop!
r.delayedStop = false;
if (r.startRequested) {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,
"Applying delayed stop (from start): " + r);
stopServiceLocked(r);
}
}
}
10、ApplicationThreadNative#scheduleCreateService
public abstract class ApplicationThreadNative extends Binder
implements IApplicationThread {
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
{
*******
*******
*******
*******
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();
//这个方法会调用到ActivityThread#ApplicationThread中的scheduleCreateService方法
//
scheduleCreateService(token, info, compatInfo, processState);
return true;
}
******
*******
*******
*******
}
}
11、ApplicationThread#scheduleCreateService
//下面这个方法是ApplicationThread中的方法,重写了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;
//向ActivityThread里面的Handler发送个消息,然后处理
sendMessage(H.CREATE_SERVICE, s);
}
12、ActivityThread#handleMessage
handleReceiver((ReceiverData)msg.obj);
maybeSnapshot();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
//这个就是要create service里面
case CREATE_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
//这个是创建service的核心方法,在ActivityThread实现的
handleCreateService((CreateServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case BIND_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
handleBindService((BindServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
13、ActivityThread#handleCreateService
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) 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 设置给Service
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
//创建Application 设置给Service
Application app = packageInfo.makeApplication(false, mInstrumentation);
//执行service的attach 设置各种信息操作
service.attach(context, this, data.info.name, data.token, app,
ActivityManagerNative.getDefault());
//执行service的onCreate方法
service.onCreate();
mServices.put(data.token, service);
try {
//发送service已经启动的消息给AMS 相当于发个成功启动的回执消息
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
"Unable to create service " + data.info.name
+ ": " + e.toString(), e);
}
}
}
这个Service的onStrartCommand 还有在onBind 已经在前面的方法中的代码注释里写了,大家可以仔细看下
那么这个Service已经启动起来了,那我们继续看下Service的destory走的流程
14、Service#stopSelf
public final void stopSelf() {
stopSelf(-1);
}
/**
* Old version of {@link #stopSelfResult} that doesn't return a result.
*
* @see #stopSelfResult
*/
public final void stopSelf(int startId) {
//上面这个startid就是onStartCommad传进来的id,这个和stopself的startid是对应的,
if (mActivityManager == null) {
return;
}
try {
//这个mActivityManager 是哪里来的呢?
//还记得在ActivityThread创建Service的时候吗,执行了attach操作,最后一个参数是 //ActivityManagerNative.getDefault(),这个最终获取的是ActivityManagerProxy的实例, //binder传入的是从ServiceManager获取的远程AMS的binder,从而可以和AMS通信
mActivityManager.stopServiceToken(
new ComponentName(this, mClassName), mToken, startId);
} catch (RemoteException ex) {
}
}
stopServiceToken
这个binder的通信过程和之前启动Service过程一样,我就直接跳到AMS的stopService代码里看下
15、ActivityManagerService#stopServiceToken
AMS{
......
@Override
public boolean stopServiceToken(ComponentName className, IBinder token,
int startId) {
synchronized(this) {
//和之前的一样 还是要去ActiveService里操作
return mServices.stopServiceTokenLocked(className, token, startId);
}
}
......
}
16、ActiveService#stopServiceTokenLocked
boolean stopServiceTokenLocked(ComponentName className, IBinder token,
int startId) {
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "stopServiceToken: " + className
+ " " + token + " startId=" + startId);
ServiceRecord r = findServiceLocked(className, token, UserHandle.getCallingUserId());
if (r != null) {
if (startId >= 0) {
// Asked to only stop if done with all work. Note that
// to avoid leaks, we will take this as dropping all
// start items up to and including this one.
ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
if (si != null) {
while (r.deliveredStarts.size() > 0) {
ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
cur.removeUriPermissionsLocked();
if (cur == si) {
break;
}
}
}
if (r.getLastStartId() != startId) {
return false;
}
if (r.deliveredStarts.size() > 0) {
Slog.w(TAG, "stopServiceToken startId " + startId
+ " is last, but have " + r.deliveredStarts.size()
+ " remaining args");
}
}
synchronized (r.stats.getBatteryStats()) {
//关闭耗电统计服务
r.stats.stopRunningLocked();
}
r.startRequested = false;
if (r.tracker != null) {
r.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
SystemClock.uptimeMillis());
}
r.callStart = false;
//清空Binder远程调用端的pid 和uid 用本线程的pid 和uid代替,并返回一个tokenid
//这个tokenid 可以后面恢复使用的
final long origId = Binder.clearCallingIdentity();
//关闭远程端的Service
bringDownServiceIfNeededLocked(r, false, false);
//回复远程调用端的pid和uid
Binder.restoreCallingIdentity(origId);
return true;
}
return false;
}
17、ActiveService#bringDownServiceIfNeededLocked
private final void bringDownServiceIfNeededLocked(ServiceRecord r, boolean knowConn,
boolean hasConn) {
//Slog.i(TAG, "Bring down service:");
//r.dump(" ");
//还有明确的条件 指明这个服务需要运行吗
//如果没有就继续走下去
if (isServiceNeeded(r, knowConn, hasConn)) {
return;
}
// Are we in the process of launching?
//我们这个服务在launcher的进程中吗?如果是的话就不关闭
if (mPendingServices.contains(r)) {
return;
}
//关闭服务
bringDownServiceLocked(r);
}
18、ActiveService#bringDownServiceLocked
private final void bringDownServiceLocked(ServiceRecord r) {
//Slog.i(TAG, "Bring down service:");
//r.dump(" ");
// Report to all of the connections that the service is no longer
// available.
//告诉其他的和这个服务连接的客户端,这个服务不可以用了,连接要端了
for (int conni=r.connections.size()-1; conni>=0; conni--) {
ArrayList<ConnectionRecord> c = r.connections.valueAt(conni);
for (int i=0; i<c.size(); i++) {
ConnectionRecord cr = c.get(i);
// There is still a connection to the service that is
// being brought down. Mark it as dead.
cr.serviceDead = true;
try {
//这里binder传入的是null,所以 最终会回调 app端的disConnect的接口
//这里要说下,一个服务是可以和多个Client连接的,绑定的
cr.conn.connected(r.name, null);
} catch (Exception e) {
Slog.w(TAG, "Failure disconnecting service " + r.name +
" to connection " + c.get(i).conn.asBinder() +
" (in " + c.get(i).binding.client.processName + ")", e);
}
}
}
// Tell the service that it has been unbound.
//下面是回调远程端的Service的onUnbind 方法
if (r.app != null && r.app.thread != null) {
for (int i=r.bindings.size()-1; i>=0; i--) {
IntentBindRecord ibr = r.bindings.valueAt(i);
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bringing down binding " + ibr
+ ": hasBound=" + ibr.hasBound);
if (ibr.hasBound) {
try {
bumpServiceExecutingLocked(r, false, "bring down unbind");
mAm.updateOomAdjLocked(r.app);
ibr.hasBound = false;
//最终会回调Service端的onUnbind 方法
//这个过程也 binder通信 到ActivityThread 我就不分析了
r.app.thread.scheduleUnbindService(r,
ibr.intent.getIntent());
} catch (Exception e) {
Slog.w(TAG, "Exception when unbinding service "
+ r.shortName, e);
serviceProcessGoneLocked(r);
}
}
}
}
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bringing down " + r + " " + r.intent);
r.destroyTime = SystemClock.uptimeMillis();
if (LOG_SERVICE_START_STOP) {
EventLogTags.writeAmDestroyService(
r.userId, System.identityHashCode(r), (r.app != null) ? r.app.pid : -1);
}
final ServiceMap smap = getServiceMap(r.userId);
smap.mServicesByName.remove(r.name);
smap.mServicesByIntent.remove(r.intent);
r.totalRestartCount = 0;
//移除重新启动service的列表中的这个服务,因为这个是自己关闭的,所以不能重启服务了
unscheduleServiceRestartLocked(r, 0, true);
// Also make sure it is not on the pending list.
//还要把mPendingServices中移除这个Service,将来也不会启动了
for (int i=mPendingServices.size()-1; i>=0; i--) {
if (mPendingServices.get(i) == r) {
mPendingServices.remove(i);
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Removed pending: " + r);
}
}
cancelForegroudNotificationLocked(r);
r.isForeground = false;
r.foregroundId = 0;
r.foregroundNoti = null;
// Clear start entries.
r.clearDeliveredStartsLocked();
r.pendingStarts.clear();
if (r.app != null) {
synchronized (r.stats.getBatteryStats()) {
//关闭电池电量统计服务
r.stats.stopLaunchedLocked();
}
r.app.services.remove(r);
if (r.whitelistManager) {
updateWhitelistManagerLocked(r.app);
}
if (r.app.thread != null) {
updateServiceForegroundLocked(r.app, false);
try {
bumpServiceExecutingLocked(r, false, "destroy");
mDestroyingServices.add(r);
r.destroying = true;
mAm.updateOomAdjLocked(r.app);
//经过上面的把这个服务从当前的AMS中的信息中去除调,保证以后也不会自动重启服务了
//核心代码 调用了客户端的ActivityThread 停止服务
r.app.thread.scheduleStopService(r);
} catch (Exception e) {
Slog.w(TAG, "Exception when destroying service "
+ r.shortName, e);
serviceProcessGoneLocked(r);
}
} else {
if (DEBUG_SERVICE) Slog.v(
TAG_SERVICE, "Removed service that has no process: " + r);
}
} else {
if (DEBUG_SERVICE) Slog.v(
TAG_SERVICE, "Removed service that is not running: " + r);
}
if (r.bindings.size() > 0) {
r.bindings.clear();
}
if (r.restarter instanceof ServiceRestarter) {
((ServiceRestarter)r.restarter).setService(null);
}
int memFactor = mAm.mProcessStats.getMemFactorLocked();
long now = SystemClock.uptimeMillis();
if (r.tracker != null) {
r.tracker.setStarted(false, memFactor, now);
r.tracker.setBound(false, memFactor, now);
if (r.executeNesting == 0) {
r.tracker.clearCurrentOwner(r, false);
r.tracker = null;
}
}
smap.ensureNotStartingBackground(r);
}
前面说到了核心代码 r.app.thread.scheduleStopService?;
这个也是进程间通信,中间过程不说了,直接到ActivityThread中的代码来说
19、ActivityThread#handleStopService
private void handleStopService(IBinder token) {
//把当前的服务列表中移除这个服务
Service s = mServices.remove(token);
if (s != null) {
try {
if (localLOGV) Slog.v(TAG, "Destroying service " + s);
//执行这个service的onDestory方法
s.onDestroy();
Context context = s.getBaseContext();
if (context instanceof ContextImpl) {
final String who = s.getClassName();
//执行Service中的Context 清除工作
//比如反注册广播等
((ContextImpl) context).scheduleFinalCleanup(who, "Service");
}
//等待里面的异步线程runable执行完,才继续
QueuedWork.waitToFinish();
try {
//向AMS发送 关闭这个服务成功了的回执,然后在AMS也要对这个服务的信息做清理工作
ActivityManagerNative.getDefault().serviceDoneExecuting(
token, SERVICE_DONE_EXECUTING_STOP, 0, 0);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} catch (Exception e) {
if (!mInstrumentation.onException(s, e)) {
throw new RuntimeException(
"Unable to stop service " + s
+ ": " + e.toString(), e);
}
Slog.i(TAG, "handleStopService: exception for " + token, e);
}
} else {
Slog.i(TAG, "handleStopService: token=" + token + " not found.");
}
//Slog.i(TAG, "Running services: " + mServices);
}
我们来说下Service开始和停止的本质是什么,
启动了这个Service后,这个Service 执行了生命周期的方法,然后这个服务的信息就记录到AMS中了,以后系统发的消息,都会按照条件发送到Service中,比如广播等,这个Service是活着的,可以和外界通信
如果这个服务停止了,就把这个服务在AMS上注册的信息还有资源删除掉,这个服务无法和外界交互了,这个服务所持有的Context 都清理了,这个Service就无法正常工作了
好了到此为止吧,整个Service的启动还有结束就分析完了,由于技术有限,如有错误,期待评论中讨论~~~。
|