android Activity启动流程

Activity的启动过程,我们可以从Context的startActivity说起,其实现是ContextImpl的startActivity,然后内部会通过Instrumentation来尝试启动Activity,这是一个跨进程过程,它会调用ams的startActivity方法,当AMS校验完activity的合法性后,会通过ApplicationThread回调到我们的进程,这也是一次跨进程过程,而applicationThread就是一个binder,回调逻辑是在binder线程池中完成的,所以需要通过Handler H将其切换到ui线程,第一个消息是LAUNCH_ACTIVITY,它对应handleLaunchActivity,在这个方法里完成了Activity的创建和启动,接着,在activity的onResume中,activity的内容将开始渲染到window上,然后开始绘制直到我们看见(摘自网友的总结)

当在app内通过startActiviy启动一个新的Activity的时候,主要会调用以下几个函数

MyActivity.startActivity() 
Activity.startActivity() 
Activity.startActivityForResult 
Instrumentation.execStartActivty 
ActivityManagerNative.getDefault().startActivityAsUser() 

首选我们看一下startActivity方法

 @Override
    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);
        }
    }

startAcitity最终会执行startActivityForResult方法,如果调用startActivity方法传入了-1,表示会有返回值返回。

继续向下看startActivityForResult方法

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);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            if (requestCode >= 0) {
                mStartedActivity = true;
            }

            cancelInputsAndStartExitTransition(options);
        } else {
            if (options != null) {
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }
    }

在上面的代码中,mParent进行了一个判Null操作,可以发现由于我们是第一次启动Activity,所以这里的mParent为空,所以会执行if分之,然后调用mInstrumentation.execStartActivity方法,

重点看下以下代码

nstrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);

mInstrumentation.execStartActivity中传递了几个参数,第二个参数mMainThread就是程序的主线程,它在app启动的时候创建的,即UI线程,mMainThread.getApplication()获取到binder对象,代表了app的主线程;mToken也是一个Binder对象,代表了上一个Activity也通过Instumentation传递给AMS,此时AMS就知道谁向自己发送的消息了。

mInstrumentation的execStartActivity方法

public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        Uri referrer = target != null ? target.onProvideReferrer() : null;
        if (referrer != null) {
            intent.putExtra(Intent.EXTRA_REFERRER, referrer);
        }
        if (mActivityMonitors != null) {
            synchronized (mSync) {
                final int N = mActivityMonitors.size();
                for (int i=0; i<N; i++) {
                    final ActivityMonitor am = mActivityMonitors.get(i);
                    ActivityResult result = null;
                    if (am.ignoreMatchingSpecificIntents()) {
                        result = am.onStartActivity(intent);
                    }
                    if (result != null) {
                        am.mHits++;
                        return result;
                    } else if (am.match(who, null, intent)) {
                        am.mHits++;
                        if (am.isBlocking()) {
                            return requestCode >= 0 ? am.getResult() : null;
                        }
                        break;
                    }
                }
            }
        }
        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;
    }

execStartActivity主要有以下几个参数

who:启动Activity对象

contextThread:Binder对象,为主进程的context对象

token:Binder对象,

target:为启动的目标Activity

intent:启动的Intent对象

requestCode:请求吗

options:参数

通过,execStartActivity方法可以发现,该方法主要调用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;
                }
            };

变量IActivityManagerSingleton是个Singleton对象,下面看下Singleton源码

package android.util;

/**
 * Singleton helper class for lazily initialization.
 *
 * Modeled after frameworks/base/include/utils/Singleton.h
 *
 * @hide
 */
public abstract class Singleton<T> {
    private T mInstance;

    protected abstract T create();

    public final T get() {
        synchronized (this) {
            if (mInstance == null) {
                mInstance = create();
            }
            return mInstance;
        }
    }
}

 Singleton是一个抽象类,有一个抽象方法create()。有一个get()方法,内部通过单例模式创建T对象,调用create方法创建T对象,且只会创建一次T对象。

继续查看create方法的具体实现,IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE)获取一个关联了系统服务ActivityManagerService的Binder对象;IActivityManager.Stub.asInterface(b)返回一个IActivityManager的代理对象,基于Binder机制,通过调用代理对象的方法,使得系统服务ActivityManagerService对应的方法被调用。可以猜测ActivityManagerService肯定继承了IActivityManager.Stub,事实也确实如此。
       ActivityManagerService源码如下:

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

