1.
1.一个service只要是通过start方法启动的.无论调用几次,无论是否调用bindService.都只能通过stop方法结束且,统只会创建一个Service实例.
2.一个startService方法就会对应一个onStartCommand,bindService不会回调onStartCommand方法
3.通过bindService启动的服务,只能通过unbindService接触绑定,调用该Service的Context不存在了(如Activity被Finish——因为bindService启动的Service的生命周期依附于启动它的Context),系统在这时会自动停止该Service。
4.当手机屏幕发生旋转时,如果Activity设置的是自动旋转的话,在旋转的过程中,Activity会重新创建,那么之前通过bindService 建立的连接便会断开(之前的Context不存在了),服务也会被自动停止
5.多次调用bindeService. onBind不会多次执行.
6.如果同时使用startService 与bindService 方法启动Service,需要终止该Service时,要调用stopService 和unbindService 方法(unbindService 依附于启动它的Context,startServicec 并不依附于启动它的Context。如果先调用unbindService ,这时服务并不会被终止,当调用stopService 后,服务才会被终止;如果先调用stopService ,服务也不会被终止,当调用unbindService 或者之前调用bindService 的Context不存在了(如Activity被finish掉了)服务才会自动停止)
6.onStartCommand的返回值,默认情况下,使用startService()方法激活的Service组件是粘性的,
START_STICKY:粘性的,被意外中止后自动重启,但丢失原来激活它的Intent
START_NO_STICKY:非粘性的,被意外中止后不会重新启动;
START_REDELIVER_INTENT:粘性的且重新发送Intent,即被意外中止后自动重启,
且该Service组件将得到原来用于激活它的Intent对象;
7.一个App里,同一个Activity多次bind一个服务,除了第一次,后面的bind不会有任何onBind、onServiceConnected打印。不同的Activity去bind一个服务,第一次bind有onBind、onServiceConnected打印,后面的bind只会有onServiceConnected打印
2.启动过程
- ContextWrapper的startService.
所有的service,activity都继承自ContextWrapper,其实就是继承自Context.而ContextWrapper是一个包装类,主要的Context核心功能在ComtextImpl类里,而系统创建Activity和Service时,就为我们创建了ContextImpl类.存在ContextWrapper的mBase变量里.
public ComponentName startService(Intent service) { 调用了ContextImpl的方法,接着看
return mBase.startService(service);
}
- ContextImpl.startService
1.
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, mUser);
}
2. 这个方法最重要的就是.跨进程调用Ams来启动service.
private ComponentName startServiceCommon(Intent service, UserHandle user) {
try {
validateServiceIntent(service); //1.验证intent的合法性
service.prepareToLeaveProcess();
//2.这是核心代码.ActivityManagerNative.getDefault()就是ActivityManagerProxy,是Ams的本地binder代理.
ComponentName cn = ActivityManagerNative.getDefault().startService(
mMainThread.getApplicationThread(), service,
service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
if (cn != null) {
if (cn.getPackageName().equals("!")) {
throw new SecurityException( //3不具备调用目标Service的权限
"Not allowed to start service " + service
+ " without permission " + cn.getClassName());
} else if (cn.getPackageName().equals("!!")) {
throw new SecurityException(//4// 无法启动目标Service的处理
"Unable to start service " + service
+ ": " + cn.getClassName());
}
}
return cn;
} catch (RemoteException e) {
return null;
}
}
- Ams.startService 接下来就是Ams对service的操作.接着看.
//参数IApplicationThread caller 就是ActivityThread的内部类Application在服务端的代理
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, int userId) {
//1.决绝孤立的进程执行 starService操作
enforceNotIsolatedCaller("startService");
// 2.拒绝包含可能造成内存泄露的文件描述符的Intent
if (service != null && service.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
synchronized(this) {
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
//3.这里调用了ActiveServices 的方法.ActiveServices负责Service的组件调用和维护Service的状态信息
ComponentName res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid, userId);
Binder.restoreCallingIdentity(origId);
return res;
}
- ActiveServices.startServiceLocked 本方对调用者检测,同时.如果是后台进程.要延迟启动.
ComponentName startServiceLocked(IApplicationThread caller,
Intent service, String resolvedType,
int callingPid, int callingUid, int userId) {
final boolean callerFg;
if (caller != null) {//1.这个mAm就是ActivityManagerService
final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
if (callerApp == null) {//2.在ActivityManagerService中查询不到调用者,直接抛出异常。
throw new SecurityException(
"Unable to find app for caller " + caller
+ " (pid=" + Binder.getCallingPid()
+ ") when starting service " + service);
}
//3.判断调用方是前台进程还是后台进程
callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
} else {
callerFg = true;
}
//4.检索匹配Service组件信息
ServiceLookupResult res =
retrieveServiceLocked(service, resolvedType,
callingPid, callingUid, userId, true, callerFg);
if (res == null) { //5.没有匹配到Service组件就返回
return null;
}
ServiceRecord r = res.record;
//5. 如果目标的Service正在被请求重启,但还未重启,取消这个请求
if (unscheduleServiceRestartLocked(r, callingUid, false)) {
if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
}
r.lastActivity = SystemClock.uptimeMillis();
r.startRequested = true;
r.delayedStop = false;
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
service, neededGrants));//这个ServiceRecord是Service的记录,会贯穿整个启动过程
final ServiceMap smap = getServiceMap(r.userId);//smap是一个handler
boolean addToStarting = false;
//6.这里是对后台服务的处理,如果启动的是后台服务.就延迟启动他.
防止多个进程启动service发生
if (!callerFg && r.app == null && mAm.mStartedUsers.get(r.userId) != null) {
ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
if (proc == null || proc.curProcState > ActivityManager.PROCESS_STATE_RECEIVER) {
if (r.delayed) {
//7. 目标Service正在启动中,但还没有启动完成
return r.name;
}
if (smap.mStartingBackground.size() >= mMaxStartingBackground) {
//8.该进程有其它组件正在启动,加入到延迟启动列表,等待它完成后再启动。
smap.mDelayedStartList.add(r);
r.delayed = true;
return r.name;
}
addToStarting = true;
} else if (proc.curProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
addToStarting = true;
}
} //8.继续调用.启动service
return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
}
- AcivityService.startServiceInnerLocked
启动了对Service内存消耗和电量消耗的跟踪,
最重要的是调用bringUpServiceLocked 真正启动service
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service,
ServiceRecord r, boolean callerFg, boolean addToStarting) {
ProcessStats.ServiceState stracker = r.getTracker();
if (stracker != null) {//1.跟踪Service的内存消耗
stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
}
r.callStart = false;
synchronized (r.stats.getBatteryStats()) {
r.stats.startRunningLocked();//2.跟踪Service的耗电量
}
//3.通知客户端进程启动Service
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
if (error != null) {
return new ComponentName("!!", error);//4.启动失败.
}
if (r.startRequested && addToStarting) {
boolean first = smap.mStartingBackground.size() == 0;
smap.mStartingBackground.add(r);
r.startingBgTimeout = SystemClock.uptimeMillis() + BG_START_TIMEOUT;//5.设定客户端Service启动超时的时间
if (DEBUG_DELAYED_SERVICE) {
RuntimeException here = new RuntimeException("here");
here.fillInStackTrace();
Slog.v(TAG, "Starting background (first=" + first + "): " + r, here);
} else if (DEBUG_DELAYED_STARTS) {
Slog.v(TAG, "Starting background (first=" + first + "): " + r);
}
if (first) {
smap.rescheduleDelayedStarts();
}
} else if (callerFg) {
smap.ensureNotStartingBackground(r);
}
return r.name;
}
- AcivityService.bringUpServiceLocked
这个方法就是如果service正在启动就什么都不做,如果service的进程已存在就接着启动service,
如果进程不存在,则要先启动进程.
private final String bringUpServiceLocked(ServiceRecord r,
int intentFlags, boolean execInFg, boolean whileRestarting) {
if (r.app != null && r.app.thread != null) {
//1.如果已经启动.这个方法会通过ApplicationThread传递到ActivityThread
然后调用wevice的onStartCommand方法
sendServiceArgsLocked(r, execInFg, false);
return null;
}
//2.如果目标Service正在等待restart完成,什么都不用做,直接返回
if (!whileRestarting && r.restartDelay > 0) {
// If waiting for a restart, then do nothing.
return null;
}
//3.从正在重启的Service列表中移除目标Service
if (mRestartingServices.remove(r)) {
clearRestartingIfNeededLocked(r);
}
// 4.目标Service不再是delayed状态
if (r.delayed) {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "REM FR DELAY LIST (bring up): " + r);
getServiceMap(r.userId).mDelayedStartList.remove(r);
r.delayed = false;
}
// 5.确保目标Service所属的User处于started状态,否则不能启动service
if (mAm.mStartedUsers.get(r.userId) == null) {
String msg = "Unable to launch app "
+ r.appInfo.packageName + "/"
+ r.appInfo.uid + " for service "
+ r.intent.getIntent() + ": user " + r.userId + " is stopped";
bringDownServiceLocked(r);
return msg;
}
//6.Service即将被启动,它所属的Package不能被停止
try {
AppGlobals.getPackageManager().setPackageStoppedState(
r.packageName, false, r.userId);
} catch (RemoteException e) {
}
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 {//7.此时目标进程已创建,为该进程添加package,创建并启动目标Service
app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
realStartServiceLocked(r, app, execInFg);
return null;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting service " + r.shortName, e);
}
}
} else {
app = r.isolatedProc;
}
//8.没有目标进程,通过ActivityManagerService来创建目标进程,调用将阻塞到目标进程创建完成为止
if (app == null) {
if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
"service", r.name, false, isolated, false)) == null) {
//9.运行到这里说明目标进程创建失败
String msg = "Unable to launch app "
+ r.appInfo.packageName + "/"
+ r.appInfo.uid + " for service "
+ r.intent.getIntent() + ": process is bad";
bringDownServiceLocked(r);
return msg;
}
if (isolated) {
r.isolatedProc = app;
}
}
//10.将目标Service添加到 正在启动Service但未启动完成 的Service列表中
if (!mPendingServices.contains(r)) {
mPendingServices.add(r);
}
return null;
}
- ActivityService.realStartServiceLocked 接着看正常的执行流程
这个方法的重要部分就是远程调用到ActivityThread中的onStart,onBind,onStartCommand方法.
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
r.app = app;
r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
app.services.add(r);
bumpServiceExecutingLocked(r, execInFg, "create");
mAm.updateLruProcessLocked(app, false, null);
mAm.updateOomAdjLocked();
boolean created = false;
try {
synchronized (r.stats.getBatteryStats()) {
r.stats.startLaunchedLocked();
}
//1.确保目标App的Dex已经优化完成
mAm.ensurePackageDexOpt(r.serviceInfo.packageName);
app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
//2.通过ApplicationThread.夸进程到ActivityThread启动service.执行service的onAttach,onCreat
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
r.postNotification();
created = true;
} catch (DeadObjectException e) {
mAm.appDiedLocked(app);
} finally {
if (!created) {//
app.services.remove(r);
r.app = null;
scheduleServiceRestartLocked(r, false);
return;
}
}
//3. 如果Service需要绑定,则绑定目标Service,bindingServices时一定会执行.
他最后会执行到onBind方法.
requestServiceBindingsLocked(r, execInFg);
updateServiceClientActivitiesLocked(app, null, true);
if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
null, null));
}
//4.通知客户端ApplicationThread调用目标Service的onStartCommand方法
sendServiceArgsLocked(r, execInFg, true);
if (r.delayed) {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "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, "Applying delayed stop (from start): " + r);
stopServiceLocked(r);
}
}
}
- app.thread.scheduleCreateService是核心方法.app.thread 就是ApplicationThread在服务器端的代理,这是binder机制,这里不说了.最后就是ApplicationThread发送message,交给ActivityThread的handler处理,最后待用了handleCreateService 方法.内部就是加载了service,执行他的attach,onCreate,并通知ams
AcitivityThread.handleCreateService
private void handleCreateService(CreateServiceData data) {
//1.如果当前已经准备好gc了.那么取消gc,因为我们要添加新东西
unscheduleGcIdler();
//2.取得App对应的LoadedApk
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
//3. 通过反射来创建Service实例
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = (Service) cl.loadClass(data.info.name).newInstance();
} catch (Exception e) {
}
try {
//4.创建Service的base context
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
//5.取得Application
Application app = packageInfo.makeApplication(false, mInstrumentation);
//6.填充信息到Service
service.attach(context, this, data.info.name, data.token, app,
ActivityManagerNative.getDefault());
service.onCreate();
//7.将创建完成的Service放入mServices这个Map中
mServices.put(data.token, service);
try {
//8 通知服务端,Service启动完成。
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, 0, 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);
}
}
}
- 步骤7.4的方法sendServiceArgsLocked 最后调用到ActivityThread.handleServiceArgs
其实就是执行 onStartCommand
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) { //1.调用onStartCommand
res = s.onStartCommand(data.args, data.flags, data.startId);
} else {
//2.如果你写了这个标签 FLAG_STOP_WITH_TASK |FLAG_STOP_WITH_TASK就走这里.(目前不懂)
s.onTaskRemoved(data.args);
res = Service.START_TASK_REMOVED_COMPLETE;
}
QueuedWork.waitToFinish();
try {//2.通知ams,service已经启动成功
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, 1, data.startId, res);
}
ensureJitEnabled();
} catch (Exception e) {
}
}
}
3.绑定过程
- 先看一下绑定的写法.
Intent service = new Intent(this , ServcieDemo.class);
/**
* 第一个参数:intent对象
* 第二个参数:servcieConnection 用于监听服务当前的状态
* 第三个参数:BIND_AUTO_CREATE 服务自动创建,然后绑定。
*/
bindService(service, new MyConn(), BIND_AUTO_CREATE);
- 看下MyConn的类
class MyConn implements ServiceConnection{
/**
* 如果服务能够成功绑定上,那么这个方法将会调用,启动的参数service就是服务返回的内部对象 MyBinder
*/
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//获取到服务内部返回的代理对象 ,用binder承接起来
binder = (MyBinder) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {}
}
3.在看下service里和重要代码
public IBinder onBind(Intent intent) { //service内部方法
//返回内部代理对象
return new MyBinder();
}
class MyBinder extends Binder{//自己写的service内部类
/**
* 内部人员中固有的方法,它的作用就让别人来访问它,然后它自己去访问服务中的方法。
* 通过迂回的手段达到从外部类调用服务中的方法效果。
*/
public void callMethodInService(String name , int money){
methodInService(name , money);
}
}
4.总结一下.就是service里通过onBind 会返回给绑定service的Activity一个Binder代理,我们通过这个Binder可以访问调用Service的服务.当然这个Binder可以是同一个进程的,这种很简单,也可能因为Service是另一个进程,这就设计ipc,所以系统对Connection在内部又做了封装,就是为了适应跨进程的问题.
5.看代码.
ContextWrapper的绑定方法,也是调用ContextImpl的方法.同startService一样的.
@Override
public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
return mBase.bindService(service, conn, flags);
}
ContextImpl类内部
public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
warnIfCallingFromSystemProcess();
return bindServiceCommon(service, conn, flags, Process.myUserHandle());
}
//1.这个conn就是我们绑定时候写的conn.
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
UserHandle user) {
IServiceConnection sd;
if (mPackageInfo != null) {
//2.mPackageInfo是LoadedApk类.这里对conn进行了封装,使conn里的binder可以支持IPC
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
mMainThread.getHandler(), flags);
} else {
throw new RuntimeException("Not supported in system context");
}
validateServiceIntent(service);
try {
IBinder token = getActivityToken();
//3.这里调用的Ams的bindService方法,可以看到.这里没有把conn传输过去,而是传递的sd对象
int res = ActivityManagerNative.getDefault().bindService(
mMainThread.getApplicationThread(), getActivityToken(),
service, service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, user.getIdentifier());
return res != 0;
} catch (RemoteException e) {
return false;
}
}
6.先看一下5.1的代码,在LoadedApk中.LoadeApk内部有个mServices,存放所有Context对应的
ArrayMap
又对应一个ServiceDispatcher, ServiceDispatcher内部有个InnerConnection的内部类,这个类继承自Stub,
也就是一个Binder,是用来夸进程通讯用的.调用Ams的bindServices时,会调用InnerConnection的方法,InnerConnection在通知connection.ServiceDispatcher则是把二者联系在一起.
ublic final IServiceConnection getServiceDispatcher(ServiceConnection c,
Context context, Handler handler, int flags) {
synchronized (mServices) {
LoadedApk.ServiceDispatcher sd = null;//1.得到context对应的map对象.
ArrayMap map = mServices.get(context);
if (map != null) {
sd = map.get(c);//2.得到ServiceDispatcher对象,
}
if (sd == null) {//3.创建ServiceDispatcher对象是内部也创建了InnerConnection对象,
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();//4.这里返回的就是InnerConnection对象.
}
}
7.接着看5.3的代码.调用到Ams的BindService
原理同startService一样.都是在ActiveServices里处理.
public int bindService(IApplicationThread caller, IBinder token,
Intent service, String resolvedType,
//1.拒绝包含可能造成内存泄露的文件描述符的Intent
if (service != null && service.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
synchronized(this) {
return mServices.bindServiceLocked(caller, token, service, resolvedType,
connection, flags, userId);
}
}
8.ActiveServices.bindServiceLocked
方法的目的是找到调用者,然后封装绑定相关的数据. AppBindRecord ConnectionRecord
int bindServiceLocked(IApplicationThread caller, IBinder token,
Intent service, String resolvedType,
IServiceConnection connection, int flags, int userId) {
//1.在ActivityManagerService中查询不到调用者,直接抛出异常。
final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
if (callerApp == null) {
throw new SecurityException(
"Unable to find app for caller " + caller
+ " (pid=" + Binder.getCallingPid()
+ ") when binding service " + service);
}
ActivityRecord activity = null;
if (token != null) {//2.activity没找到. ActivityRecord 是activity的数据记录对象.
activity = ActivityRecord.isInStackLocked(token);
if (activity == null) {
Slog.w(TAG, "Binding with unknown activity: " + token);
return 0;
}
}
int clientLabel = 0;
PendingIntent clientIntent = null;
final boolean callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
//3.是获取根据intent、binder等数据获取Service的信息,其中ServiceLookupResult包含了ServiceRecord和权限信息
ServiceLookupResult res =
retrieveServiceLocked(service, resolvedType,
Binder.getCallingPid(), Binder.getCallingUid(), userId, true, callerFg);
if (res == null) {
return 0;
}
if (res.record == null) {
return -1;
}
ServiceRecord s = res.record;
final long origId = Binder.clearCallingIdentity();
//4.这里跟踪service的消耗.
if ((flags&Context.BIND_AUTO_CREATE) != 0) {
s.lastActivity = SystemClock.uptimeMillis();
if (!s.hasAutoCreateConnections()) {
// This is the first binding, let the tracker know.
ProcessStats.ServiceState stracker = s.getTracker();
if (stracker != null) {
stracker.setBound(true, mAm.mProcessStats.getMemFactorLocked(),
s.lastActivity);
}
}
}
//5.维持应用和service的关系
AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
//6.进程和Service建立起的本次通信,记一次ConnectionRecord
ConnectionRecord c = new ConnectionRecord(b, activity,
connection, flags, clientLabel, clientIntent);
IBinder binder = connection.asBinder();
//7.主要代码,调用bringUpServiceLocked继续绑定线程
//BIND_TREAT_LIKE_ACTIVITY可以降低Service被杀的概率、重新回调connected、rebind等
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) {
if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
s.app.treatLikeActivity = true;
}
// 8.使service变得更重要,应该是改变进程的优先级.
mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities
|| s.app.treatLikeActivity, b.client);
mAm.updateOomAdjLocked(s.app);
}
//9.服务已经启动.直接发布连接
if (s.app != null && b.intent.received) {
// Service is already running, so we can immediately
// publish the connection.
try {
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);
}
getServiceMap(s.userId).ensureNotStartingBackground(s);
} finally {
Binder.restoreCallingIdentity(origId);
}
return 1;
}
- 接着看ActivityServices.bringUpServiceLocked ,这里的执行和启动service的步骤6 以后都是差不多的,因为是同样的方法,bringUpServiceLocked在调用realStartServiceLocked,这里会执行startService过程中7.3的requestServiceBindingsLocked方法.我们在这里看
private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg) {
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) {
if (r.app == null || r.app.thread == null) {
// If service is not currently running, can't yet bind.
return false;
}
if ((!i.requested || rebind) && i.apps.size() > 0) {
try {
//1.r.app.thread就是ApplicationThread在Ams端的代理,这个方法会夸进程掉调用到ApplicationThread的方法,然后发送message执行到ActivityThread 的主线程.
bumpServiceExecutingLocked(r, execInFg, "bind");
r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
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) {
if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
return false;
}
}
return true;
}
10.ActivityThread.handleBindService
本地处理service的方法.回调了onBind方法,同时通知了Ams
private void handleBindService(BindServiceData data) {
//1.先根据Token 取出service.
Service s = mServices.get(data.token);
if (s != null) {
try {
data.intent.setExtrasClassLoader(s.getClassLoader());
data.intent.prepareToEnterProcess();
try {
if (!data.rebind) {
//1.调用了service的onBind方法,onBind方法会返回给客户端一个Binder对象,
到这里原则上service已经绑定成功了.但是客户端还不知道,所以我们要通过
调用客户端的SerciveConnection的onServiceConnected方法.
IBinder binder = s.onBind(data.intent);
//2.这个重要,通知Ams,注意,这里的binder是service中用户提供的binder,
ActivityManagerNative.getDefault().publishService(
data.token, data.intent, binder);
} else {
s.onRebind(data.intent);
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, 0, 0, 0);
}
ensureJitEnabled();
} catch (RemoteException ex) {
}
} catch (Exception e) {
if (!mInstrumentation.onException(s, e)) {
throw new RuntimeException(
"Unable to bind to service " + s
+ " with " + data.intent + ": " + e.toString(), e);
}
}
}
11.ActivtiyManagerService.publishService
还是交给了ActivityServices来处理.
public void publishService(IBinder token, Intent intent, IBinder service) {
// Refuse possible leaked file descriptors //1.拒绝可能存在的文件描述符泄漏.
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");
}//2.还是通过ActivityServices来处理
mServices.publishServiceLocked((ServiceRecord)token, intent, service);
}
}
ActivityServices.publishServiceLocked方法执行了ServiceDispatcher.InnerConnection的connected方法
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
11.看InnerConnection.connected方法.
其实就是调用了ServiceDispatcher 的connected方法.
InnerConnection.connected
public void connected(ComponentName name, IBinder service) throws RemoteException {
LoadedApk.ServiceDispatcher sd = mDispatcher.get();
if (sd != null) {
sd.connected(name, service);//1.执行ServiceDiaptacher的connected方法
}
}
ServiceDiaptacher.connected
public void connected(ComponentName name, IBinder service) {
if (mActivityThread != null) {
//2.主要执行这个.因为mActivityThread 是主线程的handler,不会为空,
其实最后就是执行RunConnection的run方法.在主线程中.接着看.
mActivityThread.post(new RunConnection(name, service, 0));
} else {
doConnected(name, service);
}
}
RunConnection.run
public void run() {
if (mCommand == 0) {
//这里,因为上边传入的是0,RunConnection是ServiceDispatcher 的内部类,
doConnected在ServiceDispatcher 中
doConnected(mName, mService);
} else if (mCommand == 1) {
doDeath(mName, mService);
}
}
12.ServiceDispatcher.doConnected
这里最终完成了用户绑定service是传入的ServiceConnection.onServiceConnected方法.
public void doConnected(ComponentName name, IBinder service) {
ServiceDispatcher.ConnectionInfo old;
ServiceDispatcher.ConnectionInfo info;
synchronized (this) {
if (mForgotten) {
//如果正在解绑service,就忽略connection
return;
}
old = mActiveConnections.get(name);
if (old != null && old.binder == service) {
// 存在connection. 返回
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);//保存content对应的connection.
} catch (RemoteException e) {
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) {
//最重要这一行,调用ServiceConnection的onServiceConnected
这样,客户端就收到了service绑定后返回的binder.
mConnection.onServiceConnected(name, service);
}
}