Launcher是默认的桌面应用,在系统启动后开始启动Launcher,进而才加载桌面数据。那么如何实现开机进入默认Launcher,比如把自己写的应用设置成开机默认启动的桌面呢?带着这个问题来分析Launcher是如何被选中并成为默认桌面应用而启动的。
SystemServer启动ActivityManagerService并调用了它的systemReady()函数。
ActivityManagerService
public void systemReady(final Runnable goingCallback){
//Start up initial actiivty
mBooting = true;
startHomeActivityLocked(mCurrentUserId, "systemReady");
}
接着调用startHomeActivityLocked()启动Launcher
boolean startHomeActivityLocked(int userId, String reason){
if(mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) && mTopAction == null){
// We are running in factory test mode, but unable to find
// the factory test app, so just sit around displaying the
// error message and don't try to start anything.
return false;
}
//给Intent设置Category
Intent intent = getHomeIntent();
//获取ActivityInfo
ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
if(aInfo != null){
intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
// Don't do this if the home app is currently being instrumented.
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);
//启动launcher
mStackSupervisor.startHomeActivity(intent, aInfo, reason);
}
}
return true;
}
这个函数主要完成的工作:函数首先创建一个CATEGORY_HOME类型的Intent,然后通过 Intent.resolveActivityInfo函数向 PackageManagerService查询Category类型为HOME的Activity。
1、getHomeIntent()给Intent设置Category:CATEGORY_HOME
mTopAction = Intent.MAIN
Intent getHomeIntent(){
Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
intent.setComponent(mTopComponent);
if(mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL){
//设置category
intent.addCategory(Intent.CATEGORY_HOME);
}
return intent;
}
2、resolveActivityInfo()获取ActivityInfo信息
private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId){
ActivityInfo ai = null;
ComponentName comp = intent.getComponent();
try{
if(comp != null){
//Factory test
ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
}else{
ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
intent,
intent.resolveTypeIfNeed(mContext.getContentResolver()
flags,userId);
if(info != null){
ai = info.activityInfo;
}
}
}catch(RemoteException e){
}
return ai;
}
2.1、AppGlobal.get