基于Android8.0-26源码分析
整体流程:
- startService:
- Activity: startService
- ContextWrapper: startService
- ContextImpl: startService
- ContextImpl: startServiceCommon
- ActivityManagerService: startService
- ActiveServices: startServiceLocked
- ActiveServices: startServiceInnerLocked
- ActiveServices: bringUpServiceLocked
- ActiveServices: realStartServiceLocked
- ApplicationThread: scheduleCreateService
- ActivityThread: sendMessage->H.CREATE_SERVICE
- ActivityThread.H:handleMessage->H.CREATE_SERVICE
- ActivityThread: handleCreateService
- Service: attach->onCreate
- ActiveService: sendServiceArgsLocked
- ApplicationThread: scheduleServiceArgs
- ActivityThread: handleServiceArgs
- Service: onStartCommand
- bindService
- Activity: bindService
- ContextWrapper: bindService
- ContextImpl: bindService
- ContextImpl: bindServiceCommon
- ActivityManagerService: bindService
- ActiveServices: bindServiceLocked
- ActiveServices: bringUpServiceLocked
- ActiveServices: realStartServiceLocked
- ApplicationThread: scheduleCreateService //创建Service并回调onCreate方法
- ActiveServices: requestServiceBindingsLocked //请求绑定Service
- ActiveServices: requestServiceBindingLocked
- ApplicationThread: scheduleBindService
- ActivityThread: handleBindService
- Service: onBind//回调Service的onBind方法
- ActivityManagerService: publishService
- ActiveServices: publishServiceLocked
- LoadedApk.ServiceDispatcher: connected
- ServiceConnection: onServiceConnected//绑定成功后回调onServiceConnected方法
- Service在新的进程里运行,需要先创建进程然后再启动Service
- ActiveServices: bringUpServiceLocked
- ActivityManagerService: startProcessLocked
- Process: start//创建新的进程
- ActivityThread:main
- ActivityThread:attach
- ActivityManagerService: attachApplication
- ActivityManagerService: attachApplicationLocked
- ActiveServices: attachApplicationLocked
- ActiveServices: realStartServiceLocked//启动Service,后面流程跟之前是一样的
先来回顾一下启动service的方法:
- 注册Service
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.test"
android:versionCode="1"
android:versionName="1.0" >
<application >
.. ..
<service android:name="com.example.test.TestService" >
</service>
</application>
</manifest>
- 普通方式启动Service
Intent intentOne = new Intent(this, TestService.class);
startService(intentOne);
- bindService方法:
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder binder) {
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
Intent intent = new Intent(this, TestService.class);
bindService(intent, conn, BIND_AUTO_CREATE);
startService:
startService是Context中的方法,Activity继承自Context,所以startService方法最终的调用的是Context的实现者ContextImpl:
class ContextImpl extends Context{
@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
return startServiceCommon(service, false, mUser);
}
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
try {
.. ..
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), requireForeground,
getOpPackageName(), user.getIdentifier());
.. ..
return cn;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
可以看到,startService里调用了startServiceCommon,接着就是远程调用ActivityManagerService的startService方法
public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
final ActiveServices mServices;
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, boolean requireForeground, String callingPackage, int userId)
throws TransactionTooLargeException {
.. ..
synchronized(this) {
.. ..
ComponentName res;
try {
res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid,
requireForeground, callingPackage, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
return res;
}
}
}
接着就是调用ActiveServices里的startServiceLocked方法,这个类里实现了很多跟Service有关的方法
public final class ActiveServices {
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId)
throws TransactionTooLargeException {
.. ..
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
return cmp;
}
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
.. ..
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
if (error != null) {
return new ComponentName("!!", error);
}
.. ..
}
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
boolean whileRestarting, boolean permissionsReviewRequired)
throws TransactionTooLargeException {
if (r.app != null && r.app.thread != null) {
//多次启动service直接调用sendServiceArgsLocked,该方法最终会回调Service的onStartCommand方法
sendServiceArgsLocked(r, execInFg, false);
return null;
}
.. ..
if (!isolated) {
.. ..
if (app != null && app.thread != null) {//所需要的进程已经存在
try {
.. ..
realStartServiceLocked(r, app, execInFg);
return null;
}
.. ..
}
}
.. ..
//需要创建新的进程则调用startProcessLocked方法
if (app == null && !permissionsReviewRequired) {
if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
hostingType, r.name, false, isolated, false)) == null) {
.. ..
return msg;
}
.. ..
}
.. ..
return null;
}
}
经过多次跳转会来到bringUpServiceLocked这个方法,这里主要判断该Service是否已经启动
- 如果已经启动则回调onStartCommand方法;
- 如果需要的进程已经存在则调用realStartServiceLocked方法,
- 如果进程不存在,则先调用ActivityManagerService的startProcessLocked方法启动一个新的进程,最终还是会跳转到realStartServiceLocked进行创建启动Service
我们先来分析一下ActivityManagerService的startProcessLocked方法,然后最后再分析ActiveServices类中的realStartServiceLocked方法;
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
.. ..
if (hostingType.equals("webview_service")) {
startResult = startWebView(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, null, entryPointArgs);
} else {
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith, entryPointArgs);
}
.. ..
可以看到在startProcessLocked方法中,判断如果是webview所需进程则调用startWebView方法,否则调用Process.start方法启动进程:
public class Process {
public static final ZygoteProcess zygoteProcess =
new ZygoteProcess(ZYGOTE_SOCKET, SECONDARY_ZYGOTE_SOCKET);
public static final ProcessStartResult start(final String processClass,
final String niceName,
int uid, int gid, int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String invokeWith,
String[] zygoteArgs) {
return zygoteProcess.start(processClass, niceName, uid, gid, gids,
debugFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
}
}
接着就是调用了ZygoteProcess的start方法:
public class ZygoteProcess {
public final Process.ProcessStartResult start(final String processClass,
final String niceName,
int uid, int gid, int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String invokeWith,
String[] zygoteArgs) {
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
debugFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
Log.e(LOG_TAG,
"Starting VM process through Zygote failed");
throw new RuntimeException(
"Starting VM process through Zygote failed", ex);
}
}
private Process.ProcessStartResult startViaZygote(final String processClass,
final String niceName,
final int uid, final int gid,
final int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String invokeWith,
String[] extraArgs)
throws ZygoteStartFailedEx {
ArrayList<String> argsForZygote = new ArrayList<String>();
.. .. //数组保存了进程的uid、gid、groups、target-sdk、nice-name等一系列的参数
synchronized(mLock) {
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}
//打开socket通道连接Zygote进程
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held");
if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
try {
primaryZygoteState = ZygoteState.connect(mSocket);
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
}
}
if (primaryZygoteState.matches(abi)) {
return primaryZygoteState;
}
// The primary zygote didn't match. Try the secondary.
if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
try {
secondaryZygoteState = ZygoteState.connect(mSecondarySocket);
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);
}
}
if (secondaryZygoteState.matches(abi)) {
return secondaryZygoteState;
}
throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
}
private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, ArrayList<String> args)
throws ZygoteStartFailedEx {
try {
.. ..
final BufferedWriter writer = zygoteState.writer;
final DataInputStream inputStream = zygoteState.inputStream;
writer.write(Integer.toString(args.size()));
writer.newLine();
for (int i = 0; i < sz; i++) {
String arg = args.get(i);
writer.write(arg);
writer.newLine();
}
writer.flush();
// Should there be a timeout on this?
Process.ProcessStartResult result = new Process.ProcessStartResult();
// Always read the entire result from the input stream to avoid leaving
// bytes in the stream for future process starts to accidentally stumble
// upon.
result.pid = inputStream.readInt();
result.usingWrapper = inputStream.readBoolean();
if (result.pid < 0) {
throw new ZygoteStartFailedEx("fork() failed");
}
return result;
} catch (IOException ex) {
zygoteState.close();
throw new ZygoteStartFailedEx(ex);
}
}
}
从代码里可以看到,最终是调用了zygoteSendArgsAndGetResult这个方法
- 先是保存了进程的uid、gid、groups、target-sdk、nice-name等一系列的参数
- 调用openZygoteSocketIfNeeded方法,打开socket通道连接zygote进程
- 通过socket向zygote进程发送所需进程参数列表,直到进程创建完毕返回pid为止
- 最终会启动ActivityThread的main方法
public final class ActivityThread {
public static void main(String[] args) {
public static void main(String[] args) {
.. ..
Looper.prepareMainLooper();//创建Looper
ActivityThread thread = new ActivityThread();
thread.attach(false);
.. ..
Looper.loop();//开启消息循环
}
}
}
在ActivityThread的main方法中,开启了主线程消息循环,调用了attach方法:
private void attach(boolean system) {
.. ..
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
.. ..
}
接着调用ActivityManagerService的attachApplication方法:
@Override
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
.. ..
attachApplicationLocked(thread, callingPid);
.. ..
}
}
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
.. ..
// 判断有没有要启动的Activity
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
// 判断有没有需要启动的Service,有的话则调用ActiveServices的attachApplicationLocked方法
if (!badApp) {
try {
didSomething |= mServices.attachApplicationLocked(app, processName);
checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
badApp = true;
}
}
.. ..
return true;
}
判断有没有需要启动的Service,有的话则调用ActiveServices的attachApplicationLocked方法
//ActiveServices.java
boolean attachApplicationLocked(ProcessRecord proc, String processName)
throws RemoteException {
boolean didSomething = false;
// Collect any services that are waiting for this process to come up.
if (mPendingServices.size() > 0) {
.. ..
realStartServiceLocked(sr, proc, sr.createdFromFg);
.. ..
} catch (RemoteException e) {
Slog.w(TAG, "Exception in new application when starting service "
+ sr.shortName, e);
throw e;
}
}
.. ..
return didSomething;
}
最终又回到了ActiveServices的realStartServiceLocked方法创建并启动Service:
//ActiveServices.java
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException {
.. ..
try {
.. ..
//创建Service并回调onCreate方法
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
.. ..
}
.. ..
//bindServer在创建完Service后执行绑定操作,会回调Service的onBind方法
requestServiceBindingsLocked(r, execInFg);
.. ..
//最终会回调service的onStartCommand方法
sendServiceArgsLocked(r, execInFg, true);
.. ..
}
在ActiveServices的realStartServiceLocked方法里,主要逻辑:
- 创建Service并回调相应的生命周期onCreate
- 如果是bindService方式启动,还会回调onBind方法,以及ServiceConnection的onServiceConnected方法
- sendServiceArgsLocked方法最终会调用Service的onStartCommand方法
创建Service是在ApplicationThread的scheduleCreateService方法,而ApplicationThread是ActivityThread的内部类:
public final class ActivityThread {
private class ApplicationThread extends IApplicationThread.Stub {
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);
}
}
}
接着就是通过H类发送一个Handler消息,H类也是ActivityThread的内部类,继承自Handler,收到消息后,会调用ActivityThread的handleCreateService方法:
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();
} catch (Exception e) {
if (!mInstrumentation.onException(service, e)) {
throw new RuntimeException(
"Unable to instantiate service " + data.info.name
+ ": " + e.toString(), e);
}
}
try {
.. ..
Application app = packageInfo.makeApplication(false, mInstrumentation);
//调用Service的attach方法,并联Application对象
service.attach(context, this, data.info.name, data.token, app,
ActivityManager.getService());
//调用Service的onCreate方法
service.onCreate();
.. ..
}
.. ..
}
在handleCreateService方法中:
- 通过类加载器创建Service对象
- 调用Service的attach方法,并联Application对象
- 调用Service的onCreate方法
到这里Service就创建完成了,接下来看看bindService的时候,如何绑定Service的
bindService
//ContextImpl.java
@Override
public boolean bindService(Intent service, ServiceConnection conn,
int flags) {
warnIfCallingFromSystemProcess();
return bindServiceCommon(service, conn, flags, mMainThread.getHandler(),
Process.myUserHandle());
}
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler
handler, UserHandle user) {
// Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser.
IServiceConnection sd;
.. ..
if (mPackageInfo != null) {//跟ServiceConnection相关的回调接口,用于跨进程调用
sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
}
.. ..
try {
.. ..
int res = ActivityManager.getService().bindService(
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, getOpPackageName(), user.getIdentifier());
.. ..
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
从代码可以看到,先创建了一个IServiceConnection接口,该接口是一个Binder接口,用于跨进程回调ServiceConnection中的方法,它的实现类是LoadedApk.java中的ServiceDispatcher类里面的InnerConnection方法:
class LoadedApk{
public final IServiceConnection getServiceDispatcher(ServiceConnection c,
Context context, Handler handler, int flags) {
synchronized (mServices) {
LoadedApk.ServiceDispatcher sd = null;
.. ..
if (sd == null) {
sd = new ServiceDispatcher(c, context, handler, flags);
.. ..
}
.. ..
return sd.getIServiceConnection();//获取ServiceDispatcher的Binder接口
}
}
static final class ServiceDispatcher {
private final ServiceDispatcher.InnerConnection mIServiceConnection;
private static class InnerConnection extends IServiceConnection.Stub {
final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;
InnerConnection(LoadedApk.ServiceDispatcher sd) {
mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
}
public void connected(ComponentName name, IBinder service, boolean dead)
throws RemoteException {
LoadedApk.ServiceDispatcher sd = mDispatcher.get();
if (sd != null) {
sd.connected(name, service, dead);
}
}
}
public void connected(ComponentName name, IBinder service, boolean dead) {
if (mActivityThread != null) {
mActivityThread.post(new RunConnection(name, service, 0, dead));
} else {
doConnected(name, service, dead);
}
}
}
public void doConnected(ComponentName name, IBinder service, boolean dead) {
ServiceDispatcher.ConnectionInfo old;
ServiceDispatcher.ConnectionInfo info;
synchronized (this) {
.. ..
// If there is a new service, it is now connected.
if (service != null) {//调用ServiceDispatcher的onServiceConnected方法
mConnection.onServiceConnected(name, service);
}
}
}
从代码里可以看出:
- IServiceConnection是个Binder接口,它对应的实现类是ServiceDispatcher.InnerConnection,里面只有一个connected方法,最终远程调用的是ServiceDispatcher的contected方法。
然后调用了ActivityManagerService的bindService方法:
public int bindService(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, IServiceConnection connection, int flags, String callingPackage,
int userId) throws TransactionTooLargeException {
enforceNotIsolatedCaller("bindService");
.. ..
synchronized(this) {
return mServices.bindServiceLocked(caller, token, service,
resolvedType, connection, flags, callingPackage, userId);
}
}
int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, final IServiceConnection connection, int flags,
String callingPackage, final int userId) throws TransactionTooLargeException {
.. ..
RemoteCallback callback = new RemoteCallback(
new RemoteCallback.OnResultListener() {
@Override
public void onResult(Bundle result) {
synchronized(mAm) {
.. ..
try {
bringUpServiceLocked(serviceRecord,
serviceIntent.getFlags(),
callerFg, false, false);
} catch (RemoteException e) {
/* ignore - local call */
}
.. ..
}
}
});
final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
intent.putExtra(Intent.EXTRA_PACKAGE_NAME, s.packageName);
intent.putExtra(Intent.EXTRA_REMOTE_CALLBACK, callback);
mAm.mHandler.post(new Runnable() {
@Override
public void run() {
mAm.mContext.startActivityAsUser(intent, new UserHandle(userId));
}
});
}
}
.. ..
}
接着就是在ActiveServices的bindServiceLocked方法里调用了bringUpServiceLocked,接着就是到了realStartServiceLocked方法里,在这个方法里显示创建了Service,然后通过ActiveServices的requestServiceBindingsLocked这个方法绑定Service:
private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg)
throws TransactionTooLargeException {
for (int i=r.bindings.size()-1; i>=0; i--) {
IntentBindRecord ibr = r.bindings.valueAt(i);
if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
break;
}
}
}
private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
boolean execInFg, boolean rebind) throws TransactionTooLargeException {
.. ..
if ((!i.requested || rebind) && i.apps.size() > 0) {
try {
.. ..
r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
r.app.repProcState);
.. ..
}
.. ..
}
return true;
}
接着又调用了ApplicationThread的scheduleBindService,这个方法里也是通过Handler发送消息,然后ActivityThread的handleBindService方法处理:
private void handleBindService(BindServiceData data) {
Service s = mServices.get(data.token);
.. ..
if (s != null) {
try {
.. ..
IBinder binder = s.onBind(data.intent);
ActivityManager.getService().publishService(
data.token, data.intent, binder);
.. ..
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
.. ..
}
}
在ActivityThread的handleBindService方法中回调了Service的onBind方法,拿到Bider对象,然后调用ActivityManagerService的publishService方法:
public void publishService(IBinder token, Intent intent, IBinder service) {
.. ..
synchronized(this) {
.. ..
mServices.publishServiceLocked((ServiceRecord)token, intent, service);
}
}
接着又来到了ActiveServices的publishServiceLocked方法:
void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
.. ..
ConnectionRecord c = clist.get(i);
try {
c.conn.connected(r.name, service, false);
}
.. ..
}
- 代码里的c指的是ConnectionRecord
- c.conn指向的是IServiceConnection接口
- service指的是自定义Service中onBind方法中返回的Binder接口
- 从前面分析知道,IServiceConnection是个Binder接口,最终会回调ServiceConnection的onServiceConnected方法,到这里Service就启动并绑定上了
到这里Service就创建启动并绑定上了客户端