您的位置:首页 > 移动开发 > Android开发

Service启动流程源码分析(一):startService

2017-10-23 22:07 756 查看

Service启动流程源码分析(一):startService

Service是Android组件中最基本也是最为常见用的四大组件之一,分析Service启动流程源码可以加深对Service的了解。Service一共有两种状态,启动和绑定,本文先分析Service启动的流程,大体上和之前的Activity启动流程类似。

Service启动流程源码分析(二):bindService

启动流程

Activity

本文从Activity的startService(Intent service)入手分析

Activity的startService(Intent service)代码如下

@Override
public ComponentName startService(Intent service) {
// mBase在之前Activity启动流程中分析过,是在Activity的attach方法中赋值的,是一个ContextImpl
return mBase.startService(service);
}


调用ContextImpl的startService(service),代码如下

@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, mUser);
}


调用ContextImpl的startServiceCommon(Intent service, UserHandle user),代码如下

private ComponentName startServiceCommon(Intent service, UserHandle user) {
try {
// Android 5.0之后不允许隐式启动Service
validateServiceIntent(service);
// Binder调用ActivityManagerNative.getDefault()启动Service,同Activity的启动
ComponentName cn = ActivityManagerNative.getDefault().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), getOpPackageName(), user.getIdentifier());
...
return cn;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}


Android 5.0之后不允许隐式启动Service,个人觉得Google是为了安全考虑,限制代码如下

private void validateServiceIntent(Intent service) {
// 5.0以上启动Service时切记要设置相关内容
if (service.getComponent() == null && service.getPackage() == null) {
if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
IllegalArgumentException ex = new IllegalArgumentException(
"Service Intent must be explicit: " + service);
throw ex;
} else {
Log.w(TAG, "Implicit intents with startService are not safe: " + service
+ " " + Debug.getCallers(2, 3));
}
}
}


ActivityManagerService

public abstract class ActivityManagerNative extends Binder implements IActivityManager

public interface IActivityManager extends IInterface

从中可以看出ActivityManagerNative是一个Binder类,Service的启动已经通过Binder调用转交到系统服务中了。

IActivityManager Binder具体实现是ActivityManagerService,最终调用到ActivityManagerService的startService

调用进入ActivityManagerService的进程

ActivityManagerService的startService(IApplicationThread caller, Intent service,

String resolvedType, String callingPackage, int userId)是一次Binder调用,代码如下

@Override
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, String callingPackage, int userId)
throws TransactionTooLargeException {
...
synchronized(this) {
...
// mServices是一个ActiveServices
ComponentName res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid, callingPackage, userId);

return res;
}
}


ActiveServices

ActiveServices是AMS中专门抽出来管理Service活动的类,包括启动、绑定等。

ActiveServices的startServiceLocked调用了startServiceInnerLocked

startServiceInnerLocked调用了bringUpServiceLocked

bringUpServiceLocked调用了realStartServiceLocked

realStartServiceLocked代码如下

private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
...
try {
...
// 第一步,主要就是通过app.thread(ApplicationThread)Binder调用scheduleCreateService启动Service
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
...
}
// 第二步,sendServiceArgsLocked调用了ApplicationThread的scheduleServiceArgs方法
sendServiceArgsLocked(r, execInFg, true);
...

}


ApplicationThread

IApplicationThread thread;

public interface IApplicationThread extends IInterface

public abstract class ApplicationThreadNative extends Binder implements IApplicationThread

ApplicationThreadNative的具体实现是ActivityThread中的ApplicationThread

ApplicationThread实现了许多Activity和Service 启动、暂停等有关的操作

调用进入应用程序的进程

第一步,调用ApplicationThread的scheduleCreateService,是一次Binder调用

public final void scheduleCreat
4000
eService(IBinder token,
ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
...
// 类似Activity启动,通过mH发送一条CREATE_SERVICE消息
sendMessage(H.CREATE_SERVICE, s);
}


mH收到H.CREATE_SERVICE,调用handleCreateService(CreateServiceData data),代码如下

private void handleCreateService(CreateServiceData data) {

LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
// 实例化Service
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = (Service) cl.loadClass(data.info.name).newInstance();
}

try {
// 创建ContextImpl
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);

// 尝试创建Application
Application app = packageInfo.makeApplication(false, mInstrumentation);
// 将之前创建的ContextImpl给service的mBase赋值
service.attach(context, this, data.info.name, data.token, app,
ActivityManagerNative.getDefault());
// 调用Service的onCreate方法
service.onCreate();
// 将service对象保存在ActivityThread中
//     final ArrayMap<IBinder, Service> mServices = new ArrayMap<>();

mServices.put(data.token, service);
try {
// 调用AMS的serviceDoneExecuting

ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
}
...
}
}


第二步,调用ApplicationThread的scheduleServiceArgs,是一次Binder调用

scheduleServiceArgs类似scheduleCreateService,通过mH发送H.SERVICE_ARGS,mH收到消息调用handleServiceArgs(ServiceArgsData data),代码如下

private void handleServiceArgs(ServiceArgsData data) {
Service s = mServices.get(data.token);
if (s != null) {
try {

if (!data.taskRemoved) {
// 调用Service的onStartCommand方法
res = s.onStartCommand(data.args, data.flags, data.startId);
}
...
}
...
}


handleServiceArgs最终调用了Service的onStartCommand方法

总结

流程图待补充

Service启动流程源码分析(二):bindService

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android service 源码