Activity启动流程-AMS

  1. Activity的启动的基本介绍

因为关于AMS内部类的关系,例如stack、task,已有了相关的文档做介绍,本文不再赘述细说,基于相关文档以及代码的学习,本文主要集中篇幅集中于第三章,描述在Activity进程的启动流程中,启动应用进程以及应用进程中启动Activity的流程,也就是Activity启动的后半段流程。第二章关于Activity启动的前期准备主要涉及AMS的重点地方也会做详细描述。

    1. 启动模式

Android定义了4种Activity的启动模式,分别为Standard、SingleTop、SingleTask和SingleInstance

Standard模式

我们平时创建的Activity都是默认采用这种模式。

这种模式的特点是你创建启动一个Activity,就会创造一个实例,并加入到当前的任务栈,退出的时候就会销毁它。

在一个task可以存在多个关于该Activity的对象

SingleTop模式

这种模式启动新的Activity的时候,先判断是否有相同Activity的实例存在于栈顶,如果有直接复用,没有创建新的实例。

SingleTask模式

在该种模式下,只要Activity在一个栈中存在,那么多次启动此Activity都不会重新创建实例。

例如启动一个singleTask模式的Activity a,系统先查找是否已经存在a的task。

如果不存在task,就重新创建一个task,然后创建a的实例后,把a放到task中。

如果存在a所需的task,那么系统将判断该task是否有实例a。

如果有实例a,那么系统就将a调到task顶并调用其onNewIntent方法(会清空a之上的Activity)。

如果没有实例a,那么系统就创建实例a并task中。

SingleInstance模式

SingleTask模式加强模式,Activity只能单独地放在一个task中。

    1. 启动方法
      1. am命令启动

启动命令:

am start -W -n 包名(package)/包名.activity名称

例子:am start -W -n com.example.android365/com.example.android365.MainActivity

-W是一个可选项,表示等待目标activity启动后,am才返回结果;

-n ,表示后接COMPONENT。

am脚本的文件路径是frameworks/base/cms/am

调用am命令同样最终会调用到Am.java(frameworks/base/cmds/am/src/com/android/commands/am)的main函数。

此处只是做简单介绍am命令,最后它会调用AMS的startActivityAndWait函数启动Activity。

      1. launcher启动

点击应用图标,launcher会调用Activity.java的startActivity

==》Activity.startActivityForResult

         ==》mInstrumentation.execStartActivity

          ==>ActivityManagerNative.getDefault().startActivity

                   ==>AMS.startActivity

                    ==》ActivityManagerService.startActivityAsUser

                           ==>ActivityStater.startActivityMayWait

  1. Activity启动的前期准备
    1. ActivityStater.startActivityMayWait

首先这个方法传入的参数非常多,这里对一些参数做简单介绍:

IApplicationThread caller = ApplicationThreadProxy,IApplicationThread是应用进程和AMS交互的通道,用于跟调用者进程和AMS进行通信的binder代理类.

String callingPackage = ContextImpl.getBasePackageName(),获取调用者Activity所在包名

Intent intent: 这是启动Activity时传递过来的参数;

String resolvedType = intent.resolveTypeIfNeeded //启动使用的resolvedType

IBinder resultTo = Activity.mToken, 其中Activity是指调用者所在Activity, mToken对象保存自己所处的ActivityRecord信息

String resultWho = Activity.mEmbeddedID, 其中Activity是指调用者所在Activity

int startFlags = 0;启动Activity的对应flag

ProfilerInfo profilerInfo = null;//性能统计有关

Bundle options = null;指定Activity要加入的task

int userId = AMS.handleIncomingUser, 当调用者userId跟当前处于同一个userId,则直接返回该userId;当不相等时则根据调用者userId来决定是否需要将callingUserId转换为mCurrentUserId.

下面我们将这个方法中主要的代码逻辑进行摘录分析:

//先从Intent中读取组件(Activity)名

boolean componentSpecified = intent.getComponent() != null;

//创建新的Intent对象

intent = new Intent(intent);

// mSupervisor的类型为ActivityStackSupervisor, 负责管理Activity和对应Task之间的关系.

这里调用resolveIntent,取出对应的ActivityInfo

ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);

得到option

ActivityOptions options = ActivityOptions.fromBundle(bOptions);

