Android9.0源码APP启动流程

本文使用到的相关源码路径: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();
    }
  }
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

若邪〃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值