activity启动流程(8.0源码)

不管是相同应用还是不同应用启动两个activity(可以把系统也看成是一个应用),都是调用startActivity开始启动。

             //该应用的包名
            String pkg = info.activityInfo.packageName;
            //应用的主activity类
            String cls = info.activityInfo.name;

            ComponentName componet = new ComponentName(pkg, cls);

            Intent i = new Intent();
            i.setComponent(componet);
            startActivity(i);

这是启动另外一个APP的方法。

流程图:
activity启动流程.jpg

Instrumentation类

execStartActivity

public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
    ......
 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;
    }

ActivityManager只是一个单独的类

public class ActivityManager {......}

ActivityManager的getService方法

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

IActivityManager 就是一个aidl文件对象,而ActivityManagerService也是继承了IActivityManager.Stub(API 26已经变了不再是继承ActivityManagerNative)

public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {......}

通过AIDL返回ActivityManagerService的IActivityManager这个代理 对象,通过这个代理调用ActivityManagerService中的方法。

ActivityManagerService类

public int startActivity(IBinder whoThread, String callingPackage,
                Intent intent, String resolvedType, Bundle bOptions) {
..........
return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
                    resolvedType, null, null, null, null, 0, 0, null, null,
                    null, bOptions, false, callingUser, tr, "AppTaskImpl");
}

ActivityStarter类

startActivityMayWait 获得启动activity的一些系统参数如uid,进程的pid等等,跟传入的Intent重新组合一个newIntent传入启动流程中。

final ActivityRecord[] outRecord = new ActivityRecord[1]

startActivity(294行)

初始化ActivityRecord 对象

  ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
                resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
                mSupervisor, options, sourceRecord);

startActivityUnchecked

startActivityUnchecked方法太复杂了,涉及activity的启动模式Intent的flag等诸多要素,如其中一个方法computeLaunchingTaskFlags()

if (mLaunchSingleInstance || mLaunchSingleTask) {......}

是不是有点眼熟,SingleInstance、SingleTask都是activity的启动模式之一。
最后会调用

if (mDoResume) {
........
}else {
 if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
         mTargetStack.moveToFront("startActivityUnchecked");
 }
         mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                        mOptions);
}

resumeFocusedStackTopActivityLocked

//如果待启动activity的ActivityStack是当前的前台Stack
 if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }

        final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
//否则调用当前前台ActivityStack的resumeTopActivityUncheckedLocked
        if (r == null || r.state != RESUMED) {
            mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
        } else if (r.state == RESUMED) {
            // Kick off any lingering app transitions form the MoveTaskToFront operation.
            mFocusedStack.executeAppTransition(targetOptions);
        }

ActivityStack类

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
......
boolean result = false;
        try {
            // Protect against recursion.
            mStackSupervisor.inResumeTopActivity = true;
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
......
    return result;
    }

resumeTopActivityInnerLocked

这个方法非常复杂

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
......
// Find the next top-most activity to resume in this stack that is not finishing and is
        // focusable. If it is not focusable, we will fall into the case below to resume the
        // top activity in the next focusable task.
        final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
......
if (next.app != null && next.app.thread != null) {
......
//如果activity启动过了就ResumeActivity
  next.app.pendingUiClean = true;
                    next.app.forceProcessStateUpTo(mService.mTopProcessState);
                    next.clearOptionsLocked();
                    next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
                            mService.isNextTransitionForward(), resumeAnimOptions);
......
}else{
......
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}

ActivityStackSupervisor类

startSpecificActivityLocked

 void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);

        r.getStack().setLaunchTime(r);
//如果进程已经存在,也就是APP启动过
if (app != null && app.thread != null) {
            try {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                        || !"android".equals(r.info.packageName)) {
                    // Don't add this if it is a platform component that is marked
                    // to run in multiple processes, because this is actually
                    // part of the framework so doesn't make sense to track as a
                    // separate apk in the process.
                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                            mService.mProcessStats);
                }
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

            // If a dead object exception was thrown -- fall through to
            // restart the application.
        }
//否则使用zygote创建一个进程
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }

realStartActivityLocked

   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是IApplicationThread对象,而ActivityThread的内部类ApplicationThread继承了IApplicationThread.Stub,app是当前ProcessRecord对象,也就是进程,每个进程都绑定一个ApplicationThread

private class ApplicationThread extends IApplicationThread.Stub {
......
RuntimeInit.setApplicationObject(mAppThread.asBinder());
......
}

所以通过Binder机制scheduleLaunchActivity调用的其实是ApplicationThread 的方法。

ActivityThread

内部类ApplicationThread的scheduleLaunchActivity

使用Handler机制发送一个LAUNCH_ACTIVITY的消息

public final void scheduleLaunchActivity(......){
.......
sendMessage(H.LAUNCH_ACTIVITY, r);
}
public void handleMessage(Message msg) {
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;
......
}

handleLaunchActivity

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
......
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
 handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
......
  }else{
......
  }
}

1、先来看一下performLaunchActivity

 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
......
//创建当前Activity的Context的实现类ContextImpl
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
//类加载器初始化一个activity 
            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);
            }
        } catch (Exception e) {
......
    }
 try {
    Application app = r.packageInfo.makeApplication(false,   mInstrumentation);
if (activity != null) {
......
 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, r.configCallback);
......
 if (r.isPersistable()) {
     mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
    } else {
      mInstrumentation.callActivityOnCreate(activity, r.state);
   }

  }catch (Exception e) {
......
  }
}
 public Activity newActivity(ClassLoader cl, String className,
            Intent intent)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        return (Activity)cl.loadClass(className).newInstance();
    }

