在早些年学习Android的时候,对Service有过总结,但是主要是如何去使用,注意事项,startService和bindService的区别。
Android Service_public int onstartcommand(intent intent, int flags-CSDN博客
但是今天从源码来总结下framework层的启动流程大致是什么样的。
一、startService()
平时,在我们的activity里,我们通过startService去启动一个service服务。
1.context.startService
使用例子:
//testActivity
@Override
public void onClick(View v) {
Intent it=new Intent(this, SimpleService.class);
switch (v.getId()){
case R.id.startService:
startService(it);
break;
case R.id.stopService:
stopService(it);
break;
}
这儿,实际上是调用的context上下文去调用的这个方法,那我们去看下里面的代码
@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, false, mUser);
}
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
try {
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), requireForeground,
getOpPackageName(), user.getIdentifier());
...
return cn;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
2.ActivityManager.getService().startService()
可以看到:核心代码为ActivityManager.getService().startService()
在 Activity 中使用的 startService 方法是定义在 Context 的抽象类中,它的真正实现类是 ContextImpl,所以先进入 ContextImpl 类。先从startService开始,然后进入本类的startServiceCommon方法,并最终调用ActivityManagerNative.getDefault()对象的 startService 方法。ActivityManager.getService()获取到IActivityManager对象,并且是通过单利模式创建的。
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
看下ActivityManager.getService()这个如果看过app启动流程就知道,这玩意儿在创建application和activity时也看到过。这儿用到了binder实现进程间通信,最后走到了AMS里面
看下ActivityManagerService中startService()代码
这里面走到了startServiceLocked()方法,其中mServices是ActiveServices。
ActiveServices这里面进行了以下步骤:
1.通过 retrieveServiceLocked 方法来解析 service 这个 Intent,就是解析前面我们在 AndroidManifest.xml 定义的 Service 标签的 intent-filter 相关内容,然后将解析结果放在 res.record 中。
2.调用 startServiceInnerLocked 方法。
在startServiceInnerLocked 方法中会调用 bringUpServiceLocked 方法。
3.bringUpServiceLocked方法中,当 Service 所在的进程存在时,将调用realStartServiceLocked 方法来启动 Service,否则的话调用 startProcessLocked 方法来启动新进程。
情况一:realStartServiceLocked()