//要是从一个Activity启动其他Activity,该Activity必须依据resume

if (container != null && container.mParentActivity != null &&

          container.mParentActivity.state != RESUMED) {

  // Cannot start a child activity if the parent is not resumed.

  return ActivityManager.START_CANCELED;

}

选择启动stack

final ActivityStack stack;

if (container == null || container.mStack.isOnHomeDisplay()) {

    //am 启动和launch启动,stack为前台stack

  stack = mSupervisor.mFocusedStack;

} else {

    //如果从其他Activity启动,stack为父stack

  stack = container.mStack;

}

//保存启动Activity的ActivityRecord

final ActivityRecord[] outRecord = new ActivityRecord[1];

//继续执行启动流程

int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,

          aInfo, rInfo, voiceSession, voiceInteractor,

          resultTo, resultWho, requestCode, callingPid,

          callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,

          options, ignoreTargetSecurity, componentSpecified, outRecord, container,

          inTask);

//outResult不等于null,表示等待启动结果目标Activity要运行在一个新的应用进程中,因此需要等待应用进程正常启动并处理相关请求

if (outResult != null) {

  ......

  do {

          try {

              //一直等待,直到outResult显示Activity对应的Task成为front task

                   mService.wait();

          } catch (InterruptedException e) {

          }

  } while (outResult.result != START_TASK_TO_FRONT

                   && !outResult.timeout && outResult.who == null);

  ......

  if (res == START_TASK_TO_FRONT) {

        //Activity对应的task拉到前台后,一直要等到该界面被加载

        ActivityRecord r = stack.topRunningActivityLocked();

  ......

    1. ActivityStarter.startActivityLocked

//err 错误标志位,后面会有各种条件判断,如果有错误err会被置为对应代表值。

int err = ActivityManager.START_SUCCESS;

//保存Activity的进程信息

ProcessRecord callerApp = null;

//如果caller调用者补位空,可以通过找到processrecord找到对应的pid和uid,am启动,调用信息为null

if (caller != null) {

        callerApp = mService.getRecordForAppLocked(caller);

        if (callerApp != null) {

                 callingPid = callerApp.pid;

                 callingUid = callerApp.info.uid;

        } else {

                 err = ActivityManager.START_PERMISSION_DENIED;

        }

}

//父Activity

ActivityRecord sourceRecord = null;

//接受启动结果的Activity,在一般情况下,sourceRecord和resultRecord应指向同一个Activity

ActivityRecord resultRecord = null;

//从Intent获取flag

final int launchFlags = intent.getFlags();

//接受启动结果的stack

final ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;

//一下两项分别是权限检查,根据IntentFirewall校验Intent是否满足要求,然后设置abort值,abort值为true

//进行通知(ActivityOptions.abort(options);)

boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,

                 requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity, callerApp,

                 resultRecord, resultStack, options);

boolean firewallCheck = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,

                 callingPid, resolvedType, aInfo.applicationInfo);

abort |= firewallCheck;

//创建启动Activity的ActivityRecord

ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,

                 intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,

                 requestCode, componentSpecified, voiceSession != null, mSupervisor, container,

                 options, sourceRecord);

//启动处于pending状态的Activity

doPendingActivityLaunchesLocked(false);

 

try {

        //Window 延迟绘制

        mService.mWindowManager.deferSurfaceLayout();

        //继续startActivity流程

        err = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags,

                         true, options, inTask);

        Slog.d(TAG,"startActivityUncheckedLocked result : " + err);

} finally {

        mService.mWindowManager.continueSurfaceLayout();

}

//通知ActivityStarter, Activity对应的Task被移动到前台

postStartActivityUncheckedProcessing(r, err, stack.mStackId, mSourceRecord, mTargetStack);

    1. ActivityStater.startActivityUnchecked()

// 下面这段代码的功能就是判断,当待启动的Activity已经位于前台栈顶时,是否需要重新启动一个实例

  final ActivityStack topStack = mSupervisor.mFocusedStack; // 顶栈

  final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);//顶栈上正在运行的Activity