makeApplication方法创建应用的Application对象,并调用Application的onCreate方法

public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
......
//如果自定义了Application就是自定义的,否则默认一个
 String appClass = mApplicationInfo.className;
        if (forceDefaultAppClass || (appClass == null)) {
            appClass = "android.app.Application";
        }
java.lang.ClassLoader cl = getClassLoader();
......
//创建Application并调用Application的attach方法
app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
......
//调用Application的onCreate
instrumentation.callApplicationOnCreate(app);
}

callActivityOnCreate方法调用activity的performCreate

   public void callActivityOnCreate(Activity activity, Bundle icicle,
            PersistableBundle persistentState) {
        prePerformCreate(activity);
        activity.performCreate(icicle, persistentState);
        postPerformCreate(activity);
    }
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
......
if (persistentState != null) {
            onCreate(icicle, persistentState);
        } else {
            onCreate(icicle);
        }
......
}
 final void performCreate(Bundle icicle, PersistableBundle persistentState) {
......
if (persistentState != null) {
            onCreate(icicle, persistentState);
        } else {
            onCreate(icicle);
        }
......
}

2、handleResumeActivity

 final void handleResumeActivity(IBinder token,
            boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
......
if (r.window == null && !a.mFinished && willBeVisible) {
                r.window = r.activity.getWindow();
                View decor = r.window.getDecorView();
                decor.setVisibility(View.INVISIBLE);
                ViewManager wm = a.getWindowManager();
                WindowManager.LayoutParams l = r.window.getAttributes();
                a.mDecor = decor;
                l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
                l.softInputMode |= forwardBit;
                if (r.mPreserveWindow) {
                    a.mWindowAdded = true;
                    r.mPreserveWindow = false;
                    ViewRootImpl impl = decor.getViewRootImpl();
                } 
......
  }
......
}

这个是不是很熟悉,在View的绘制流程中的window、DecorView、ViewRootImpl 。

如果app从未被启动

主入口ActivityThread的调用attach方法

public static void main(String[] args) {
......
        ActivityThread thread = new ActivityThread();
        thread.attach(false);
......
}
private void attach(boolean system) {
RuntimeInit.setApplicationObject(mAppThread.asBinder());
            final IActivityManager mgr = ActivityManager.getService();
            try {
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
......
}

又是熟悉的Binder机制,mgr实际是ActivityManagerService的代理对象,并把ApplicationThread传入ActivityManagerService,这样ActivityManagerService就通过ApplicationThread这个桥梁和ActivityThread关联起来了。

 public final void attachApplication(IApplicationThread thread) {
        synchronized (this) {
            //获得当前进程的id
            int callingPid = Binder.getCallingPid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid);
            Binder.restoreCallingIdentity(origId);
        }
    }
private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {
.......
//绑定Application
  if (app.instr != null) {
                thread.bindApplication(processName, appInfo, providers,
                        app.instr.mClass,
                        profilerInfo, app.instr.mArguments,
                        app.instr.mWatcher,
                        app.instr.mUiAutomationConnection, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.persistent,
                        new Configuration(getGlobalConfiguration()), app.compat,
                        getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial);
            } else {
                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
                        null, null, null, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.persistent,
                        new Configuration(getGlobalConfiguration()), app.compat,
                        getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial);
            }
......
 // See if the top visible activity is waiting to run in this process...
        if (normalMode) {
            try {
                //启动Activity
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }
......
}

bindApplication

thread是IApplicationThread代理对象,ActivityThread通过ApplicationThread和ActivityManagerService通信,所以bindApplication是ApplicationThread的方法

private class ApplicationThread extends IApplicationThread.Stub {
public final void bindApplication(...参数...){
    ......
     sendMessage(H.BIND_APPLICATION, data);
  }
}
public void handleMessage(Message msg) {
  .....
  case BIND_APPLICATION:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                    AppBindData data = (AppBindData)msg.obj;
                    handleBindApplication(data);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
  ......
}
private void handleBindApplication(AppBindData data) {
  ......
 //创建进程对应的Android运行环境ContextImpl
  final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
......
if (ii != null) {
......
//初始化LoadedApk 对象
final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
                    appContext.getClassLoader(), false, true, false);
final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
try {
//初始化Instrumentation
                final ClassLoader cl = instrContext.getClassLoader();
                mInstrumentation = (Instrumentation)
                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();
            } catch (Exception e) {
      ......
    }
  }else {
        //或者在这初始化Instrumentation
            mInstrumentation = new Instrumentation();
        }
......
//初始化Application
app = data.info.makeApplication(data.restrictedBackupMode, null);
......
//调用Application的onCreate方法
mInstrumentation.callApplicationOnCreate(app);
......
}

attachApplicationLocked

ActivityStackSupervisor类中的方法attachApplicationLocked

boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
  ......
  if (realStartActivityLocked(activity, app,
                                    top == activity /* andResume */, true /* checkConfig */)) {
                                didSomething = true;
                            }
  ......
}

又是realStartActivityLocked又是一个轮回,调用真的启动Activity的方法。
参考博客链接:https://blog.csdn.net/qian520ao/article/details/78156214

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355

推荐阅读更多精彩内容