目录
一、Android APK的构建过程
二、Android 应用进程启动过程
三、 Android Activity的启动流程
通过IDE可以生成可以在android设备中安装的apk文件,Google官方提供的构建APK的过程流程图如下:
我们知道,通过Intent就可以执行APK安装的,执行如下代码后,我们就会打开安装apk文件的程序并执行安装逻辑了,大家应该都知道这段代码执行的结果是打开一个隐式的Activity,即PackageInstallerActivity。
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(Uri.parse("file://" + path),"application/vnd.android.package-archive");
context.startActivity(intent);
首先,Android在系统架构分为四个层面。从高层到低层分别是应用程序层、应用程序框架层、系统运行库层和linux核心层。另外,进程是系统的执行单位。Linux系统是核心底层,那么Android的其他进程都是基于Linux进程的根进程init进程,因此它可以算作是整个android操作系统的第一个进程。最后,我们知道android系统的Zygote进程是所有的android进程的父进程,包括SystemServer和各种应用进程都是通过Zygote进程fork出来的。而Zygote进程则是通过linux系统的init进程启动的,也就是说,android系统中各种进程的启动方式及顺序是:
init进程 –> Zygote进程 –> SystemServer进程 –>各种应用进程
各种应用进程:启动自己编写的客户端应用时,一般都是重新启动一个应用进程,有自己的虚拟机与运行环境;
init进程在启动Zygote进程时一般都会调用ZygoteInit类的main方法,Zygote进程mian方法主要执行逻辑:
初始化DDMS;
注册Zygote进程的socket通讯;
初始化Zygote中的各种类,资源文件,OpenGL,类库,Text资源等等;
初始化完成之后fork出SystemServer进程;
fork出SystemServer进程之后,关闭socket连接;
其实,SystemServer进程主要的作用是启动各种系统服务,比如ActivityManagerService,PackageManagerService,WindowManagerService等服务。我们平时熟知的各种系统性的服务其实都是在SystemServer进程中启动的,而当我们的应用需要使用各种系统服务的时候,其实也是通过与SystemServer进程通讯获取各种服务对象的句柄来执行相应的操作。
SystemServer进程启动服务的启动函数为main函数;
SystemServer在执行过程中首先会初始化一些系统变量,加载类库,创建Context对象,创建SystemServiceManager对象等之后才开始启动系统服务;
SystemServer进程将系统服务分为三类:boot服务,core服务和other服务,并逐步启动;
SystemServer进程在尝试启动服务之前会首先尝试与Zygote建立socket通讯,只有通讯成功之后才会开始尝试启动服务;
创建的系统服务过程中主要通过SystemServiceManager对象来管理,通过调用服务对象的构造方法和onStart方法初始化服务的相关变量;
服务对象都有自己的异步消息对象,并运行在单独的线程中;
其实,我们知道SystemServer进程主要用于启动系统的各种服务,而且其中就包含负责启动Launcher程序的服务-LauncherAppService。Launcher 程序就是我们平时看到的桌面程序,它其实也是一个android应用程序,只不过这个应用程序是系统默认第一个启动的应用程序,这里我们就简单的分析一下Launcher应用的启动流程。
前面说SystemServer调用三个内部方法分别启动boot service、core service和other service。在调用startOtherService方法中就会通过调用mActivityManagerService.systemReady()方法。
public void systemReady(final Runnable goingCallback) {
...
// Start up initial activity.
mBooting = true;
startHomeActivityLocked(mCurrentUserId, "systemReady");
...
}
这个方法体中调用了startHomeActivityLocked方法,看名字就知道开始执行启动homeActivity的操作。好了,既然如此,我们再看一下startHomeActivityLocked的具体实现:
boolean startHomeActivityLocked(int userId, String reason) {
if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
&& mTopAction == null) {
return false;
}
Intent intent = getHomeIntent();//下面第一段代码进入查看
ActivityInfo aInfo =
resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
if (aInfo != null) {
intent.setComponent(new ComponentName(
aInfo.applicationInfo.packageName, aInfo.name));
aInfo = new ActivityInfo(aInfo);
aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
ProcessRecord app = getProcessRecordLocked(aInfo.processName,
aInfo.applicationInfo.uid, true);
if (app == null || app.instrumentationClass == null) {
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
mStackSupervisor.startHomeActivity(intent, aInfo, reason);//第二段代码查看
}
}
return true;
}
Intent getHomeIntent() {
Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
intent.setComponent(mTopComponent);
if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
intent.addCategory(Intent.CATEGORY_HOME);
}
return intent;
}
可以发现,Intent是一个隐士对象,并且添加了Intent.CATEGORY_HOME常量,这个其实是一个launcher的标志,一般系统的启动页面Activity都会在androidmanifest.xml中配置这个标志。
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason) {
moveHomeStackTaskToTop(HOME_ACTIVITY_TYPE, reason);
startActivityLocked(null /* caller */, intent, null /* resolvedType */, aInfo,
null /* voiceSession */, null /* voiceInteractor */, null /* resultTo */,
null /* resultWho */, 0 /* requestCode */, 0 /* callingPid */, 0 /* callingUid */,
null /* callingPackage */, 0 /* realCallingPid */, 0 /* realCallingUid */,
0 /* startFlags */, null /* options */, false /* ignoreTargetSecurity */,
false /* componentSpecified */,
null /* outActivity */, null /* container */, null /* inTask */);
if (inResumeTopActivity) {
scheduleResumeTopActivities();
}
}
发现其调用的是scheduleResumeTopActivities()方法,这个方法其实是关于Activity的启动流程的逻辑的,这逻辑后面会讲。因为我们的Launcher启动的Intent是一个隐士的Intent,所以我们会启动在androidmanifest.xml中配置了相同catogory的activity,androidManifest中配置的这个catogory其实就是LauncherActivity。
LauncherActivity继承与ListActivity,我们先看一下其Layout布局文件和onCreate方法:
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
mPackageManager = getPackageManager();
if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setProgressBarIndeterminateVisibility(true);
}
onSetContentView();
mIconResizer = new IconResizer();
mIntent = new Intent(getTargetIntent());
mIntent.setComponent(null);
mAdapter = new ActivityAdapter(mIconResizer);
setListAdapter(mAdapter);
getListView().setTextFilterEnabled(true);
updateAlertTitle();
updateButtonText();
if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
setProgressBarIndeterminateVisibility(false);
}
}
可见,手机桌面其实就是一个ListView控件,在onCreate方法中初始化了一个PackageManager,从中查询出系统所有已经安装的应用列表,包括应用包名、图标等信息,然后将这些信息以Adapter方式注入到Listview中将系统应用图标和名称显示出来。 另外,在系统的回调方法onListItemClick中说明了,为什么我们点击某一个应用图标之后就可以启动某一项应用的原因了。
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Intent intent = intentForPosition(position);
startActivity(intent);
}
protected Intent intentForPosition(int position) {
ActivityAdapter adapter = (ActivityAdapter) mAdapter;
return adapter.intentForPosition(position);
}
public Intent intentForPosition(int position) {
if (mActivitiesList == null) {
return null;
}
Intent intent = new Intent(mIntent);
ListItem item = mActivitiesList.get(position);
intent.setClassName(item.packageName, item.className);
if (item.extras != null) {
intent.putExtras(item.extras);
}
return intent;
}
所以,LauncherActivity中是以ListView来显示我们的应用图标列表的,并且为每个Item保存了应用的包名和启动Activity类名,这样点击某一项应用图标的时候就可以根据应用包名和启动Activity名称启动我们的App了。
其实Android中应用进程可以通过许多方式启动,比如启动一个Activity、Service、ContentProvider或BroadcastReceiver,也就是说通过启动四大组件的方式启动,这时候系统会判断当前这些组件所需要的应用进程是否已经启动,若没有的话,则会启动应用进程。通过上面Launcher启动流程,我们知道每一个launcher中的图标对应着一个应用报名和启动activity类名,查看LauncherActivity中的图标点击事件:
protected void onListItemClick(ListView l, View v, int position, long id) {
Intent intent = intentForPosition(position);
startActivity(intent);
}
这里调用了startActivity方法传入Intentd对象来启动这个activity。很明显,当前该应用属于冷启动,也就是说我们调用的startActivity方法不单单为我们启动了这个activity,也同时在启动activity之前启动了这个应用进程。好了,那我们这里就以这个方法为入口分析一下应用进程的启动流程。
@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
发现其调用的startActivity的重载方法,传入Intent对象和可为空Bundle对象。 并且发现继续调用startActivityForResult方法。
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
startActivityForResult(intent, -1);
}
}
很明显的此时传递的options为空,继续跟进:
public void startActivityForResult(Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, null);
}
好吧,最后调用的还是startActivityForResult(intent, requestCode, null)这个重载方法:
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
if (mParent == null) {
Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),ar.getResultData());
}
if (requestCode >= 0) {
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
首先注意mInstrumentation.execStartActivity方法。Instrumentation对象,他是Android系统中应用程序端操作Activity的具体操作类,这里的操作是相对于ActivityManagerService服务端来说的。也就是说当我们在执行对Activity的具体操作时,比如回调生命周期的各个方法都是借助于Instrumentation类来实现的。看一下源码:
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
...
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess();
//关键代码
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
关键代码段实际上是进程间通讯。ActivityManagerNative继承于Binder接口,本身就是一个Binder对象,然后上面我们介绍SystemServer进程的时候对ActivityManagerService有过了解,发现其继承于ActivityManagerNative,好吧,了解过Binder机制的知道,ActivityManagerService就是这个Binder机制的服务器端而ActivityManagerNative就是这个Binder机制的客户端。所以我们这里调用的startActivity实际上是将参数传递给ActivityManagerService,并执行ActivityManagerService的startActivity方法。
既然这样,我们看一下ActivityManagerService的startActivity方法:
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, options,
UserHandle.getCallingUserId());
}
然后我们继续看一下startActivityAsUser方法:
@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
enforceNotIsolatedCaller("startActivity");
userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
false, ALLOW_FULL_ONLY, "startActivity", null);
return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, options, false, userId, null, null);
}
继续查看startActivityMayWait方法:
final int startActivityMayWait(IApplicationThread caller, int callingUid,
String callingPackage, Intent intent, String resolvedType,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, WaitResult outResult, Configuration config,
Bundle options, boolean ignoreTargetSecurity, int userId,
IActivityContainer iContainer, TaskRecord inTask) {
...
int res = startActivityLocked(caller, intent, resolvedType, aInfo,
voiceSession, voiceInteractor, resultTo, resultWho,
requestCode, callingPid, callingUid, callingPackage,
realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,
componentSpecified, null, container, inTask);
...
return res;
}
}
这里调用了startActivityLocked方法,也就是说在初始化其他逻辑之后,这个方法会调用startActivityLocked方法,然后我们查看startActivityLocked方法发现其调用了resumeTopActivitiesLocked方法:
if (doResume) {
mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
}
继续跟进:
final boolean resumeTopActivityLocked(ActivityRecord prev) {
return resumeTopActivityLocked(prev, null);
}
resumeTopActivityLocked方法中又调用了resumeTopActivityInnerLocked方法,resumeTopActivityInnerLocked方法中又调用了startSpecificActivityLocked方法:
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
String hostingType, ComponentName hostingName, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
null /* crashHandler */);
}
查看startProcessLocked方法的具体实现:
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!");
查看关键代码,这里调用了Process.start方法:
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[] zygoteArgs) {
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
debugFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
Log.e(LOG_TAG,
"Starting VM process through Zygote failed");
throw new RuntimeException(
"Starting VM process through Zygote failed", ex);
}
}
最后,这里的processClass就是要启动的进程的名称,这里传递的就是ActivityThread:"android.app.ActivityThread"。具体的Process启动进程的Native层代码这里不做过多的分析,这个方法就是启动了AcitivtyThread进程并执行了ActivityThread的main方法,所以我们经常说的进程的启动方法就是ActivityThread的main方法,就在这里实现的。
Activity的启动流程一般是通过调用startActivity或者是startActivityForResult来开始的
startActivity内部也是通过调用startActivityForResult来启动Activity,只不过传递的requestCode小于0
Activity的启动流程涉及到多个进程之间的通讯这里主要是ActivityThread与ActivityManagerService之间的通讯
ActivityThread向ActivityManagerService传递进程间消息通过ActivityManagerNative,ActivityManagerService向ActivityThread进程间传递消息通过IApplicationThread。
ActivityManagerService接收到应用进程创建Activity的请求之后会执行初始化操作,解析启动模式,保存请求信息等一系列操作。
ActivityManagerService保存完请求信息之后会将当前系统栈顶的Activity执行onPause操作,并且IApplication进程间通讯告诉应用程序继承执行当前栈顶的Activity的onPause方法;
ActivityThread接收到SystemServer的消息之后会统一交个自身定义的Handler对象处理分发;
ActivityThread执行完栈顶的Activity的onPause方法之后会通过ActivityManagerNative执行进程间通讯告诉ActivityManagerService,栈顶Actiity已经执行完成onPause方法,继续执行后续操作;
ActivityManagerService会继续执行启动Activity的逻辑,这时候会判断需要启动的Activity所属的应用进程是否已经启动,若没有启动则首先会启动这个Activity的应用程序进程;
ActivityManagerService会通过socket与Zygote继承通讯,并告知Zygote进程fork出一个新的应用程序进程,然后执行ActivityThread的mani方法;
在ActivityThead.main方法中执行初始化操作,初始化主线程异步消息,然后通知ActivityManagerService执行进程初始化操作;
ActivityManagerService会在执行初始化操作的同时检测当前进程是否有需要创建的Activity对象,若有的话,则执行创建操作;
ActivityManagerService将执行创建Activity的通知告知ActivityThread,然后通过反射机制创建出Activity对象,并执行Activity的onCreate方法,onStart方法,onResume方法;
ActivityThread执行完成onResume方法之后告知ActivityManagerService onResume执行完成,开始执行栈顶Activity的onStop方法;
ActivityManagerService开始执行栈顶的onStop方法并告知ActivityThread;
ActivityThread执行真正的onStop方法;