final boolean dontStart = top != null && mStartActivity.resultTo == null && top.realActivity.equals(mStartActivity.realActivity) && top.userId == mStartActivity.userId && top.app != null && top.app.thread != null //可以粗略的认为,上面的判断是为了确保待启动的Activity与当前的前台Activity一致 //下面的判断,决定了是否需要重新创建一个实例 && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0 || mLaunchSingleTop || mLaunchSingleTask);

if (dontStart) { ................

if (mDoResume) { //resume top activity mSupervisor.resumeFocusedStackTopActivityLocked(); } ............... //调用onNewIntent函数 top.deliverNewIntentLocked( mCallingUid, mStartActivity.intent, mStartActivity.launchedFromPackage); .............. return START_DELIVERED_TO_TOP;

}

//表示是否创建新的Task boolean newTask = false; //得到Affiliate Task,Activity的归属,也就是Activity应该在哪个Task中,Activity与Task的吸附关系。

这种吸附关系由启动模式和intent flag以及affinity属性共同决定的。

final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null) ? mSourceRecord.task : null;

if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask

  && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {

  newTask = true;

  //如果mReuseTask不为null,那么将mStartActivity的Task设置为mReuseTask

  //否则,重新创建一个Task给mStartActivity使用

  setTaskFromReuseOrCreateNewTask(taskToAffiliate);

  ...................

} else if (mSourceRecord != null) {

  ..................

  //待启动的Activity使用父Activity的Task

  //其中在必要时将父Activity的Task移动到前台

  //若待启动的Activity存在于Task中,但不在Task的顶部,还需要将Activity移动到顶部

  final int result = setTaskFromSourceRecord();

  .................

} else if (mInTask != null) {

  ................

  //对应于以指定Task启动Activity的情况

  final int result = setTaskFromInTask();

  ................

} else {

  // This not being started from an existing activity, and not part of a new task...

  // just put it in the top task, though these days this case should never happen.

  //待启动的Activity使用前台Task或重新创建一个Task (什么条件决定是否创建一个新Task)

  setTaskToCurrentTopOrCreateNewTask();

}

......................

//将待启动的Activity加入到mTargetStack的记录中,同时调用WindowManager准备App切换相关的工作(启动startingWindow)

mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions);

 

if (mDoResume) {

  if (!mLaunchTaskBehind) {

  // TODO(b/26381750): Remove this code after verification that all the decision

  // points above moved targetStack to the front which will also set the focus

  // activity. 然后调用focus方法将activity移到front,调用到window,会set app focus到当前的app

  //依次调用到WMS的setFocusedApp,并同步到input

  //mInputMonitor.setFocusedAppLw(newFocus); ==>mService.mInputManager.setFocusedApplication(handle);

  //updateFocusedWindowLocked 然后焦点应用置null

  mService.setFocusedActivityLocked(mStartActivity, "startedActivity");

  }

  final ActivityRecord topTaskActivity = mStartActivity.task.topRunningActivityLocked();

 

  //待启动的Activity不可见的情况

  if (!mTargetStack.isFocusable()

  || (topTaskActivity != null && topTaskActivity.mTaskOverlay

  && mStartActivity != topTaskActivity)) {

  ...........................,.......

  } else {

  //最终调用resumeFocusedStackTopActivityLocked

  mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,

  mOptions);

 

  }

} else {

  .............

}

    1. ActivityStack.resumeTopActivityInnerLocked

首先上文调用到ActivityStackSupervisor. resumeFocusedStackTopActivityLocked

这里面的处理逻辑比较简单

//待启动Activity对应的Task为前台Task时,调用该Task对应ActivityStack的resumeTopActivityUncheckedLocked函,否则只是调用当前前台栈的resumeTopActivityUncheckedLocked,而resumeTopActivityUncheckedLocked的主要实现函数就是resumeTopActivityInnerLocked。

下面我们主要分析ActivityStack. resumeTopActivityUncheckedLocked()

//从当前ActivityStack的记录中,找到第一个待启动的ActivityRecord

final ActivityRecord next = topRunningActivityLocked();

