Android Activity启动过程全解析

首先参考:
【凯子哥带你学Framework】Activity启动过程全解析

关键概念

zygote进程

这里面讲的很详细,先摘抄其中重要的部分出来,方便以后记忆
每一个App其实都是

  1. 一个单独的dalvik虚拟机
  2. 一个单独的进程

Android是基于Linux System的,当你的手机开机的时候,Linux的内核加载完成之后就会启动一个叫“init“的进程。zygote进程是由init进程fork出来的,当系统里面的第一个zygote进程运行之后,在这之后再开启App,就相当于开启一个新的进程。而为了实现资源共用和更快的启动速度,Android系统开启新进程的方式,是通过fork第一个zygote进程实现的.
Android Framework里面两大非常重要的进程之一
1. zygote进程
2. SystemServer也是一个进程,而且是由zygote进程fork出来的,这个主要开启重要的系统服务,比如ActivityManagerService、PackageManagerService、WindowManagerService

AMS

ActivityManagerService,简称AMS,服务端对象,负责系统中所有Activity的生命周期。
ActivityManagerService进行初始化的时机很明确,就是在SystemServer进程开启的时候,就会初始化ActivityManagerService
在创建AMS之前会调用createSystemContext()创建系统上下文的时候,也已经完成了mSystemContext和ActivityThread的创建。然后创建AMS,在然后,会开启系统的Launcher程序,完成系统界面的加载与显示。

如果想打开一个App的话,需要AMS去通知zygote进程,来fork一个新进程,来开启我们的目标App的。除此之外,其实所有的Activity的开启、暂停、关闭都需要AMS来控制,所以我们说,AMS负责系统中所有Activity的生命周期。
我们的App和AMS(SystemServer进程)还有zygote进程分属于三个独立的进程,他们之间如何通信呢?
App与AMS通过Binder机制进行IPC通信,AMS(SystemServer进程)与zygote通过Socket进行IPC通信。

Launcher

当我们点击手机桌面上的图标的时候,App就由Launcher开始启动了。Launcher本质上也是一个应用程序,和我们的App一样。
Launcher中点击图标,Launcher会判断哪个图标对应哪个应用程序,封装intent,然后使用这个intent开启一个App,其实和我们在Activity中直接startActivity()基本一样,都是调用了Activity.startActivityForResult()。

Instrumentation

每个Activity都持有Instrumentation对象的一个引用,但是整个进程只会存在一个Instrumentation对象。当startActivityForResult()调用之后,实际上还是调用了mInstrumentation.execStartActivity()

    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
            ...ignore some code...
      try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess();
            int result = ActivityManagerNative.getDefault()
                .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) {
        }
        return null;
    }

先提一下,当AMS通知ActivityThread启动一个activity的时候,首先会执行handleLaunchActivity方法,这个方法里面会去回调activity的各个生命周期函数。具体handleLaunchActivity方法在什么时候被调用后面分析

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ..........
        Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            Bundle oldState = r.state;
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed);
        }
        ........

performLaunchActivity方法创建activity,内部其实都是调用Instrumentation的相关方法,然后在调用activity的onCreat和onStart等生命周期方法

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {

        Activity activity = null;
        try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            //说明如果一个activity有构造函数,那么这个构造函数是优先于onCreate方法执行的
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
        }

        try {
            //把之前创建的application对象取出来
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);

            if (activity != null) {
                //绑定ContextImpl对象给该Activity
                Context appContext = createBaseContextForActivity(r, activity);
                //做attach,attah里面会赋值mWindow,mApplication,mWindowManager等              
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.voiceInteractor);

                activity.mCalled = false;
                if (r.isPersistable()) {
                    //最终会调用到Activity的onCreate方法
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }

                if (!r.activity.mFinished) {
                    //实际调用mInstrumentation.callActivityOnStart(this);,然后调用Activity的onStart方法
                    activity.performStart();
                    r.stopped = false;
                }
                if (!r.activity.mFinished) {
                    if (r.isPersistable()) {
                        if (r.state != null || r.persistentState != null) {
                            //调用Activity的onRestoreInstanceState方法
                            mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                                    r.persistentState);
                        }
                    } else if (r.state != null) {
                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                    }
                }
                if (!r.activity.mFinished) {
                    activity.mCalled = false;
                    if (r.isPersistable()) {
                        调用Activity的onPostCreate方法
                        mInstrumentation.callActivityOnPostCreate(activity, r.state,
                                r.persistentState);
                    } else {
                        mInstrumentation.callActivityOnPostCreate(activity, r.state);
                    }
                }
            }        
        } 
        return activity;
    }

