Service启动过程and新进程创建全过程源码分析
Posted 刘镓旗
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Service启动过程and新进程创建全过程源码分析相关的知识,希望对你有一定的参考价值。
由于android本身对于四大组件的封装,导致在开发当中根本不需要知道四大组件的底层原理及运行过程,但是如果作为一个高级者来说或者为了解决一些底层出现的问题,那么了解四大组件的运行原理和启动过程那么非常必要的。而且目前市面上的热修复,插件化技术越来越火,那么如果连四大组件的启动过程和运行原理都不知道的话,那么也就根本就不明白这些技术的实现原理的,总之好处还是大大的,那么就让我们来一起研究一下吧。
在阅读源码以前还是先简要的说一下,其实四大组件的底层原理是用了Binder机制,那么如果对Binder机制一点都不了解的话,希望还是先看一下Binder机制,之前也有写一篇关于Binder的文章,希望可以有所帮助插件化知识详细分解及原理 之Binder机制
我们先说Service的启动过程,下面会说新进程的启动过程
一、Service的启动过程 :
启动Service的方式有两种,一种是startService和bindService,虽然调用的方法不同,但是其底层原理基本都一样,这里就从startService开始了,本文源码基于5.1
然后我们先看一下继承关系:
1、一般情况下我们都是在Activity当中通过调用startService来启动的,但是Activity并没有重写Context的startService方法,而是调用了ContextWrapper中的startService方法,那么我们就从这里开始了
源码路径:
/frameworks/base/core/java/android/content/ContextWrapper.java
@Override
public ComponentName startService(Intent service)
return mBase.startService(service);
2、通过上面的代码我们看到他调用了mBase.startService(service)方法,mBase是什么我们看一下,然后我们进入他的startService再看
我们看到mBase是Context类型,而Context是一个抽象类,它的实现类是ContextImpl,那么我们就直接去看ContextImpl中的startService就好了
源码路径:
/frameworks/base/core/java/android/app/ContextImpl.java
@Override
public ComponentName startService(Intent service)
//这里只判断了是否是系统进程,如果是打了一段log,忽略
warnIfCallingFromSystemProcess();
//调用了本类的startServiceCommon方法
return startServiceCommon(service, mUser);
3、上面又调用了ContextImpl类中的startServiceCommon方法,进去看看
private ComponentName startServiceCommon(Intent service, UserHandle user)
try
//验证Intent的信息是否有效,无效抛出异常
validateServiceIntent(service);
service.prepareToLeaveProcess();
//这里又调用了ActivityManagerNative中startService
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;
4、上面又转到了ActivityManagerNative.getDefault().startService当中,而ActivityManagerNative.getDefault()是一个Binder对象,我们看一下
源码路径:
/frameworks/base/core/java/android/app/ActivityManagerNative.java
//ActivityManagerNative 类继承Binder 实现了IActivityManager
public abstract class ActivityManagerNative extends Binder implements IActivityManager
...
//getDefault方法返回了gDefault.get()
static public IActivityManager getDefault()
return gDefault.get();
//gDefault是一个单例,
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>()
protected IActivityManager create()
//获取ActivityManagerService
IBinder b = ServiceManager.getService("activity");
if (false)
Log.v("ActivityManager", "default service binder = " + b);
//远程调用将ACtivityManagerService的代理类
IActivityManager am = asInterface(b);
if (false)
Log.v("ActivityManager", "default service = " + am);
return am;
;
//asInterface方法将返回ActivityManagerService的代理类
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);
...
5、通过上面的代码我们可以知道ActivityManagerNative.getDefault()返回的是ActivityManagerService的代理类,也就是ActivityManagerProxy,而ActivityManagerProxy是ActivityManagerNative的内部类其中的startService也只是发起了远程调用,最终会调用到ActivityManagerService中的startService方法,这里有不明白的请先看插件化知识详细分解及原理 之Binder机制
6、上面的代码会转到ActivityManagerService当中,调用startService方法,下面我们就去看ActivityManagerService当中的startService
源码路径:
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback
public ActivityManagerService(Context systemContext)
...
//构造方法中初始化了mServices
mServices = new ActiveServices(this);
...
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
String resolvedType, int userId)
...
//调用了mServices的startServiceLocked方法
ComponentName res = mServices.startServiceLocked(caller, service,
resolvedType, callingPid, callingUid, userId);
Binder.restoreCallingIdentity(origId);
return res;
7、上面的代码又转到了ActiveServices中的startServiceLocked方法中,继续跟进
源码路径:
/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
ComponentName startServiceLocked(IApplicationThread caller,
Intent service, String resolvedType,
int callingPid, int callingUid, int userId)
if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "startService: " + service
+ " type=" + resolvedType + " args=" + service.getExtras());
final boolean callerFg;
//这里的caller是调用者所在的ActivityThread中的内部类ApplicationThread,它也是一个Binder对象
//主要用来和应用进程进行通信
if (caller != null)
final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
if (callerApp == null)
throw new SecurityException(
"Unable to find app for caller " + caller
+ " (pid=" + Binder.getCallingPid()
+ ") when starting service " + service);
callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
else
callerFg = true;
//retrieveServiceLocked是解析Intent对象,从ActivityManagerService中取这个进程中
//的ServiceMap,然后从ServiceMap当中看是否存在这个service的ServiceRecord,
//如果不存在则创建一个ServiceRecord,ServiceRecord是用来记录这个service的各种信息的,
//包括属于哪个进程,service的名称,应用包名等等,然后将ServiceRecord存入ActivityManagerService
//的成员变量mServiceMap当中
ServiceLookupResult res =
retrieveServiceLocked(service, resolvedType,
callingPid, callingUid, userId, true, callerFg);
if (res == null)
return null;
if (res.record == null)
return new ComponentName("!", res.permission != null
? res.permission : "private to package");
ServiceRecord r = res.record;
...
//接着调用本类的startServiceInnerLocked方法
return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
8、上面说到了ServiceRecord,ServiceRecord是用来记录这个service的各种信息的,包括属于哪个进程,service的名称,应用包名等等
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service,
ServiceRecord r, boolean callerFg, boolean addToStarting)
....
//又转到了bringUpServiceLocked方法
String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
if (error != null)
return new ComponentName("!!", error);
....
return r.name;
9、点进去,接着看bringUpServiceLocked方法
private final String bringUpServiceLocked(ServiceRecord r,
int intentFlags, boolean execInFg, boolean whileRestarting)
...
//判断要启动的Service是否已经启动,如果启动只调用onStartCommand方法,下面再分析这个方法
if (r.app != null && r.app.thread != null)
sendServiceArgsLocked(r, execInFg, false);
return null;
.....
final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != ;
final String procName = r.processName;
ProcessRecord app;
//判断要启动的这个service是否配置了要在独立进程中启动,之前是否加载过这个进程
if (!isolated)
app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
+ " app=" + app);
//之前加载过该进程,不需要再创建
if (app != null && app.thread != null)
try
app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
//启动service,一会分析
realStartServiceLocked(r, app, execInFg);
return null;
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.
else
app = r.isolatedProc;
// Not running -- get it started, and enqueue this service record
// to be executed when the app comes up.
if (app == null)
//没有加载过这个进程,创建一个新的进程,然后启动service
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);
//启动service,一会分析
bringDownServiceLocked(r);
return msg;
if (isolated)
r.isolatedProc = app;
//保存这个ServiceRecord
if (!mPendingServices.contains(r))
mPendingServices.add(r);
....
return null;
10、在即将启动service的时候突然出现了三种情况,我们总结一下
v1:要启动的Service是否已经启动,调用了sendServiceArgsLocked方法
v2:Service没有启动,但是需要启动这个service的进程已经存在,调用了realStartServiceLocked方法
v3:Service没有启动,但是需要启动这个service的进程不存在,调用了bringDownServiceLocked
v1.1、我们先来看如果这个service已经启动的情况,即sendServiceArgsLocked方法:
private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
boolean oomAdjusted)
....
//调用了r.app.thread,这个参数其实就是上面说过的ActivitiyThread中的内部类ApplicationThread
r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
....
v1.2、上面调用了ActivitiyThread中的内部类ApplicationThread的scheduleServiceArgs方法,那么我们就去找这个方法就好了
源码路径:
/frameworks/base/core/java/android/app/ActivityThread.java
private class ApplicationThread extends ApplicationThreadNative
....
public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
int flags ,Intent args)
ServiceArgsData s = new ServiceArgsData();
s.token = token;
s.taskRemoved = taskRemoved;
s.startId = startId;
s.flags = flags;
s.args = args;
//这里是要发送一条消息
sendMessage(H.SERVICE_ARGS, s);
....
private void sendMessage(int what, Object obj)
sendMessage(what, obj, 0, 0, false);
private void sendMessage(int what, Object obj, int arg1)
sendMessage(what, obj, arg1, 0, false);
private void sendMessage(int what, Object obj, int arg1, int arg2)
sendMessage(what, obj, arg1, arg2, false);
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);
v1.3、上面所有的发送消息的方法最终都会走到参数最多的那个,然后通过mH发送了一条消息,而mH其实就是一个Handler,也是在ActivityThread当中通过内部类的方式创建的,上面发送的是H.SERVICE_ARGS,我们去找这个对应的常量就好了
case SERVICE_ARGS:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart");
//调用service的onStartCommand方法
handleServiceArgs((ServiceArgsData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
v1.4、在接着看ActivityThread当中的handleServiceArgs方法
private void handleServiceArgs(ServiceArgsData data)
//从map中取出service,因为这里已经启动的service
Service s = mServices.get(data.token);
if (s != null)
try
if (data.args != null)
data.args.setExtrasClassLoader(s.getClassLoader());
data.args.prepareToEnterProcess();
int res;
if (!data.taskRemoved)
//回调service的onStartCommand方法
res = s.onStartCommand(data.args, data.flags, data.startId);
else
s.onTaskRemoved(data.args);
res = Service.START_TASK_REMOVED_COMPLETE;
QueuedWork.waitToFinish();
try
//告诉ActivityManagerService,onStartCommand方法已经回调完毕
ActivityManagerNative.getDefault().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
catch (RemoteException e)
// nothing to do.
ensureJitEnabled();
catch (Exception e)
if (!mInstrumentation.onException(s, e))
throw new RuntimeException(
"Unable to start service " + s
+ " with " + data.args + ": " + e.toString(), e);
v1.5、好了,到这里我们就分析完了启动service时的第一种情况,也就是这个service已经被启动了后再次调用startService方法的流程
v2、1:Service没有启动,但是需要启动这个service的进程已经存在,调用了realStartServiceLocked方法,
private final void realStartServiceLocked(ServiceRecord r,
ProcessRecord app, boolean execInFg) throws RemoteException
....
//启动创建service
app.thread.scheduleCreateService(r, r.serviceInfo,
....
//绑定service,即
requestServiceBindingsLocked(r, execInFg);
....
//调用service的onStartCommand方法,上边分析过这个方法了
sendServiceArgsLocked(r, execInFg, true);
....
v2、2上面的几个方法都和第一个分析调用onStartCommand的方式一样,只不过调用的方法不同,下面不再贴代码了,我们看一下最后一种创建进程的那种情况
二、新进程启动过程 :
v3.1、Service没有启动,但是需要启动这个service的进程不存在,调用了bringDownServiceLocked,我们再看一下最会出现三种情况的那个方法,这里我们也只分析创建进程的这一部分,其余的原理和步骤都和上边分析的相同。
private final String bringUpServiceLocked(ServiceRecord r,
int intentFlags, boolean execInFg, boolean whileRestarting)
...
//省略前两种情况了,已经分析过
if (app == null)
//没有加载过这个进程,创建一个新的进程,然后启动service
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);
//启动service,一会分析
bringDownServiceLocked(r);
return msg;
if (isolated)
r.isolatedProc = app;
//保存这个ServiceRecord
if (!mPendingServices.contains(r))
mPendingServices.add(r);
....
return null;
v3.2、上面判断如果需要创建进程的话是通过调用mAm.startProcessLocked生成了进程,mAm就是AMS,我们直接看startProcessLocked方法
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs)
long startTime = SystemClock.elapsedRealtime();
.....
try
.....
//注意看如果entryPoint等于null的话,会被赋值android.app.ActivityThread
boolean isActivityProcess = (entryPoint == null);
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
checkTime(startTime, "startProcess: asking zygote to start proc");
//启动进程
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);
checkTime(startTime, "startProcess: returned from zygote!");
....
catch (RuntimeException e)
.....
v3.3、指定了ActivityThread的这个类后,在创建进程完成后会调用ActivityThread的main方法,生成进程的代码在Process.java中,想去深入了解的自行查阅,我们再去看ActivityThread
源码路径:
/frameworks/base/core/java/android/app/ActivityThread.java
public final class ActivityThread
....
//直接创建了一个ApplicationThread类型的mAppThread成员变量
final ApplicationThread mAppThread = new ApplicationThread();
....
//main方法
public static void main(String[] args)
SamplingProfilerIntegration.start();
....
//创建Looper
Looper.prepareMainLooper();
//创建自己的实例
ActivityThread thread = new ActivityThread();
//准备和AMS绑定
thread.attach(false);
if (sMainThreadHandler == null)
sMainThreadHandler = thread.getHandler();
if (false)
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
//开启Looper循环
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
//这里和AMS绑定,system代表是否为系统进程
private void attach(boolean system)
sCurrentActivityThread = this;
mSystemThread = system;
if (!system)
....
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManagerNative.getDefault();
try
//和AMS绑定
mgr.attachApplication(mAppThread);
catch (RemoteException ex)
// Ignore
....
else
//是系统进程
android.ddm.DdmHandleAppName.setAppName("system_process",
UserHandle.myUserId());
try
mInstrumentation = new Instrumentation();
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();
catch (Exception e)
throw new RuntimeException(
"Unable to instantiate Application():" + e.toString(), e);
// add dropbox logging to libcore
DropBox.setReporter(new DropBoxReporter());
//ViewRootImpl添加onConfigurationChanged 、 onLowMemory 、 onTrimMemory等方法回调
ViewRootImpl.addConfigCallback(new ComponentCallbacks()
@Override
public void onConfigurationChanged(Configuration newConfig)
synchronized (mResourcesManager)
// We need to apply this change to the resources
// immediately, because upon returning the view
// hierarchy will be informed about it.
if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null))
// This actually changed the resources! Tell
// everyone about it.
if (mPendingConfiguration == null ||
mPendingConfiguration.isOtherSeqNewer(newConfig))
mPendingConfiguration = newConfig;
sendMessage(H.CONFIGURATION_CHANGED, newConfig);
@Override
public void onLowMemory()
@Override
public void onTrimMemory(int level)
);
v3.4、这里调用了ActivityManagerNative.getDefault()的attachApplication方法,我们上面分析过ActivityManagerNative.getDefault()返回的是AMS的代理里,那么我们直接去看AMS中的attachApplication方法
源码路径:
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@Override
public final void attachApplication(IApplicationThread thread)
synchronized (this)
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
//调用了本类的attachApplicationLocked方法
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
v3.5、再看一下attachApplicationLocked
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid)
.....
ApplicationInfo appInfo = app.instrumentationInfo != null
? app.instrumentationInfo : app.info;
app.compat = compatibilityInfoForPackageLocked(appInfo);
if (profileFd != null)
profileFd = profileFd.dup();
ProfilerInfo profilerInfo = profileFile == null ? null
: new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
//调用了传进来的ActivityThread的内部类ApplicationThread的bindApplication方法
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked());
updateLruProcessLocked(app, false, null);
app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
catch (Exception e)
Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
app.resetPackageList(mProcessStats);
app.unlinkDeathRecipient();
startProcessLocked(app, "bind fail", processName);
return false;
......
//上面创建Application后再进一步操作Serivice,一会反回来分析
if (!badApp)
try
didSomething |= mServices.attachApplicationLocked(app, processName);
catch (Exception e)
Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
badApp = true;
return true;
v3.6、attachApplicationLocked的代码非常的多,我们只看相关代码
,这里调用了刚刚传进来的ActivityThread内部类ApplicationThread的
bindApplication方法,我们再返回ActivityThread中看
源码路径:
/frameworks/base/core/java/android/app/ActivityThread.java
public final void bindApplication(String processName, ApplicationInfo appInfo,
List<ProviderInfo> providers, ComponentName instrumentationName,
ProfilerInfo profilerInfo, Bundle instrumentationArgs,
IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,
Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
Bundle coreSettings)
....
//创建绑定数据
AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
data.providers = providers;
data.instrumentationName = instrumentationName;
data.instrumentationArgs = instrumentationArgs;
data.instrumentationWatcher = instrumentationWatcher;
data.instrumentationUiAutomationConnection = instrumentationUiConnection;
data.debugMode = debugMode;
data.enableOpenGlTrace = enableOpenGlTrace;
data.restrictedBackupMode = isRestrictedBackupMode;
data.persistent = persistent;
data.config = config;
data.compatInfo = compatInfo;
data.initProfilerInfo = profilerInfo;
//发送消息到Handler中
sendMessage(H.BIND_APPLICATION, data);
v3.7、我们上面也分析过消息会发送到ActivityThread中的内部类Handler中,我们找一个这个常量指定的处理
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
//拿到刚才创建的绑定数据
AppBindData data = (AppBindData)msg.obj;
//调用了handleBindApplication方法
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
v3.8、我们再去看一下handleBindApplication
private void handleBindApplication(AppBindData data)
....
//创建上下文对象
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
....
//准备初始化的数据
if (data.instrumentationName != null)
InstrumentationInfo ii = null;
try
ii = appContext.getPackageManager().
getInstrumentationInfo(data.instrumentationName, );
catch (PackageManager.NameNotFoundException e)
if (ii == null)
throw new RuntimeException(
"Unable to find instrumentation info for: "
+ data.instrumentationName);
mInstrumentationPackageName = ii.packageName;
mInstrumentationAppDir = ii.sourceDir;
mInstrumentationSplitAppDirs = ii.splitSourceDirs;
mInstrumentationLibDir = ii.nativeLibraryDir;
mInstrumentedAppDir = data.info.getAppDir();
mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
mInstrumentedLibDir = data.info.getLibDir();
//准备创建Application的数据
ApplicationInfo instrApp = new ApplicationInfo();
instrApp.packageName = ii.packageName;
instrApp.sourceDir = ii.sourceDir;
instrApp.publicSourceDir = ii.publicSourceDir;
instrApp.splitSourceDirs = ii.splitSourceDirs;
instrApp.splitPublicSourceDirs = ii.splitPublicSourceDirs;
instrApp.dataDir = ii.dataDir;
instrApp.nativeLibraryDir = ii.nativeLibraryDir;
//LoadedApk对象是APK文件在内存中的表示。 //Apk文件的相关信息,诸如Apk文件的代码和资源,甚至代码里面的Activity,Service等四大组件的信息我们都可以通过此对象获取
LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
appContext.getClassLoader(), false, true, false);
//创建新进程的Context
ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
try
//创建Instrumentation对象
java.lang.ClassLoader cl = instrContext.getClassLoader();
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
catch (Exception e)
throw new RuntimeException(
"Unable to instantiate instrumentation "
+ data.instrumentationName + ": " + e.toString(), e);
//初始化Instrumentation
mInstrumentation.init(this, instrContext, appContext,
new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher,
data.instrumentationUiAutomationConnection);
....
else
mInstrumentation = new Instrumentation();
....
try
//通过创建Application并回调Application的attach方法
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
....
try
//回调Application的OnCreate方法
mInstrumentation.callApplicationOnCreate(app);
catch (Exception e)
if (!mInstrumentation.onException(app, e))
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
finally
StrictMode.setThreadPolicy(savedPolicy);
v3.9、这里不要蒙啊,这里是创建了新的进程,所以应该也就知道了每个进程都会创建一个Application对象,到这里新进程的创建就完了,我们总结一下
总结进程启动:新进程通过调用Process.start的方法启动一个进程,然后因为指定了android.app.ActivityThread的这个类,所以在创建进程之后会调用android.app.ActivityThread类中的main方法,在main方法中会开启消息循环,然后创建了一个ActivityThread实例,调用attach方法,在attach方法中,通过AMS.attachApplication方法,将ActivityThread当中的内部类ApplicationThread和AMS绑定,之后这个进程的所有通信全部都是靠ApplicationThread和AMS和ActivityThread中的Handler来进行,希望本能能对大家有所帮助,从一个启动的过程可以窥视Android的通信机制及运行原理。
好了,我们在返回到v3.5中AMS中的attachApplicationLocked方法,我们在贴一下代码
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid)
.....
ApplicationInfo appInfo = app.instrumentationInfo != null
? app.instrumentationInfo : app.info;
app.compat = compatibilityInfoForPackageLocked(appInfo);
if (profileFd != null)
profileFd = profileFd.dup();
ProfilerInfo profilerInfo = profileFile == null ? null
: new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
//调用了传进来的ActivityThread的内部类ApplicationThread的bindApplication方法
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
以上是关于Service启动过程and新进程创建全过程源码分析的主要内容,如果未能解决你的问题,请参考以下文章
windows Service 之调试过程(附加到进程里调试,而且启动时间不能超过30秒)
go语言创建新进程过程详解 (os.StartProcess源码分析)