if (next == null) {

        ......

        //当前的ActivityStack没有等待启动的Activity时,将启动Home

        return isOnHomeDisplay() &&

                mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, reason);

    }

    ......

    // 将待启动的Activity从下面几个队列中移除

    mStackSupervisor.mStoppingActivities.remove(next);

    mStackSupervisor.mGoingToSleepActivities.remove(next);

    next.sleeping = false;

    mStackSupervisor.mWaitingVisibleActivities.remove(next);

 

    //如果系统当前正在中断一个Activity,需要先等待那个Activity paus完毕

    if (!mStackSupervisor.allPausedActivitiesComplete()) {

        ......

        return false;

    }

 

    mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);

 

    // We need to start pausing the current activity so the top one can be resumed...

    final boolean dontWaitForPause = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0;

 

    //mResumedActivity指向上一次启动的Activity,也就是当前界面显示的Activity

    if (mResumedActivity != null) {

        ......

        //如果当前界面显示了一个Activity,那么在启动新的Activity之前,必须中断当前的Activity,现将这个Activity paus

                 //之后系统会重新调用resumeTopActivityInnerLocked函数,找到下一个要启动的Activity。我会在这节末尾列出调用的相关逻辑情况

        pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);

    }

 

    if (pausing) {

        ......

        if (next.app != null && next.app.thread != null) {

            //在中断当前界面的Activity时,调用待启动Activity所在进程的优先级,保证其不被kill

            mService.updateLruProcessLocked(next.app, true, null);

        }

        ......

        return true;

    } else if (mResumedActivity == next && next.state == ActivityState.RESUMED &&

            mStackSupervisor.allResumedActivitiesComplete()){

        //特殊情况,上面的代码中断后台栈,同时启动模式指定了FLAG_RESUME_WHILE_PAUSING

        mWindowManager.executeAppTransition();

        mNoAnimActivities.clear();

        ......

        return true;

    }

 

    //若之前存在未正常结束的Activity,那么要优先结束掉这些Activity

    if (mService.isSleepingLocked() && mLastNoHistoryActivity != null &&

            !mLastNoHistoryActivity.finishing) {

        .......

                 vityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED,

                null, "resume-no-history", false);

        mLastNoHistoryActivity = null;

        .......

    }

    .......

    try {

        //通过PKMS,修改待启动Activity对应Package的stop状态

        AppGlobals.getPackageManager().setPackageStoppedState(

                next.packageName, false, next.userId); /* TODO: Verify if correct userid */

    } catch (RemoteException e1) {

    } catch (IllegalArgumentException e) {

        .......

    }

 

    //处理动画相关的选项

    Bundle resumeAnimOptions = null;

    if (anim) {

        ActivityOptions opts = next.getOptionsForTargetActivityLocked();

        if (opts != null) {

            resumeAnimOptions = opts.toBundle();

        }

        next.applyOptionsLocked();

    } else {

        next.clearOptionsLocked();

    }

    .......

    if (next.app != null && next.app.thread != null) {

        //如果待启动的Activity已有对应的进程存在,则只需要重启Activity

                 mStackSupervisor.scheduleResumeTopActivities();

        .......

    } else {

        启动应用进程

        mStackSupervisor.startSpecificActivityLocked(next, true, true);

        .......

    }

    ......

    return true;

}

Activity pause的调用情况:

IApplicationThread.schedulePauseActivity()

        ==>ActivityThread.schedulePauseActivity()

        ==>ActivityThread.sendMessage()

        ==>ActivityThread.H.sendMessage()

        ==>ActivityThread.H.handleMessage()

        ==>ActivityThread.handlePauseActivity()

        ==>ActivityThread.performPauseActivity()

                 ==>Instrumentation.callActivityOnPause()

                 ==>Activity.performPause()

                 ==>Activity.onPause()

==>ActivityManagerNative.getDefault().activityPaused()

==>ActivityManagerService.activityPaused()

        ==>ActivityStack.activityPausedLocked()

        ==>ActivityStack.completePauseLocked()

       ==> ActivityStack. resumeFocusedStackTopActivityLocked

  1. 启动应用进程和Activity
    1. 启动应用进程
      1. mStackSupervisor.startSpecificActivityLocked

//从AMS中查询是否已经存在满足要求的进程

    ProcessRecord app = mService.getProcessRecordLocked(r.processName,

            r.info.applicationInfo.uid, true);

//如果对应进程已经存在,并向AMS注册过

    if (app != null && app.thread != null)

//通知进程启动目标Activity

    realStartActivityLocked(r, app, andResume, checkConfig);

