启动Service组件的流程如下所示:
1 向ActivityManagerService发送一个启动Service组件的请求。
2 ActivityManagerService发现用来运行Service组件的进程不存在,它会先保存Service组件的信息,接着再创建一个新的应用进程。
3 新的应用进程创建完成后,就会向ActivityManagerService发送一个启动完成的进程间通信请求,以便ActivityManagerService可
以继续执行启动Service组件的的操作。
4 ActivityManagerService将第2步保存的Service组件信息发送给新床架的应用进程,以便它可以将Service组件启动起来。
新进程中启动Service组件序列图
当我们在Activity里调用startService(Intent service)方法时,它实际上在调用ContextWrapper.startService(Intent service)。
public class ContextWrapper{
@Override
public ComponentName startService(Intent service) {
return mBase.startService(service);
}
}
mBase的对象类型是Context,它实际上指向了Context的实现类ContextImpl,所以该方法进一步调用ContextImpl.startService.
public class ContextImpl{
@Override
public ComponentName startService(Intent service) {
try {
ComponentName cn = ActivityManagerNative.getDefault().startService(
mMainThread.getApplicationThread(), service,
service.resolveTypeIfNeeded(getContentResolver()));
if (cn != null && cn.getPackageName().equals("!")) {
throw new SecurityException(
"Not allowed to start service " + service
+ " without permission " + cn.getClassName());
}
return cn;
} catch (RemoteException e) {
return null;
}
}
}
ActivityManagerNative.getDefault()获取的是ActivityManagerService的一个代理对象,即ActivityManagerProxy。我们再看看看传递的参数:
mMainThread.getApplicationThread(:获取当前应用进程的一个类型为ApplicationThread的Binder本地对象。将它传递给ActivityManagerService,以便
ActivityManagerService知道是谁在请求它启动Service组件。
service:intent对象。
service.resolveTypeIfNeeded(getContentResolver()):返回Intent的MIME类型。
该方法进一步调用即ActivityManagerProxy.startService(IApplicationThread caller, Intent service, String resolvedType)
public abstract class ActivityManagerNative extends Binder implements IActivityManager{
class ActivityManagerProxy implements IActivityManager{
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType) throws RemoteException{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
service.writeToParcel(data, 0);
data.writeString(resolvedType);
mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
reply.readException();
ComponentName res = ComponentName.readFromParcel(reply);
data.recycle();
reply.recycle();
return res;
}
}
}
将传递金磊的参数封装成Parcel对象,然后利用ActivityManagerProxy内部的Binder对象mRemote向ActivityManagerService发送一个START_SERVICE_TRANSACTION进程间通信请求。
该函数进一步调用ActivityManagerService.startService(IApplicationThread caller, Intent service, String resolvedType)来处理这个请求。
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType) {
// Refuse possible leaked file descriptors
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();
ComponentName res = startServiceLocked(caller, service,
resolvedType, callingPid, callingUid);
Binder.restoreCallingIdentity(origId);
return res;
}
}
}
这个函数的参数的含义上面第2步已经介绍过,它进一步调用ActivityManagerService.startServiceLocked()方法执行启动Service组件的操作。
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
ComponentName startServiceLocked(IApplicationThread caller,
Intent service, String resolvedType,
int callingPid, int callingUid) {
synchronized(this) {
if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
+ " type=" + resolvedType + " args=" + service.getExtras());
if (caller != null) {
final ProcessRecord callerApp = getRecordForAppLocked(caller);
if (callerApp == null) {
throw new SecurityException(
"Unable to find app for caller " + caller
+ " (pid=" + Binder.getCallingPid()
+ ") when starting service " + service);
}
}
//查找是否有与参数service对应的一个ServiceRecord对象,如果没有则ActivityManagerService就会到PackageManagerService中
//去获取与参数service对应的一个Service组件信息,并把它封装成一个ServiceRecord对象。
ServiceLookupResult res =
retrieveServiceLocked(service, resolvedType,
callingPid, callingUid);
if (res == null) {
return null;
}
if (res.record == null) {
return new ComponentName("!", res.permission != null
? res.permission : "private to package");
}
//每个Service组件都用一个ServiceRecord对象类描述,就行每个Activity组件都用一个ActivityRecord来描述一样。
ServiceRecord r = res.record;
int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
callingUid, r.packageName, service);
if (unscheduleServiceRestartLocked(r)) {
if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
}
r.startRequested = true;
r.callStart = false;
r.lastStartId++;
if (r.lastStartId < 1) {
r.lastStartId = 1;
}
r.pendingStarts.add(new ServiceRecord.StartItem(r, r.lastStartId,
service, targetPermissionUid));
r.lastActivity = SystemClock.uptimeMillis();
synchronized (r.stats.getBatteryStats()) {
r.stats.startRunningLocked();
}
//根据上面封装的ServiceRecord对象,调用bringUpServiceLocked()方法进一步启动Service组件的启动操作。
if (!bringUpServiceLocked(r, service.getFlags(), false)) {
return new ComponentName("!", "Service process is bad");
}
return r.name;
}
}
}
ServiceRecord:用来描述Service组件信息,每个Service组件都用一个ServiceRecord对象类描述,就行每个Activity组件都用一个ActivityRecord来描述一样。
这个函数主要做了两件事情:
1 查找是否有与参数service对应的一个ServiceRecord对象,如果没有则ActivityManagerService就会到PackageManagerService中
去获取与参数service对应的一个Service组件信息,并把它封装成一个ServiceRecord对象。
2 根据上面封装的ServiceRecord对象,调用bringUpServiceLocked()方法进一步启动Service组件的启动操作。
我们来看ActivityManagerService.bringUpServiceLocked()方法的实现。
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
private final boolean bringUpServiceLocked(ServiceRecord r,
int intentFlags, boolean whileRestarting) {
//Slog.i(TAG, "Bring up service:");
//r.dump(" ");
if (r.app != null && r.app.thread != null) {
sendServiceArgsLocked(r, false);
return true;
}
if (!whileRestarting && r.restartDelay > 0) {
// If waiting for a restart, then do nothing.
return true;
}
if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
// We are now bringing the service up, so no longer in the
// restarting state.
mRestartingServices.remove(r);
//获取ServiceRecord里的processName属性
final String appName = r.processName;
//然后根据processName属性与Service组件的用户ID去查找ActivityManagerService是否已经存在
//一个ProcessRecord对象。
ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
if (app != null && app.thread != null) {
try {
//如果存在该ProcessRecord对象则在app所描述的应用进程中启动该Service组件
realStartServiceLocked(r, app);
return true;
} 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.
}
//如果没有查找到该进程,则会去启动一个新的应用进程。
// Not running -- get it started, and enqueue this service record
// to be executed when the app comes up.
if (startProcessLocked(appName, r.appInfo, true, intentFlags,
"service", r.name, false) == null) {
Slog.w(TAG, "Unable to launch app "
+ r.appInfo.packageName + "/"
+ r.appInfo.uid + " for service "
+ r.intent.getIntent() + ": process is bad");
bringDownServiceLocked(r, true);
return false;
}
if (!mPendingServices.contains(r)) {
//将该Service组件对象保存在ActivityManagerService的成员变量mPendingService中,表示它是一个
//正在等待启动的Service组件。
mPendingServices.add(r);
}
return true;
}
}
该函数主要做了两件事情:
1 获取ServiceRecord里的processName属性,然后根据processName属性与Service组件的用户ID去查找ActivityManagerService
是否已经存在一个ProcessRecord对象。
如果存在:则在app所描述的应用进程中启动该Service组件
如果不存在:则会去启动一个新的应用进程。
2 将该Service组件对象保存在ActivityManagerService的成员变量mPendingService中,表示它是一个正在等待启动的Service组件。
我们分析的是在新进程创建Service组件的情况,因此我们接着来看ActivityManagerService.startProcessLocked()的实现。
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
ProcessRecord app = getProcessRecordLocked(processName, info.uid);
...
startProcessLocked(app, hostingType, hostingNameStr);
return (app.pid != 0) ? app : null;
}
private final void startProcessLocked(ProcessRecord app,
String hostingType, String hostingNameStr) {
...
int pid = Process.start("android.app.ActivityThread",
mSimpleProcessManagement ? app.processName : null, uid, uid,
gids, debugFlags, null);
...
}
}
从这个函数开始就开始创建新的应用进程了,它主要调用Process的静态函数start()来创建一个新的应用进程,这个新进程以ActivityThread
类的静态成员函数main()为入口。
public final class ActivityThread {
public static final void main(String[] args) {
SamplingProfilerIntegration.start();
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
if (sMainThreadHandler == null) {
sMainThreadHandler = new Handler();
}
ActivityThread thread = new ActivityThread();
//该方法会去调用ActivityManagerProxy.attachApplication()方法
thread.attach(false);
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();
if (Process.supportsProcesses()) {
throw new RuntimeException("Main thread loop unexpectedly exited");
}
thread.detach();
String name = (thread.mInitialApplication != null)
? thread.mInitialApplication.getPackageName()
: "<unknown>";
Slog.i(TAG, "Main thread of " + name + " is now exiting");
}
}
main函数是新创建进程的入口,该函数会创建一个ActivityThread与ApplicationThread对象,并调用ActivityManagerProxy.attachApplication()方
法进一步执行Service组件启动操作。
class ActivityManagerProxy implements IActivityManager{
public void attachApplication(IApplicationThread app) throws RemoteException{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(app.asBinder());
mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
reply.recycle();
}
}
该函数中ActivityManagerProxy接受上一步main方法创建的ApplicationThread对象,并向ActivityManagerService发送一个类型为
ATTACH_APPLICATION_TRANSACTION进程间通信请求,并将ApplicationThread对象传递给ActivityManagerService,以便
ActivityManagerService可以和这个新创建的进程进行通信。
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
}
该方法进一步调用ActivityManagerService.attachApplicationLocked()来处理上一步发出的ATTACH_APPLICATION_TRANSACTION
进程间通信请求。这个方法我们应该很熟悉,我们以前在分析新进程启动Activity组件时就走到了这个函数,我们再来看一看它的实现。
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
// Find the application record that is being attached... either via
// the pid if we are running in multiple processes, or just pull the
// next app record if we are emulating process with anonymous threads.
ProcessRecord app;
//pid指向的前面新创建的应用进程的PID,在第8步中,ActivityManagerService以这个PID
//为key将一个ProcessRecord存在了mPidsSelfLocked,现在把它取出来保存在变量app中。
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid);
}
} else if (mStartingProcesses.size() > 0) {
app = mStartingProcesses.remove(0);
app.setPid(pid);
} else {
app = null;
}
...
//指向上一步传递过来的ApplicationThread对象,ActivityManagerService以后就可以通过
//这个ApplicationThread对象同新创建的应用进程通信了。
app.thread = thread;
...
//处理Service组件
// Find any services that should be running in this process...
if (!badApp && mPendingServices.size() > 0) {
ServiceRecord sr = null;
try {
for (int i=0; i<mPendingServices.size(); i++) {
sr = mPendingServices.get(i);
//检查保存在mPendingServices里的Service组件是否需要在新进程中启动
if (app.info.uid != sr.appInfo.uid
|| !processName.equals(sr.processName)) {
continue;
}
//如果需要在新进程中启动,则将其在mPendingServices移除,并调用
//realStartServiceLocked启动该Service组件。
mPendingServices.remove(i);
i--;
realStartServiceLocked(sr, app);
didSomething = true;
}
} catch (Exception e) {
Slog.w(TAG, "Exception in new application when starting service "
+ sr.shortName, e);
badApp = true;
}
}
...
}
}
注:Activity组件、Service组件与BrocastReceiver组件启动都是由这个函数来处理的。
该函数会检查保存在mPendingServices里的Service组件是否需要在新进程中启动,如果果需要在新进程中启动,则将其
在mPendingServices移除,并调用realStartServiceLocked启动该Service组件。
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app) throws RemoteException {
...
//将ProcessRecord对象app设置为ServiceRecord的成员变量app
r.app = app;
...
try {
...
app.thread.scheduleCreateService(r, r.serviceInfo);
...
} finally {
if (!created) {
app.services.remove(r);
scheduleServiceRestartLocked(r, false);
}
}
...
}
该函数进一步调用ApplicationThreadProxy.scheduleCreateService()方法执行Service组件启动操作。
class ApplicationThreadProxy implements IApplicationThread {
public final void scheduleCreateService(IBinder token, ServiceInfo info)
throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
data.writeStrongBinder(token);
info.writeToParcel(data, 0);
mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,
IBinder.FLAG_ONEWAY);
data.recycle();
}
}
该函数调用ApplicationThreadProxy内部的一个Binder对象向新创建的进程发送一个SCHEDULE_CREATE_SERVICE_TRANSACTION
进程间通信请求,进一步在新进程中创建Service组件。
public final class ActivityThread {
public final void scheduleCreateService(IBinder token,
ServiceInfo info) {
CreateServiceData s = new CreateServiceData();
s.token = token;
s.info = info;
queueOrSendMessage(H.CREATE_SERVICE, s);
}
}
该方法将要启动的Service组件信息封装成一个CreateServiceData对象,然后传递给queueOrSendMessage方法。
public final class ActivityThread {
private final void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {
synchronized (this) {
if (DEBUG_MESSAGES) Slog.v(
TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
+ ": " + arg1 + " / " + obj);
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
mH.sendMessage(msg);
}
}
}
该方法发送一个CREATE_SERVICE消息来进一步创建Service组件。然后调用ActivityThread内部的Handler对象来处理消息。
private final class H extends Handler {
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + msg.what);
switch (msg.what) {
...
case CREATE_SERVICE:
handleCreateService((CreateServiceData)msg.obj);
break;
...
}
}
该方法进一步调用handleCreateService()来创建Service组件。
public final class ActivityThread {
private final 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();
//获取一个用来描述即将要启动Service组件的所在应用的LoadedApk对象。并将它
//保存在变量packageInfo中。
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo);
Service service = null;
try {
//获取类加载器,将Service组件加载到内存中,并创建它的一个实例。
java.lang.ClassLoader cl = packageInfo.getClassLoader();
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);
//创建一个Context对象,作为Service组件运行的上下文环境。
ContextImpl context = new ContextImpl();
context.init(packageInfo, null, this);
//创建一个Application对象,用来描述Service组件所属的应用。
Application app = packageInfo.makeApplication(false, mInstrumentation);
context.setOuterContext(service);
//初始化Service组件
service.attach(context, this, data.info.name, data.token, app,
ActivityManagerNative.getDefault());
//调用Service的onCreate()方法
service.onCreate();
//将新创建的Service组件保存到ActivityThread的成员变量mServices中,其中data.token
//指向的是ActivityManagerService内部的一个ServiceRecord对象。
mServices.put(data.token, service);
try {
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);
}
}
}
}
该方法真正执行了Service组件的创建以及初始化工作,它主要做了以下几件事情:
1 获取初始化Service组件所必需的参数:
LoadedApk packageInfo:用来描述已经加载到进程中的应用,通过它可以访问到该应用里的资源。
ContextImpl context:创建一个Context对象,作为Service组件运行的上下文环境。
Application app:创建一个Application对象,用来描述Service组件所属的应用。
2 获取类加载器,将Service组件加载到内存中,并创建它的一个实例。
3 根据上面创建的参数进行Service组件的初始化。
4 调用Service的onCreate()方法。
这个onCreate()方法就是我们使用Service组件所重写的方法了,用来自定义一些我需要的初始化操作。
Copyright© 2013-2019