这里举个例子,执行了mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);怎么就回调了activity的onCreate方法

    //Instrumentation方法
    public void callActivityOnCreate(Activity activity, Bundle icicle) {
        prePerformCreate(activity);
        activity.performCreate(icicle);
        postPerformCreate(activity);
    }
    //Activity方法
    final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        onCreate(icicle, persistentState);
        mActivityTransitionState.readState(icicle);
        performCreateCommon();
    }

performLaunchActivity执行完后执行handleResumeActivity-performResumeActivity方法,有r.activity.performResume();

    final void performResume() {
        ............
        mInstrumentation.callActivityOnResume(this);
        ............
    }

然后就回调了activity的onResume方法

这里稍微总结一下:

  1. 第一步,执行activity有构造函数,那么这个构造函数是优先于onCreate方法执行的
  2. 第二步,performLaunchActivity中把一个ContextImpl对象给该Activity的父类ContextWrapper的mBase属性,这里的分析见《Android Context详解》
  3. 第二步,performLaunchActivity中调用attach方法,赋值mWindow,mApplication,mWindowManager等。mWindow,mWindowManager有啥用?见《Android 窗口添加机制系列1-Activity》
  4. 第二步,performLaunchActivity中然后回调activity的onCreate,onStart,onRestoreInstanceState,onPostCreate方法
  5. 第三步,第二部创建完初始化完acitivity调用handleResumeActivity回调activity的onResume方法,在窗口机制里面,也说过这里会把顶层的DecorView添加到window-WMS中去

Activity启动流程

前面说过startActivity实际上调用的是Instrumentation的execStartActivity方法

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Fragment target,
        Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        if (mActivityMonitors != null) {
            synchronized (mSync) {
                final int N = mActivityMonitors.size();
                for (int i=0; i<N; i++) {
                    final ActivityMonitor am = mActivityMonitors.get(i);
                    if (am.match(who, null, intent)) {
                        am.mHits++;
                        if (am.isBlocking()) {
                            return requestCode >= 0 ? am.getResult() : null;
                        }
                        break;
                    }
                }
            }
        }
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess();
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mWho : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
        }
        return null;
    }

public abstract class ActivityManagerNative extends Binder implements IActivityManager{
 //从类声明上,我们可以看到ActivityManagerNative是Binder的一个子类,而且实现了IActivityManager接口
 static public IActivityManager getDefault() {
        return gDefault.get();
    }

 //通过单例模式获取一个IActivityManager对象,这个对象通过asInterface(b)获得
 private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };
}


//最终返回的还是一个ActivityManagerProxy对象
static public IActivityManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        IActivityManager in =
            (IActivityManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }

     //这里面的Binder类型的obj参数会作为ActivityManagerProxy的成员变量保存为mRemote成员变量,负责进行IPC通信
        return new ActivityManagerProxy(obj);
    }


}

ActivityManagerProxy.startActivity(),在这里面做的事情就是IPC通信,利用Binder对象,调用transact(),把所有需要的参数封装成Parcel对象,向AMS发送数据进行通信。
看这里IBinder b = ServiceManager.getService(“activity”);之前有介绍过获取PhoneInterfaceManager的时候是这样的ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE)); 这个类似,所以其实这里的IBinder拿到的其实就是AMS(ActivityManagerService)

    public static final String ACTIVITY_SERVICE = "activity";
    public void setSystemProcess() {
        try {
            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
    }
    public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
            String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        ........
        data.writeInt(requestCode);
        data.writeInt(startFlags);
        ........
        mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
        ........
        return result;
    }

