我们一般在写代码的时候,都会通过startService来启动一个服务,但是服务到底是怎样启动的以及startService到底做了哪些工作呢?现在就来把整个过程进行整理。
我们知道Service的启动是调用了Context对象里面的startService方法,但是Context只是一个抽象类,真正的操作都是在它的实现类ContextImpl中,所以我们直接看ContextImpl里面的startService方法。
@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, mUser);
}
我们对其进行跟踪,接着调用了startServiceCommon(service, mUser);
private ComponentName startServiceCommon(Intent service, UserHandle user) {
try {
validateServiceIntent(service);
service.prepareToLeaveProcess();
ComponentName cn = ActivityManagerNative.getDefault().startService(
mMainThread.getApplicationThread(), service,
service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
if (cn != null) {
if (cn.getPackageName().equals("!")) {
throw new SecurityException(
"Not allowed to start service " + service
+ " without permission " + cn.getClassName());
} else if (cn.getPackageName().equals("!!")) {
throw new SecurityException(
"Unable to start service " + service
+ ": " + cn.getClassName());
}
}
return cn;
} catch (RemoteException e) {
return null;
}
}
这里我们要打断一下,先看看ActivityManagerNative.getDefault()干了些什么,所以我们要进入ActivityManagerNative类里面,差个究竟。
static public IActivityManager getDefault() {
return gDefault.get();
}
继续看源码,
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
IActivityManager am = asInterface(b);
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
如果看过前面浅析PackageManager的工作流程,应该对ServiceManager.getService(“activity”)这一句代码并不陌生,因为我们的PackageManager也是使用的服务,在那篇文章中,我们获取这个服务是通过ServiceManager.getService(“package”),这样充分的说明了一点:ServiceManager就是一个服务管理者,系统的service需要通过add_service把自己的信息注册到ServiceManager中,这样在需要的时候就会获取到服务。
所以我们可以看到通过ServiceManager.getService(“activity”)可以得到远程服务的Binder对象,下面接着调用了asInterface(b),这句代码大家应该并不陌生,因为我们在编写绑定远程服务的时候就会使用,我直接贴一段小程序,激发一下大家的回忆:
public class MainActivity extends Activity {
private IManager manager;
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i("MyService", "onServiceConnected");
//得到本地代理对象
manager = IManager.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void bindService(View view) {
Log.i("MyService", "bindService");
Intent intent = new Intent("com.newintenttest.startservice.MyService");
bindService(intent, connection, Context.BIND_AUTO_CREATE);
}
public void unbindService(View view) {
unbindService(connection);
}
public void caculate(View view){
if (manager == null) {
Toast.makeText(this, "请绑定服务", Toast.LENGTH_SHORT).show();
} else {
int result = 0;
try {
result = manager.add(4, 5);
} catch (Exception e) {
e.printStackTrace();
}
Toast.makeText(this, result + "",Toast.LENGTH_SHORT).show();
}
}
}
这段程序来自浅析绑定远程服务bindService基本原理与AIDL分析
我们在调用了bindService(intent, connection, Context.BIND_AUTO_CREATE)后,会回调onServiceConnected方法,这个方法里面有一个IBinder类型的参数,就相当于上面的ServiceManager.getService(“activity”),都是得到远程服务的Binder对象,在上面的代码中接着调用了IManager.Stub.asInterface(service),得到本地代理对象,同理,回过头看看asInterface(b),这里肯定也是得到本地的代理对象,然后就是通过本地代理对象进行操作。
那么我们接着看看ActivityManagerNative的asInterface的操作,就可以看到这个代理对象了。
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IActivityManager in =
(IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ActivityManagerProxy(obj);
}
我们写代码的时候,这些代码使用AIDL来自动生成的,其实也可以不自动生成,看看浅析绑定远程服务bindService基本原理与AIDL分析就知道了。
好了,这里其实得到的就是ActivityManagerProxy对象。我们回到上面,也就是说ActivityManagerNative.getDefault()返回了一个ActivityManagerProxy对象,接着看看这一整句代码ActivityManagerNative.getDefault().startService,调用了ActivityManagerNative里面的startService。我们进入到ActivityManagerNative类,看看里面的源码。ActivityManagerNative也在ActivityManagerNative.java文件中。
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, int userId) 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);
data.writeInt(userId);
mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
reply.readException();
ComponentName res = ComponentName.readFromParcel(reply);
data.recycle();
reply.recycle();
return res;
}
这里调用了mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0),其中mRemote就是ServiceManager.getService(“activity”)返回的Binder对象。
说到这里,如果还是不明白,强烈建议看看浅析绑定远程服务bindService基本原理与AIDL分析这篇文章,看了这篇文章之后,对于这整个过程就可以有一个宏观的理解。
接着会调用ActivityManagerNative里面的onTransact方法。
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
case START_SERVICE_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder b = data.readStrongBinder();
IApplicationThread app = ApplicationThreadNative.asInterface(b);
Intent service = Intent.CREATOR.createFromParcel(data);
String resolvedType = data.readString();
int userId = data.readInt();
ComponentName cn = startService(app, service, resolvedType, userId);
reply.writeNoException();
ComponentName.writeToParcel(cn, reply);
return true;
}
}
从里面可以看到会调用startService(app, service, resolvedType, userId);我们发现在ActivityManagerNative里面没有startService方法,不要急,这个方法肯定存在,我们来看看ActivityManagerNative的子类ActivityManagerService类。
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, int userId) {
enforceNotIsolatedCaller("startService");
// Refuse possible leaked file descriptors
if (service != null && service.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
if (DEBUG_SERVICE)
Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
synchronized(this) {
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
ComponentName res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid, userId);
Binder.restoreCallingIdentity(origId);
return res;
}
}
在这个里面调用了mServices.startServiceLocked方法,mServices是什么,在ActivityManagerService的构造函数中,我们可以看到下面一句。
private ActivityManagerService() {
mServices = new ActiveServices(this);
}
下面我们就要进入ActiveServices类,看看源码:
ComponentName startServiceLocked(IApplicationThread caller,
Intent service, String resolvedType,
int callingPid, int callingUid, int userId) {
......
ServiceLookupResult res =
retrieveServiceLocked(service, resolvedType,
callingPid, callingUid, userId, true, callerFg);
........
return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
}
函数首先通过retrieveServiceLocked来解析service这个Intent,就是解析前面我们在AndroidManifest.xml定义的Service标签的intent-filter相关内容,然后将解析结果放在res.record中,后面调用了startServiceInnerLocked方法
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service,
ServiceRecord r, boolean callerFg, boolean addToStarting) {
ProcessStats.ServiceState stracker = r.getTracker();
if (stracker != null) {
stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
}
r.callStart = false;
synchronized (r.stats.getBatteryStats()) {
r.stats.startRunningLocked();
}
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
if (error != null) {
return new ComponentName("!!", error);
}
if (r.startRequested && addToStarting) {
boolean first = smap.mStartingBackground.size() == 0;
smap.mStartingBackground.add(r);
r.startingBgTimeout = SystemClock.uptimeMillis() + BG_START_TIMEOUT;
if (DEBUG_DELAYED_SERVICE) {
RuntimeException here = new RuntimeException("here");
here.fillInStackTrace();
Slog.v(TAG, "Starting background (first=" + first + "): " + r, here);
} else if (DEBUG_DELAYED_STATS) {
Slog.v(TAG, "Starting background (first=" + first + "): " + r);
}
if (first) {
smap.rescheduleDelayedStarts();
}
} else if (callerFg) {
smap.ensureNotStartingBackground(r);
}
return r.name;
}
这里调用了bringUpServiceLocked进一步处理。
private final String bringUpServiceLocked(ServiceRecord r,
int intentFlags, boolean execInFg, boolean whileRestarting) {
......
final String procName = r.processName;
ProcessRecord app;
......
if (app == null) {
if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
"service", r.name, false, isolated, false)) == null) {
String msg = "Unable to launch app "
+ r.appInfo.packageName + "/"
+ r.appInfo.uid + " for service "
+ r.intent.getIntent() + ": process is bad";
Slog.w(TAG, msg);
bringDownServiceLocked(r);
return msg;
}
if (isolated) {
r.isolatedProc = app;
}
}
if (!mPendingServices.contains(r)) {
mPendingServices.add(r);
}
if (r.delayedStop) {
// Oh and hey we've already been asked to stop!
r.delayedStop = false;
if (r.startRequested) {
if (DEBUG_DELAYED_STATS) Slog.v(TAG, "Applying delayed stop (in bring up): " + r);
stopServiceLocked(r);
}
}
return null;
}
这里的procName便是我们前面在AndroidManifest.xml文件定义service标签时指定的android:process属性值了,
接着调用startProcessLocked函数来创建一个新的进程,以便加载自定义的Service类。最后将这个ServiceRecord保存在成员变量mPendingServices列表中。
那么mAm.startProcessLocked里面的mAm是什么?
看看ActiveServices的构造函数就知道了。
public ActiveServices(ActivityManagerService service) {
mAm = service;
}
就是调用了ActivityManagerService里面的startProcessLocked方法
private final void startProcessLocked(ProcessRecord app,
String hostingType, String hostingNameStr) {
......
// Start the process. It will either succeed and return a result containing
// the PID of the new process, or else throw a RuntimeException.
Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, null);
......
synchronized (mPidsSelfLocked) {
this.mPidsSelfLocked.put(startResult.pid, app);
Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
msg.obj = app;
mHandler.sendMessageDelayed(msg, startResult.usingWrapper
? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
}
}
这里调用Process.start函数创建了一个新的进程,指定新的进程执行android.app.ActivityThread类。最后将表示这个新进程的ProcessRecord保存在mPidSelfLocked列表中.
在新进程中指定了执行ActivityThread类,下面就直接进入ActivityThread的main函数里面。
public static void main(String[] args) {
SamplingProfilerIntegration.start();
// CloseGuard defaults to true and can be quite spammy. We
// disable it here, but selectively enable it later (via
// StrictMode) on debug builds, but using DropBox, not logs.
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
// Set the reporter for event logging in libcore
EventLogger.setReporter(new EventLoggingReporter());
Security.addProvider(new AndroidKeyStoreProvider());
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
AsyncTask.init();
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
}
在上面创建了一个ActivityThread对象,然后执行了它的attach方法。
private void attach(boolean system) {
IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
}
}
上面又执行了ActivityManagerNative.getDefault()方法,对于这个现在应该不陌生了吧,返回的就是一个ActivityManagerProxy本地代理对象.接着执行mgr.attachApplication(mAppThread)就是执行了ActivityManagerProxy里面的attachApplication方法。
其中mAppThread就是ApplicationThread对象。因为在ActivityThread里面创建了这个对象。
另外ApplicationThread继承自ApplicationThreadNative,ApplicationThreadNative继承自Binder。
final ApplicationThread mAppThread = new ApplicationThread();
接着进入ActivityManagerProxy类查看源码:
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();
}
调用了ActivityManagerNative里面的onTransant方法。
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
case ATTACH_APPLICATION_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IApplicationThread app = ApplicationThreadNative.asInterface(
data.readStrongBinder());
if (app != null) {
attachApplication(app);
}
reply.writeNoException();
return true;
}
}
它里面执行了attachApplication方法。同样,这个方法在ActivityManagerNative的子类ActivityManagerService里面。
@Override
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
接着跟踪attachApplicationLocked方法
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
......
// Find any services that should be running in this process...
if (!badApp) {
try {
didSomething |= mServices.attachApplicationLocked(app, processName);
} catch (Exception e) {
badApp = true;
}
}
......
return true;
}
它执行了mServices.attachApplicationLocked函数,mServices就是ActiveServices对象。
boolean attachApplicationLocked(ProcessRecord proc, String processName) throws Exception {
boolean didSomething = false;
// Collect any services that are waiting for this process to come up.
if (mPendingServices.size() > 0) {
ServiceRecord sr = null;
try {
for (int i=0; i<mPendingServices.size(); i++) {
sr = mPendingServices.get(i);
if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
|| !processName.equals(sr.processName))) {
continue;
}
mPendingServices.remove(i);
i--;
proc.addPackage(sr.appInfo.packageName, mAm.mProcessStats);
realStartServiceLocked(sr, proc, sr.createdFromFg);
didSomething = true;
}
} catch (Exception e) {
Slog.w(TAG, "Exception in new application when starting service "
+ sr.shortName, e);
throw e;
}
}
// Also, if there are any services that are waiting to restart and
// would run in this process, now is a good time to start them. It would
// be weird to bring up the process but arbitrarily not let the services
// run at this point just because their restart time hasn't come up.
if (mRestartingServices.size() > 0) {
ServiceRecord sr = null;
for (int i=0; i<mRestartingServices.size(); i++) {
sr = mRestartingServices.get(i);
if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
|| !processName.equals(sr.processName))) {
continue;
}
mAm.mHandler.removeCallbacks(sr.restarter);
mAm.mHandler.post(sr.restarter);
}
}
return didSomething;
}
这里执行了realStartServiceLocked方法,
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
......
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
......
}
上面的app.thread是IApplicatonThread类型,最终将执行ApplicationThreadProxy里的scheduleCreateService方法。
public final void scheduleCreateService(IBinder token, ServiceInfo info,
CompatibilityInfo compatInfo, int processState) throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
data.writeStrongBinder(token);
info.writeToParcel(data, 0);
compatInfo.writeToParcel(data, 0);
data.writeInt(processState);
mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,
IBinder.FLAG_ONEWAY);
data.recycle();
}
这个现在应该很熟悉了,接着执行ApplicationThreadNative里面的onTransact方法
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
case SCHEDULE_CREATE_SERVICE_TRANSACTION: {
data.enforceInterface(IApplicationThread.descriptor);
IBinder token = data.readStrongBinder();
ServiceInfo info = ServiceInfo.CREATOR.createFromParcel(data);
CompatibilityInfo compatInfo = CompatibilityInfo.CREATOR.createFromParcel(data);
int processState = data.readInt();
scheduleCreateService(token, info, compatInfo, processState);
return true;
}
}
接着就执行scheduleCreateService方法。因为ApplicationThreadNative里面没有实现scheduleCreateService这个方法,所以会执行它的子类ApplicationThread里的scheduleCreateService方法。ApplicationThread这个类在ActivityThread.java文件中。
public final void scheduleCreateService(IBinder token,
ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
updateProcessState(processState, false);
CreateServiceData s = new CreateServiceData();
s.token = token;
s.info = info;
s.compatInfo = compatInfo;
sendMessage(H.CREATE_SERVICE, s);
}
接着会执行sendMessage方法。
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
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;
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}
从定义final H mH = new H()可以看到mH是一个H对象,而H是一个继承自Handler的类。
private class H extends Handler {
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case CREATE_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
handleCreateService((CreateServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
}
}
下面执行的就是handleCreateService方法了。
private 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();
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) {
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);
ContextImpl context = new ContextImpl();
context.init(packageInfo, null, this);
Application app = packageInfo.makeApplication(false, mInstrumentation);
context.setOuterContext(service);
service.attach(context, this, data.info.name, data.token, app,
ActivityManagerNative.getDefault());
//执行了onCreate方法,也就是说我们的onCreate方法是在这里调用的
service.onCreate();
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 = (Service) cl.loadClass(data.info.name).newInstance()就创建了一个服务,data.info.name就是自定义的服务.接着就执行了service.onCreate()方法,对于这个方法应该很熟悉了,原来我们的onCreate方法是在这个地方调用的。