//如果进程不存在,利用AMS的startProcessLocked函数,创建一个新的进程

    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,

            "activity", r.intent.getComponent(), false, false, true);

      1. ActivityManagerService.startProcessLocked

//指定反射的className

if (entryPoint == null) entryPoint = "android.app.ActivityThread";

//Process.java的start函数,将通过socket发送消息给zygote

//zygote将派生出一个子进程,子进程将通过反射调用ActivityThread的main函数

//注意此时传递给zygote的参数并没有包含任何与Activity相关的信息

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);

synchronized (mPidsSelfLocked) {

    //AMS以键值对的形式,保存pid和processRecord

    this.mPidsSelfLocked.put(startResult.pid, app);

    if (isActivityProcess) {

        Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);

        msg.obj = app;

        //发送一个延迟消息

        //在消息被处理前,若新创建的进程没有和AMS交互,那么该进程启动失败

        //正常延迟时间为10s

        //若通过wrapper(例如valgrind)加载,应用程序将在wrapper的运行环境中工作,耗时较长,延迟时间在N中定义为1200s

        mHandler.sendMessageDelayed(msg, startResult.usingWrapper

                ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);

        }

}

      1. Process.start()

public static final ProcessStartResult(){

startViaZygote(processClass, niceName, uid, gid, gids,

                    debugFlags, mountExternal, targetSdkVersion, seInfo,

                    abi, instructionSet, appDataDir, zygoteArgs);

}

 

private static ProcessStartResult startViaZygote{

  在string 数组argsForZygote中加入相关的启动参数。

  zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);

}

 

private static ProcessStartResult zygoteSendArgsAndGetResult(

    //通过socket发送消息给zygote,zygote将派生出一个子进程,子进程将通过反射调用ActivityThread的main函数

  final BufferedWriter writer = zygoteState.writer;

    final DataInputStream inputStream = zygoteState.inputStream;

  writer.write(Integer.toString(args.size()));

    writer.newLine();

    for (int i = 0; i < sz; i++) {

        String arg = args.get(i);

          writer.write(arg);

        writer.newLine();

    }

    writer.flush();

    ProcessStartResult result = new ProcessStartResult();

    result.pid = inputStream.readInt();

    result.usingWrapper = inputStream.readBoolean();

}

    1. 应用进程初始化
      1. ActivityThread.mian()

ActivityThread的main函数最主要工作是:

1、创建出一个Looper,并将主线程加入到消息循环中。

2、创建出ActivityThread,并调用其attach函数。

 

通过zygote启动进程时,传入的className为android.app.ActivityThread。

因此,当zygote通过反射调用进程的main函数时,ActivityThread的main函数将被启动:

/准备主线程的Looper

Looper.prepareMainLooper();

//创建当前进程的ActivityThread

ActivityThread thread = new ActivityThread();

//调用attach函数

thread.attach(false);

 

if (sMainThreadHandler == null) {

  //保存进程对应的主线程Handler

    sMainThreadHandler = thread.getHandler();

}

.........

//进入主线程的消息循环

Looper.loop();

 

      1. ActivityThread.attach(false)

private void attach(boolean system) {

    sCurrentActivityThread = this;

    mSystemThread = system;

    if (!system) {

        ViewRootImpl.addFirstDrawHandler(new Runnable() {

            @Override

            public void run() {

                //JIT是一种提高程序运行效率的方法。通常,程序有两种运行方式:静态编译与动态解释。静态编译的程序在执行前全部被翻译为机器码,而解释执行的则是一句一句边运行边翻译。

                //这里开启JIT,应该是为了提高android绘制的速度

                ensureJitEnabled();

            }

        });

 

        //设置在DDMS中看到的进程名为"<pre-initialized>"

        android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", UserHandle.myUserId());

 

        //设置RuntimeInit的mApplicationObject参数

        RuntimeInit.setApplicationObject(mAppThread.asBinder());

 

        final IActivityManager mgr = ActivityManagerNative.getDefault();

        try {

            //与AMS通信,调用其attachApplication接口

            mgr.attachApplication(mAppThread);

        } catch (RemoteException ex) {

            throw ex.rethrowFromSystemServer();

        }

 

        // 监控GC操作; 当进程内的一些Activity发生变化,同时内存占用量较大时

        // 通知AMS释放一些Activity

        BinderInternal.addGcWatcher(new Runnable() {

            public void run() {

                if (!mSomeActivitiesChanged) {

                    return;

                }

 

                Runtime runtime = Runtime.getRuntime();

                long dalvikMax = runtime.maxMemory();

                long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();

                //判断内存占用量是否过大

                if (dalvikUsed > ((3*dalvikMax)/4)) {

                    ...........

                    mSomeActivitiesChanged = false;

                    try {

                        //通知AMS释放一些Activity,以缓解内存紧张

                        mgr.releaseSomeActivities(mAppThread);

                    } catch (RemoteException e) {

                        throw e.rethrowFromSystemServer();

                    }

                }

            }

        });

    } else {

        .............

    }

    ........

}

 

      1. ActivityManagerService.attachApplication()

   public final void attachApplication(IApplicationThread thread) {

        synchronized (this) {

                   ......

            attachApplicationLocked(thread, callingPid);

        }

  }