回到Instrumentation.execStartActivity方法的ActivityManager.getService().startActivity(...),就是IActivityManager的代理对象调用了startActivity方法,通过Binder机制,它会使系统服务ActivityManagerService的startActivity方法被调用。因此,启动Activity的操作就交给了系统服务ActivityManagerService来处理了。

ApplicationThread继承了IApplicationThread.Stub,并提出ApplicationThread重写接口IApplicationThread的抽象方法在哪里被调用。有意思的是,app.thread调用scheduleLaunchActivity方法,通过Binder机制,会使ApplicationThread$scheduleLaunchActivity方法被调用。
       于是,基于Binder机制,实现了一次进程间的通信,将启动Activity的操作交给了ApplicationThread类。

 

ApplicationThread是ActivityThread的内部类,因此ApplicationThread可以调用外部类ActivityThread的方法,也可以这样理解,启动Activity的操作交给了ActivityThread来处理。

查看ActivityThread 的 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<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

            updateProcessState(procState, false);

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

            sendMessage(H.LAUNCH_ACTIVITY, r);
        }

创建了一个ActivityClientRecord对象,用于封装启动Activity需要的一些参数值。

最后一行调用ActivityThread$sendMessage方法,查看其源码如下:

private void sendMessage(int what, Object obj) {
        sendMessage(what, obj, 0, 0, false);
}
 
//继续查看
 
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        if (DEBUG_MESSAGES) Slog.v(
            TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
            + ": " + arg1 + " / " + obj);
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        mH.sendMessage(msg);
}

第19行,mH是一个H对象,类H是ActivityThread的内部类,并继承了Handler。于是,启动Activity的操作放在处理消息的方法H$handleMessage中。

private class H extends Handler {

    //...code
	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;
    	
	//...code

}

  第9行,取出Message对象中的obj字段,它是一个ActivityClientRecord对象;
       第10行,调用ActivityThread$getPackageInfoNoCheck方法,返回一个LoadedApk对象,并将该对象封装到ActivityClientRecord的packgeInfo字段中。
       第11行,调用ActivityThread$handleLaunchActivity方法启动Activity;

  查看ActivityThread$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 {
        // If there was an error, for any reason, tell the activity manager to stop us.
        try {
             ActivityManager.getService()
                    .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                            Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
    }

}

第4行,调用performLaunchActivity方法启动Activity;
       第11行,若a不为空,则调用handleResumeActivity方法,内部会调用Activity$onResume方法。具体的代码流程还是比较好跟的,由于不是本篇的重点,有兴趣的哥们可以自己去研究。
       第16行,当a为空,也就是创建Activity的实例出错了,走else语句。ActivityManager.getService()前面已经分析过了,返回IActivityManager的代理对象,调用该代理对象的方法,会向系统服务ActivityManagerService发送请求,基于Binder机制,最终会调用ActivityManagerService$finishActivity方法。
       也就是说,当创建Activity实例出错后,停止启动Activity的具体操作交给ActivityManagerService来处理。

 回到启动Activity的流程,查看ActivityThread$performLaunchActivity源码如下:

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");

        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }

        ComponentName component = r.intent.getComponent();
        if (component == null) {
            component = r.intent.resolveActivity(
                mInitialApplication.getPackageManager());
            r.intent.setComponent(component);
        }

        if (r.activityInfo.targetActivity != null) {
            component = new ComponentName(r.activityInfo.packageName,
                    r.activityInfo.targetActivity);
        }
ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        
	    //...code

            java.lang.ClassLoader cl = appContext.getClassLoader();
            if (appContext.getApplicationContext() instanceof Application) {
                activity = ((Application) appContext.getApplicationContext())
                        .instantiateActivity(cl, component.getClassName(), r.intent);
            }
            if (activity == null) {
                activity = mInstrumentation.newActivity(
                        cl, component.getClassName(), r.intent);
            }
            
	    //...code

            Application app = r.packageInfo.makeApplication(false, mInstrumentation);

            //...code

            if (activity != null) {
                
		//...code
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);

                //...code

                mInstrumentation.callActivityOnCreate(activity, r.state);

		//...code
	     }
   
        return activity;
}

ActivityThread$performLaunchActivity方法的操作:
       1,获取要启动的Activity的ComponentName对象:里面包含了包名,类名相关的信息;
       2,创建Activity的上下文环境:即创建了ContextImpl对象;
       3,创建Activity的实例:调用Instrumentation$newActivity方法,并使用类加载器创建Activity对象;
       4,创建Application对象;
       5,调用Activity$attach方法:初始化Activity类里的一些数据;
       6,启动Activity:调用Instrumentation$callActivityOnCreate方法;

 分析ActivityThread$performLaunchActivity方法:


       步骤2,创建了Activity的上下文环境,ContextImpl是抽象类Context的实现类,有关Context的操作的具体实现,大多数由ContextImpl完成。
       查看ActivityThread$createBaseContextForActivity源码如下:

