本文使用到的相关源码路径:Android9.0 APP启动源码
1、启动简介
1.1、启动流程:
- 点击桌面App图标,Launcher进程采用Binder IPC向system_server进程发起startActivity请求;
- system_server进程接收到请求后,向Zygote进程发送创建进程的请求;
- Zygote进程fork出新的子进程,即App进程;
- App进程,通过Binder IPC向sytem_server进程发起attachApplication请求;
- system_server进程在收到请求后,进行一系列准备工作后,再通过binder IPC向App进程发送创建Activity请求;
- App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送消息执行创建事务;
- 主线程在收到Message后,通过反射机制创建目标Activity,并回调Activity.onCreate()等方法;
- 到此,App便正式启动,开始进入Activity生命周期,执行完onCreate/onStart/onResume方法,UI渲染结束后便可以看到App的主界面;
1.2、Activity启动流程图
1.3、其中涉及到的进程交互方式
- Launcher进程与AMS所在的System_Server进程为AIDL方式;
- AMS所在的System_Server进程与Zygote进程为Socket通讯;
- Zygote进程与新建的APP进程为Binder IPC方式;
2、Activity启动源码
2.1、Launcher进程阶段
Android中桌面也属于一个APP,也就是LauncherApp,其中桌面图标是以BubbleTextView的控件展示的,并且在Launcher中为其设置有点击事件,具体点击事件为ItemClickHandler类的INSTANCE对象;
public View createShortcut(ViewGroup parent, ShortcutInfo info) {
BubbleTextView favorite = (BubbleTextView) LayoutInflater.from(parent.getContext()).inflate(R.layout.app_icon, parent, false);
favorite.applyFromShortcutInfo(info);
// 桌面图标设置点击事件
favorite.setOnClickListener(ItemClickHandler.INSTANCE);
favorite.setOnFocusChangeListener(mFocusHandler);
return favorite;
}
2.1.1、点击桌面图标
点击桌面图标,解析图标信息,桌面图标属于AppInfo类型,所以调用startAppShortcutOrInfoActivity()方法;
public static final OnClickListener INSTANCE = ItemClickHandler::onClick;
private static void onClick(View v) {
// 略...
Launcher launcher = Launcher.getLauncher(v.getContext());
// 略...
Object tag = v.getTag();
if (tag instanceof ShortcutInfo) {
onClickAppShortcut(v, (ShortcutInfo) tag, launcher);
} else if (tag instanceof FolderInfo) {
// 略...
} else if (tag instanceof AppInfo) {
// 桌面图标类型为App,进入该分支
startAppShortcutOrInfoActivity(v, (AppInfo) tag, launcher);
} else if (tag instanceof LauncherAppWidgetInfo) {
// 略...
}
}
在startAppShortcutOrInfoActivity()方法中,新建Intent对象,并设置包名为null,进一步调用Launcher类的startActivitySafely()方法;
private static void startAppShortcutOrInfoActivity(View v, ItemInfo item, Launcher launcher) {
Intent intent;
// ...
if (item instanceof ShortcutInfo) {
ShortcutInfo si = (ShortcutInfo) item;
if (si.hasStatusFlag(ShortcutInfo.FLAG_SUPPORTS_WEB_UI) && intent.getAction() == Intent.ACTION_VIEW) {
// make a copy of the intent that has the package set to null
// we do this because the platform sometimes disables instant
// apps temporarily (triggered by the user) and fallbacks to the
// web ui. This only works though if the package isn't set
intent = new Intent(intent);
intent.setPackage(null);
}
}
launcher.startActivitySafely(v, intent, item);
}
在Launcher类的startActivitySafely()方法中,会调用其父类BaseDraggingActivity的startActivitySafely(),在该方法中进行一系列判断,最终调用了startActivity()方法;
public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
// 略...
UserHandle user = item == null ? null : item.user;
// 设置开启新栈的标识位
// Prepare intent
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// 略...
try {
boolean isShortcut =
Utilities.ATLEAST_MARSHMALLOW // SDK版本是否大于M
&& (item instanceof ShortcutInfo) // item类型,此处为AppInfo,所以为false
&& (item.itemType == Favorites.ITEM_TYPE_SHORTCUT || item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT) && !((ShortcutInfo) item).isPromise();
if (isShortcut) {
// Shortcuts need some special checks due to legacy reasons.
startShortcutIntentSafely(intent, optsBundle, item);
} else if (user == null || user.equals(Process.myUserHandle())) {
// 系统进程
// Could be launching some bookkeeping activity
startActivity(intent, optsBundle);
} else {
// ...
}
BaseDraggingActivity类继承自BaseActivity(),BaseActivity又继承自Activity类,在BaseDraggingActivity和BaseActivity中没有实现startActivity()方法,所以最终调用到了父类Activity类的startActivity()方法,然后继续调用startActivityForResult()方法;
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options);
// ...
} else {
// ...
}
}
在startActivityForResult()方法中执行Instrumentation类的execStartActivity()方法;
public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
// ...
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
int result = ActivityManager.getService().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;
}
2.1.2、Launcher进程拿到AMS的代理
这里通过ActivityManager.getService()来调用startActivity();
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton = new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
以上可知,Launcher进程与AMS所在的system_server进程的IPC方式为AIDL通信,即Binder IPC方式;
对比旧版本中的ActivityManagerNative中,已经标注该类已过时;
/**
* {@hide}
* @deprecated will be removed soon. See individual methods for alternatives.
*/
@Deprecated
public abstract class ActivityManagerNative {
/**
* Cast a Binder object into an activity manager interface, generating
* a proxy if needed.
*
* @deprecated use IActivityManager.Stub.asInterface instead.
*/
static public IActivityManager asInterface(IBinder obj) {
return IActivityManager.Stub.asInterface(obj);
}
//...
}
2.1.3、向AMS进程发起创建请求
Launcher进程拿到AMS在Launcher进程中的代理之后,通过代理对象调用接口方法,根据aidl通信可知,会调用到AMS的具体实现类,由此进入到system_server进程;
ActivityManager.getService().startActivity
2.2、system_server进程阶段
AMS是所有Activity的管理者,位于Android system_server进程中;
2.2.1、AMS向Zygote发起创建进程请求
ActivityManagerService也实现了IActivityManager.Stub接口,执行其startActivity()方法,经过多次重载函数的调用;
public class ActivityManagerService extends IActivityManager.Stub implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
@Override
public final int startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, UserHandle.getCallingUserId());
}
@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId, true /*validateIncomingUser*/);
}
public final int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
enforceNotIsolatedCaller("startActivity");
userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser, Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// TODO: Switch to user app stacks here.
return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId)
.execute();
}
// ...
}
最后执行mActivityStartController.obtainStarter().execute(),mActivityStartController是ActivityStartController类对象,查看其obtainStarter()方法;
/**
* @return A starter to configure and execute starting an activity. It is valid until after
* {@link ActivityStarter#execute} is invoked. At that point, the starter should be
* considered invalid and no longer modified or used.
*/
ActivityStarter obtainStarter(Intent intent, String reason) {
return mFactory.obtain().setIntent(intent).setReason(reason);
}
返回一个ActivityStarter对象,并将Intent对象设置进去,已经reason,即调用方传的“startActivityAsUser”参数;
ActivityStarter类中查看对应方法,这里需要注意setMayWait()方法;
ActivityStarter setMayWait(int userId) {
mRequest.mayWait = true;
mRequest.userId = userId;
return this;
}
该方法中将mRequest的mayWait属性设置为true,并设置userId,继续执行execute()方法,判断mRequest.mayWait是否为ture,进入对应的分支;
/**
* Starts an activity based on the request parameters provided earlier.
* @return The starter result.
*/
int execute() {
try {
// TODO(b/64750076): Look into passing request directly to these methods to allow
// for transactional diffs and preprocessing.
if (mRequest.mayWait) {
return startActivityMayWait(mRequest.caller, mRequest.callingUid,
mRequest.callingPackage, mRequest.intent,
mRequest.resolvedType, mRequest.voiceSession,
mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode,
mRequest.startFlags, mRequest.profilerInfo,
mRequest.waitResult, mRequest.globalConfig,
mRequest.activityOptions, mRequest.ignoreTargetSecurity,
mRequest.userId, mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup,
mRequest.originatingPendingIntent);
} else {
// ...
} finally {
onExecutionComplete();
}
}