Android Activity的启动过程分析

   1 Activity的常见启动方式

      1.1长按Home键,显示最近运行Task列表,选择启动其中一个Task的当前Activity。

      1.2在一个应用中,按Back键,结束当前Activity,返回上一个Activity。

      1.3在Home桌面点击应用程序的图标启动应用程序。其实质是启动应用程序的主Activity。

      1.4在应用程序中调用startActivity(intent)启动另一个Activity。

      1.5通过adb shell 命令登录手机,执行am start命令启动指定的Activity。

   2 过程分析

      选最常见的启动方式startActivity(intent)来分析。

Intent intent=new Intent(MainActivity.this,TestActivity.class);startActivity(intent);

 #Activity

 public void startActivity(Intent intent) {        this.startActivity(intent, null);    }
 public void startActivity(Intent intent, @Nullable Bundle options) {...startActivityForResult(intent, -1, options);...}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,            @Nullable Bundle options) {... Instrumentation.ActivityResult ar =                mInstrumentation.execStartActivity(                    this, mMainThread.getApplicationThread(), mToken, this,                    intent, requestCode, options);...}

分析:经过startActivity-->startActivityForResult-->execStartActivity,最终会调用Instrumentation的execStartActivity方法。

# Instrumentation

public ActivityResult execStartActivity(           Context who, IBinder contextThread, IBinder token, Activity target,           Intent intent, int requestCode, Bundle options) {...  //获取AMS的代理,启动Activity  发起请求           int result = ActivityManagerNative.getDefault()               .startActivity(whoThread, who.getBasePackageName(), intent,                       intent.resolveTypeIfNeeded(who.getContentResolver()),                       token, target != null ? target.mEmbeddedID : null,                       requestCode, 0, null, options);...}

# ActivityManagerService 

  处理Activity的启动请求

 @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) {        enforceNotIsolatedCaller("startActivity");        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),                userId, false, ALLOW_FULL_ONLY, "startActivity", null);        // TODO: Switch to user app stacks here.        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,                profilerInfo, null, null, bOptions, false, userId, null, null,                "startActivityAsUser");    }

为了减少篇幅,省略一部分

 # ActivityStarter startActivityMayWait() # ActivityStarter startActivityLocked() # ActivityStarter startActivity() # ActivityStarter startActivityUnchecked()  #ActivityStackSupervisor resumeFocusedStackTopActivityLocked() #ActivityStack resumeTopActivityUncheckedLocked() #ActivityStack resumeTopActivityInnerLocked # ActivityStackSupervisor  startSpecificActivityLocked
# ActivityStackSupervisor  realStartActivityLocked

这一步比较关键,涉及到服务端AMS调用客户端ActivityThread.

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,            boolean andResume, boolean checkConfig) throws RemoteException {...  app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,                    System.identityHashCode(r), r.info,                    // TODO: Have this take the merged configuration instead of separate global and                    // override configs.                    mergedConfiguration.getGlobalConfiguration(),                    mergedConfiguration.getOverrideConfiguration(), r.compat,                    r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,                    r.persistentState, results, newIntents, !andResume,                    mService.isNextTransitionForward(), profilerInfo);...}

app.thread就是ApplicationThreadProxy在服务端的代理对象。

# ActivityThread(内部类) # ApplicationThread scheduleLaunchActivity()
 @Override        public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,                int procState, Bundle state, PersistableBundle persistentState,                List pendingResults, List pendingNewIntents,                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {            ...           //给 H handler发送一个消息              sendMessage(H.LAUNCH_ACTIVITY, r);        }
  private class H extends Handler {...public void handleMessage(Message msg) {            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));            switch (msg.what) {                case LAUNCH_ACTIVITY: {                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;                    r.packageInfo = getPackageInfoNoCheck(                            r.activityInfo.applicationInfo, r.compatInfo);                    handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                } break;...}

#ActivityThread

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {        // If we are getting ready to gc after going to the background, well        // we are back active so skip it.... Activity a = performLaunchActivity(r, customIntent);...}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {        // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");...Activity activity = null;        try {            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();            activity = mInstrumentation.newActivity(                    cl, component.getClassName(), r.intent);            StrictMode.incrementExpectedActivityCount(activity.getClass());            r.intent.setExtrasClassLoader(cl);            r.intent.prepareToEnterProcess();            if (r.state != null) {                r.state.setClassLoader(cl);            }        }... try {            Application app = r.packageInfo.makeApplication(false, mInstrumentation);... activity.attach(appContext, this, getInstrumentation(), r.token,                        r.ident, app, r.intent, r.activityInfo, title, r.parent,                        r.embeddedID, r.lastNonConfigurationInstances, config,                        r.referrer, r.voiceInteractor, window);if (r.isPersistable()) {                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);                } else {                    mInstrumentation.callActivityOnCreate(activity, r.state);                }...}

通过Instrumentation来回调Activity的各生命周期方法

#Instrumentation

public void callActivityOnCreate(Activity activity, Bundle icicle) {        prePerformCreate(activity);        activity.performCreate(icicle);        postPerformCreate(activity);    }

#Activity

 final void performCreate(Bundle icicle) {        restoreHasCurrentPermissionRequest(icicle);        onCreate(icicle);        mActivityTransitionState.readState(icicle);        performCreateCommon();    }

至此,一个Activity的启动流程完成。




 

 

 

 

更多相关文章

  1. eclipse adb 启动失败,无法匹配android设备 的解决方案
  2. Android的两种数据存储方式分析(二)
  3. [Android设计模式]Android退出应用程序终极方法
  4. Android(安卓)应用程序之间数据共享—ContentProvider
  5. 从Android项目学习Kotlin(一)
  6. Android(1.5及以上版本) 开机图片/文字/动画分析
  7. (连载)Android(安卓)8.0 : 系统启动流程之Linux内核
  8. 转Android系统架构
  9. Android开发和调试

随机推荐

  1. android service 学习(上) 音乐播放
  2. android 中文 API (41) ―― RatingBar.O
  3. eclipse下开发android应用的几个常用插件
  4. Android(安卓)-- 超全的 File,Bitmap,Drawa
  5. Android学习之反编译工具介绍
  6. android wm9714 ASoC driver porting
  7. Android(安卓)shape中的padding无效
  8. android settings学习笔记(一)
  9. Android学习笔记-Intent(一)
  10. Android(安卓)自定义 HorizontalScrollVi