ActivityManagerService.attachApplicationLocked()

  ProcessRecord app;

  if (pid != MY_PID && pid >= 0) {

          synchronized (mPidsSelfLocked) {

              //AMS 启动的进程会保存processRecord,这里根据pid获取app

                   app = mPidsSelfLocked.get(pid);

          }

  } else {

 

    if (app == null) {

        如果app为null,说明这个进程不是ams启动的,需要kill掉该进程

          EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);

          if (pid > 0 && pid != MY_PID) {

              pid大于0且不是系统进程,则直接kill掉

                   Process.killProcessQuiet(pid);

          } else {

                   try {

                       pid<0说明fork失败,做一些上层清理即可,进程退出

                           thread.scheduleExit();

                   } catch (Exception e) {

                   }

          }

          return false;

  }

  //判断pid对应processRecord的IApplicationThread是否为null,AMS创建ProcessRecord后,在attach之前,正常情况下IApplicationThread应该为null

    // 特殊情况下:如果旧应用进程被杀死,底层对应的pid被释放,在通知到达AMS之前(AMS在下面的代码里注册了进程存活接收对象),用户又启动了一个新的进程,新进程刚好分配到旧进程的pid时此处得到的processRecord可能就是旧进程的,于是app.thread可能不为null,因此需要作判断和处理

  if (app.thread != null) {

          handleAppDiedLocked(app, true, true);

  }

 

  final String processName = app.processName;

  try {

      //APP存活检测类(AppDeathRecipient),new一个该对象,

          AppDeathRecipient adr = new AppDeathRecipient(

                           app, pid, thread);

          //注册该对象到应用进程的ApplicationThread中,当应用进程退出时,该对象的binderDied将被调用,这样AMS就能做相应的处理。

          thread.asBinder().linkToDeath(adr, 0);

          app.deathRecipient = adr;

  } catch (RemoteException e) {

          app.resetPackageList(mProcessStats);

          startProcessLocked(app, "link fail", processName);

          return false;

  }

  设置app的一些变量,例如调度优先级和oom_adj相关的成员

  app.makeActive(thread, mProcessStats);

  app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;

  app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;

  app.forcingToForeground = null;

  updateProcessForegroundLocked(app, false, false);

  app.hasShownUi = false;

  app.debugging = false;

  app.cached = false;

  app.killedByAm = false;

  //对应我们eventLog am_proc_bound

  EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);

    //AMS创建一个应用进程后,会设置一个超时时间。 如果超过这个时间,应用进程还没有和AMS交互,AMS就认为该进程创建失败,调用到此处说明启动成功,移除该消息

    mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);

 

mStackSupervisor.attachApplicationLocked(app)

这个方法主要是寻找focus stack的top Activity,然后去启动它。在应用进程没有创建的时候,没有办法将要启动的Activity传给应用进程。

所以我们前期会通过一系列的处理将Activity的task移到focus stack的顶部,Activity移到task的顶部。这样应用进程启动后,和AMS进行交换

就可以知道它要启动的Activity的具体情况

==>realStartActivityLocked(hr, app, true, true)//具体的执行启动工作