客户端:ActivityManagerProxy =====>Binder驱动=====> ActivityManagerService:服务器

流程现在进入了AMS,告诉AMS我要启动一个activity了,接下来AMS中的流程就不贴了,也没啥必要,看参考链接的吧。
【凯子哥带你学Framework】Activity启动过程全解析

//省略AMS中的代码流程

ActivityStack的resumeTopActivityInnerLocked方法中

// We need to start pausing the current activity so the top one
        // can be resumed...
        boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
        boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
        if (mResumedActivity != null) {
            pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
            if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Pausing " + mResumedActivity);
        }

说明在启动activity前,栈顶的activity需要先onpause,新的activity才能启动,所以不能在onpause中做耗时的操作,否则会造成新的activity启动的很慢,此时可以把耗时操作放在Onstop中处理
然后AMS通过以下方式来通知ActivityThread
客户端:ApplicationThread <=====Binder驱动<===== ApplicationThreadProxy:服务器

来一张高清无码大图,方便大家记忆:

如果应用进程还没打开,那么首先会开启main线程,当然就是执行ActivityThread的main方法

    public static void main(String[] args) {

        Looper.prepareMainLooper();

        ActivityThread thread = new ActivityThread();
        thread.attach(false);

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        AsyncTask.init();

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
}

这里做了两件事情

  1. 开启主线程的消息循环
  2. 做主线程的attach

attach方法里执行mgr.attachApplication(mAppThread),然后通过Binder调用到AMS里面对应的attachApplication方法
AMS方法attachApplicationLocked

private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {
    ...........
    thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
                    mCoreSettingsObserver.getCoreSettingsLocked());
    ...........
    mStackSupervisor.attachApplicationLocked(app);
    ...........

首先thread.bindApplication中
thread是IApplicationThread,实际上就是ApplicationThread在服务端的代理类ApplicationThreadProxy,然后又通过IPC就会调用到ApplicationThread的对应方法
先调用ApplicationThreadProxy的bindApplication方法,然后通过IBinder调用的是ApplicationThread的bindApplication方法中会sendMessage(),里面有函数的编号H.BIND_APPLICATION,然后这个Messge会被H这个Handler处理

private class H extends Handler {

      ...ignore some code... 

     public static final int BIND_APPLICATION        = 110;

    ...ignore some code... 

     public void handleMessage(Message msg) {
          switch (msg.what) {
        ...ignore some code... 
         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;
        ...ignore some code... 
        }
 }

ApplicationThread是ActivityThread的内部类
上面的代码也充分说明了AMS通过以下方式来通知ActivityThread
客户端:ApplicationThread <=====Binder驱动<===== ApplicationThreadProxy:服务器

看到了吗? 重要执行到了handleBindApplication,这个方法是不是很熟悉?之前在《Android Context详解》这篇文章就说到,创建单例的Application对像就是从这个方法开始滴。

然后执行完thread.bindApplication也就是说此时完成了Application相关的初始化,然后执行mStackSupervisor.attachApplicationLocked(app);然后会调用realStartActivityLocked方法。
realStartActivityLocked方法里有这么一行

app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                    r.compat, r.task.voiceInteractor, app.repProcState, r.icicle, r.persistentState,
                    results, newIntents, !andResume, mService.isNextTransitionForward(),
                    profilerInfo);

跟上面的是不是很像,先调用ApplicationThreadProxy的scheduleLaunchActivity方法,然后通过IBinder调用的是ApplicationThread的scheduleLaunchActivity方法。scheduleLaunchActivity方法中
同上发送一个标识为H.LAUNCH_ACTIVITY的消息

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

最后看到了吗?执行了handleLaunchActivity方法,这个方法很熟悉吧?执行Activity生命周期就是从这个方法开始的,见《Instrumentation》章节

现在整个流程终于清晰了吧?

另一方面,如果是启动同一个应用的activity,那么就不会有bindApplication的流程啦,就不会再重复初始化application,只会初始化该activity

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值