当请求启动一个服务时,ActivityManagerService 首先会通过IPC调用到ActivityThread的scheduleCreateService()方法中,该方法的参数中有一个是Servicelnfo类参数,它是实现了 一 个Parcelable接口的数据类,该对象由AmS创建,并通过IPC传递到ActivityThread内部。
在scheduleCreateService()方法中,会使用这些参数构造 一 个CreateServiceData的数据对象,ActivityThread会为其所包含的每 一 个Service创建该数据对象,并通过这些对象来管理Service,接着,会执行handleCreateService()方法。
public final class ActivityThread {
......
private void handleCreateService(CreateServiceData data) {
......
(1)创建Service实例
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
Service service = null;
try {
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = (Service) cl.loadClass(data.info.name).newInstance();
} catch (Exception e) {
......
}
try {
(2)创建Service的Context
ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
context.setOuterContext(service);
(3)创建Application实例
Application app = packageInfo.makeApplication(false, mInstrumentation);
(4)初始化Service
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
service.onCreate();
(5)保存Service实例
mServices.put(data.token, service);
......
} catch (Exception e) {
......
}
}
......
}我们可以将这个方法中的逻辑分为五大部分,首先通过反射来实例化一个Service对象,这和上面创建Activity实例是一样的,默认构造方法什么也不做,Service实例的初始化工作也在attach方法中。第二步:接着调用ContextImpl类的createAppContext静态方法来创建一个Service的ContextImpl实例对象,随后通过这个Contextlmpl 类型实例context调用setOuterContext()方法把service对象赋值给Contextlmpl的mOuterContext变量,这样ContextImpl对象就持有Service对象,可以调用Service中的方法和变量。第三步:接着会创建Application实例对象,由于进程启动的时候就已经创建了Application,这里会直接返回这个Application对象。第四步:等Service实例对象和Application对象创建完成后,接着会调用Service对象的attach方法来初始化这个Service实例,attach方法内部会调用其父类ContextWrapper中的attachBaseContext(context)方法,并且将Contextlmpl类实例作为参数传入,保存在其父类ContextWrap的mBase实例变量中,这样Service中就持有了Contextlmpl类实例,这个和初始化Activity一样的。初始化完Service后,会调用其onCreate方法,用户可在在这个方法里做自己的初始化工作。最后,会将这个Service对象保存在ActivityThread类中的一个数组实例变量中。class ContextImpl extends Context {
......
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
null);
context.setResources(packageInfo.getResources());
return context;
}
......
} createAppContext()方法需要两个参数,一个是LoadApk类型的对象,另一个是 ActivityThread类型对象,接着就通过new创建一 个Contextlmpl对象, 然后返回。public abstract class Service extends ContextWrapper implements ComponentCallbacks2 {
......
public final void attach(
Context context,
ActivityThread thread, String className, IBinder token,
Application application, Object activityManager) {
attachBaseContext(context);
mThread = thread; // NOTE: unused - remove?
mClassName = className;
mToken = token;
mApplication = application;
mActivityManager = (IActivityManager)activityManager;
mStartCompatibility = getApplicationInfo().targetSdkVersion
< Build.VERSION_CODES.ECLAIR;
}
......
} Service对象的attach方法主要用来初始化一些变量,其内部会调用其父类ContextWrapper中的attachBaseContext(context)方法,并且将Contextlmpl类实例作为参数传入,保存在其父类ContextWrap的mBase实例变量中,这样Service中就持有了Contextlmpl类实例,这个和初始化Activity一样的。
本文详细介绍了Android系统中Service的启动过程,包括通过反射创建Service实例、初始化Service上下文、创建Application实例、初始化Service并调用onCreate方法等关键步骤。
Service的Context创建过程&spm=1001.2101.3001.5002&articleId=79310920&d=1&t=3&u=6f451c99bb704445b5c16b76a8e8b747)
638

被折叠的 条评论
为什么被折叠?