{

  if (andResume) {

        //为显示做准备,先冻结屏幕,然后做动画切换和图像显示准备

        r.startFreezingScreenLocked(app, 0);

        mWindowManager.setAppVisibility(r.appToken, true);

        ..........

    }

  ......

  if (checkConfig) {

      //更新绘制相关的配置

          Configuration config = mWindowManager.updateOrientationFromAppTokens(

                           mService.mConfiguration,

                           r.mayFreezeScreenLocked(app) ? r.appToken : null);

          mService.updateConfigurationLocked(config, r, false);

  }

  //如果这个新启动的Activity没有保存在activities数组,这里保存一下

  int idx = app.activities.indexOf(r);

    if (idx < 0) {

        app.activities.add(r);

    }

  ......

  //更新优先级

  mService.updateOomAdjLocked();

  ......

   ==>//通知应用进程启动Activity

        app.thread.scheduleLaunchActivity(............);

  ......

    if (andResume) {

        // Activity进入resumeState后,更新相应的状态

        stack.minimalResumeActivityLocked(r);

    }

}

    1. 启动Activity
      1. scheduleLaunchActivity

public final void scheduleLaunchActivity(......) {

    //更新进程状态

  updateProcessState(procState, false);

    创建ActivityClientRecord然后把AMS传进的信息进行保存

  ActivityClientRecord r = new ActivityClientRecord();

 

  r.token = token;

  r.ident = ident;

  r.intent = intent;

  r.referrer = referrer;

  r.voiceInteractor = voiceInteractor;

  r.activityInfo = info;

  r.compatInfo = compatInfo;

  r.state = state;

  r.persistentState = persistentState;

  r.pendingResults = pendingResults;

  r.pendingIntents = pendingNewIntents;

  r.startsNotResumed = notResumed;

  r.isForward = isForward;

  r.profilerInfo = profilerInfo;

  r.overrideConfig = overrideConfig;

  //更新配置

  updatePendingConfiguration(curConfig);

    //发送消息交给ActivityThread处理LAUNCH_ACTIVITY,最后是handleLaunchActivity处理的

  sendMessage(H.LAUNCH_ACTIVITY, r);

}

 

      1. handleLaunchActivity

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {

  //如果Activity从前台移动到后台,则有可能准备进行Gc操作,现在Activity重新启动,就需要取消Gc操作了,对于新建Activity而言,此处无实际动作。

  unscheduleGcIdler();

  mSomeActivitiesChanged = true;

  //Activity进行性能统计

  if (r.profilerInfo != null) {

          mProfiler.setProfiler(r.profilerInfo);

          mProfiler.startProfiling();

  }

 

  // 保证Activity以最新的配置启动,即保证Activity符合最新语言、主题、分辨率等的要求

  handleConfigurationChanged(null, null);

 

  // 初始化WindowManagerGlobal

  WindowManagerGlobal.initialize();

  //执行performLaunchActivity创建Activity,这里面会执行Activity的onCreate,onstart

  Activity a = performLaunchActivity(r, customIntent);

 

  if (a != null) {

          r.createdConfig = new Configuration(mConfiguration);

          reportSizeConfigurations(r);

          Bundle oldState = r.state;

          //调用执行Activity onResume

          handleResumeActivity(r.token, false, r.isForward,

                           !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);

 

          if (!r.activity.mFinished && r.startsNotResumed) {

                   // 处理可见但非前台的Activity,这种Activity在启动后将进入到pause状态

                   performPauseActivityIfNeeded(r, reason);

                   ......

          }

  } else {

          //如果启动错误,则通知AMS stop

          try {

                   ActivityManagerNative.getDefault()

                           .finishActivity(r.token, Activity.RESULT_CANCELED, null,

                                           Activity.DONT_FINISH_TASK_WITH_ACTIVITY);

          } catch (RemoteException ex) {

                   throw ex.rethrowFromSystemServer();

          }

  }

}

handleLaunchActivity的工作主要包括:

1、调用performLaunchActivity创建出Activity;

2、调用handleResumeActivity,完成调用目标Activity的onResume接口等工作;

3、对于可见但非前台的Activity,还需要调用performPauseActivityIfNeeded函数,调用Activity的onPause接口

 

      1. performLaunchActivity():

//通过反射创建Activity:

java.lang.ClassLoader cl = r.packageInfo.getClassLoader();