private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {

	//...code

	ContextImpl appContext = ContextImpl.createActivityContext(
                this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);
	
	//...code

	return appContext;
}

继续查看ContextImpl$createActivityContext源码如下:

static ContextImpl createActivityContext(ActivityThread mainThread,
            LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId,
            Configuration overrideConfiguration) {
	    //...code

	    ContextImpl context = new ContextImpl(null, mainThread, packageInfo, activityInfo.splitName,
                activityToken, null, 0, classLoader);
	    
	   //...code 
}

很显然,最终创建了一个ContextImpl对象。

 

 步骤3,创建了一个Activity的实例。

        查看Instrumentation$newActivity源码如下:

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

通过ClassLoader创建Activity的实例。

 

       步骤4,创建了Application对象

       查看LoadedApk$makeApplication方法源码如下:

public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        if (mApplication != null) {
            return mApplication;
        }

	Application app = null;

	//...

	app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
	
	//...

	mApplication = app;

	instrumentation.callApplicationOnCreate(app);
	//...

	return app;
}

 第3行,当mApplication不为null时,也就是Application对象已经存在时,直接返回mApplication。很显然Application是一个单例对象,一个应用程序中只存在一个Application对象。
       第11行,当应用程序内存中没有Application对象时,创建一个Application对象。跟Activity一样,都是通过类加载器ClassLoader来创建实例。具体代码就不再展示,有兴趣哥们可以去验证。
       第16行,将Application对象app赋给字段mApplication。
       第18行,调用Application的onCreate方法。
       查看Instrumentation$callApplicationOnCreate方法源码

    public void callApplicationOnCreate(Application app) {
        app.onCreate();
    }

 

步骤5,调用Activity$attach方法初始化数据。

       查看Activity$attach方法源码:

final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor,
            Window window) {
        attachBaseContext(context);

        mFragments.attachHost(null /*parent*/);

        mWindow = new PhoneWindow(this, window);
        mWindow.setWindowControllerCallback(this);
        mWindow.setCallback(this);
        mWindow.setOnWindowDismissedCallback(this);
        mWindow.getLayoutInflater().setPrivateFactory(this);
        if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
            mWindow.setSoftInputMode(info.softInputMode);
        }
        if (info.uiOptions != 0) {
            mWindow.setUiOptions(info.uiOptions);
        }
        mUiThread = Thread.currentThread();

        mMainThread = aThread;
        mInstrumentation = instr;
        mToken = token;
        mIdent = ident;
        mApplication = application;
        mIntent = intent;
        mReferrer = referrer;
        mComponent = intent.getComponent();
        mActivityInfo = info;
        mTitle = title;
        mParent = parent;
        mEmbeddedID = id;
        mLastNonConfigurationInstances = lastNonConfigurationInstances;
        if (voiceInteractor != null) {
            if (lastNonConfigurationInstances != null) {
                mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor;
            } else {
                mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this,
                        Looper.myLooper());
            }
        }

        mWindow.setWindowManager(
                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
        if (mParent != null) {
            mWindow.setContainer(mParent.getWindow());
        }
        mWindowManager = mWindow.getWindowManager();
        mCurrentConfig = config;
    }

 第8行,参数context:步骤2中创建的ContextImpl对象传入的。attachBaseContext方法:给ContextWrapper的成员变量mBase设置值为ContextImpl对象。ContextWrapper是Context的一个子类,具体的代码流程感兴趣的哥们可以去验证~
       第12行,创建了窗口对象PhoneWindow;
       第13~15行,给窗口对象注册监听接口;
       第23~37行,初始化一些变量的值;
       第47行,通过窗口Window创建WindowManagerImpl的实例;
       第54行,将47行创建的WindowManagerImpl的实例,设置给变量mWindowManager;

 

步骤6,调用Instrumentation$callActivityOnCreate方法启动Activity。

       查看Instrumentation$callActivityOnCreate源码:

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

 第3行,调用了Activity$performCreate方法。

       查看Activity$performCreate源码如下

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

第3行,调用了Activity的onCreate方法启动Activity,分析完成

发布了15 篇原创文章 · 获赞 0 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qinggancha/article/details/104437559