activity = mInstrumentation.newActivity(

          cl, component.getClassName(), r.intent);

         

Window window = null;

window = r.mPendingRemoveWindow;

//设置Activity的主要变量,其中实例化phonewindow和window的一些设置操作 ,创建mMainThread、mUiThread等,mMainThread的类型为ActivityThread;mUiThread的类型为Thread,二者实际的工作线程是同一个             

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);

//设置主题

int theme = r.activityInfo.getThemeResource();

if (theme != 0) {

  activity.setTheme(theme);

}

//调用onCreate

if (r.isPersistable()) {

  mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);

} else {

  mInstrumentation.callActivityOnCreate(activity, r.state);

}                        

//调用onstart

if (!r.activity.mFinished) {

  activity.performStart();

  r.stopped = false;

}                                 

//调用Activity onRestoreInstanceState函数

if (r.isPersistable()) {

  if (r.state != null || r.persistentState != null) {

          mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,

                           r.persistentState);

  }

} else if (r.state != null) {

  mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);

}

//调用Activity的onPostCreate接口

if (r.isPersistable()) {

  mInstrumentation.callActivityOnPostCreate(activity, r.state,

                   r.persistentState);

} else {

  mInstrumentation.callActivityOnPostCreate(activity, r.state);

}

//保存Activity

mActivities.put(r.token, r);                                        

      1. handleResumeActivity()

该方法主要调用Activity的onresume

//调用Activity的resume方法

r = performResumeActivity(token, clearHide, reason);

然后做些绘制的操作,具体参考Activity启动涉及WMS的分析

if (!r.onlyLocalRequest) {

  //r为刚刚完成onResume的新Activity,mNewActivities保存已经之前onResume的Activity

  r.nextIdle = mNewActivities;

  //然后将新建的Activity赋值给mNewActivities

  mNewActivities = r;

  ...........

  //向ActivityThread的MessageQueue中增加一个IdleHandler

  Looper.myQueue().addIdleHandler(new Idler());

}

最后通知AMS该Activity执行完了onresume

ActivityManagerNative.getDefault().activityResumed(token);                              

 

向ActivityThread的MessageQueue中增加一个IdleHandler后,会执行下面的代码

private class Idler implements MessageQueue.IdleHandler {

        @Override

        public final boolean queueIdle() {}

 

在queueIdle函数里面会执行到am.activityIdle(a.token, a.createdConfig, stopProfiling);调用AMS的activityIdle函数

我们此处关注下Activity启动的最后一步,AMS.activityIdle

      1. AMS.activityIdle

==》ActivityRecord r =   mStackSupervisor.activityIdleInternalLocked(token, false, config);

这个方法主要处理一些扫尾工作,之前启动Activity,我们将之前的Activity进行pause处理,此处则让他们执行onstop,ondestory操作。

//finish 等待结束的Activity

if ((NF = mFinishingActivities.size()) > 0) {

  finishes = new ArrayList<>(mFinishingActivities);

  mFinishingActivities.clear();

}

//stop 那些因为新启动Activity而处于等待状态的Activity

for (int i = 0; i < NS; i++) {

  r = stops.get(i);

  final ActivityStack stack = r.task.stack;

  if (stack != null) {

          if (r.finishing) {

               //如果被暂停的Activity已经处于了finishing状态,他们将会执行Destroy操作

                   stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);

          } else {

              //如果没有处于finishing状态,执行onstop

                   stack.stopActivityLocked(r);

          }

  }

}       

然后同样finish这些Activity

for (int i = 0; i < NF; i++) {

  r = finishes.get(i);

  final ActivityStack stack = r.task.stack;

  if (stack != null) {

          activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle");

  }

}

//如果等待结束的Activity被处理,保证前台栈顶Activity处于Resumed状态

if (activityRemoved) {

  resumeFocusedStackTopActivityLocked();

}                        

本章总结如下:

1、启动进程,创建自己的ActivityThread和ApplicationThread。

2、进程与AMS通信,其实就是完成一个注册过程(将ApplicationThread作为Binder通信接口交给AMS保存)

3、AMS通知进程创建自己的Android运行环境,加入到Android体系。

4、AMS通知进程可以启动进程中的Activity。

5、Activity启动完成后,通知AMS更新相关的状态,并进行一些结尾工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值