您的位置 首页 新闻

Activity启动过程源码解析

Activity框架和管理结构 Activity管理的核心是AcitivityManagerService,是一个独立的进程; ActiveThread是每一个应用程序所在进程的主…

Activity框架和管理结构

Activity管理的核心是AcitivityManagerService,是一个独立的进程;

ActiveThread是每一个应用程序所在进程的主线程,循环的消息处理;

ActiveThread与AcitivityManagerService的通信是属于进程间通信,使用binder机制;

Activity启动过程

以启动一个应用程序startActivity为例看一下代码执行的大概流程:

可将其分为6个过程:

1 使用代理模式启动到ActivityManagerService中执行;

2 创建ActivityRecord到mHistory记录中;

3 通过socket通信到Zgote相关类创建process;

4 通过ApplicatonThread与ActivityManagerService建立通信;

5 ActivityManagerService通知ActiveThread启动Activity的创建;

6 ActivityThread创建Activity加入到mActivities中并开始调度Activity执行;

ActivityThread的创建过程

当我们第一次启动一个应用程序组件时,如果该应用没有任何组件存在,那么系统首先会创建该应用程序的ActivityThread

ActivityThread的创建过程是很复杂的,当程序进程第一次启动时,系统会在主线程中调用ActivityThread的main()方法,从而完成ActivityThread的创建。

ActivityThread是什么?网上有很多说法:ActivityThread是应用程序的主线程,其实这种说法不准确。先来看看ActivityThread的官方说明:

/** * This manages the execution of the main thread in an * application process, scheduling and executing activities, * broadcasts, and other operations on it as the activity * manager requests. * * {@hide} */ public final class ActivityThread {

可以看到ActivityThread本身并不是一个线程。它负责管理主线程在进程中的执行,调度和执行Activity、BroadCast以及其他ActivityManagerService(以下简称AMS)请求的操作。具体来说,就是ActivityThread接收AMS的请求,负责应用程序的管理,主要是回调应用程序的生命周期函数。准确的说法是ActivityThread是一个运行在主线程的类,负责完成主线程的逻辑。

系统在创建进程并初始化主线程的时候,会调用ActivityThread的main()方法,代码如下:

/** *当启动一个组件时,如果该组件的应用程序进程没有创建,则创建该组件的进程,并为该进程创建 *主线程,同时调用该方法 */ public static void main(String[] args) { SamplingProfilerIntegration.start(); // CloseGuard defaults to true and can be quite spammy. We // disable it here, but selectively enable it later (via // StrictMode) on debug builds, but using DropBox, not logs. CloseGuard.setEnabled(false); Environment.initForCurrentUser(); // Set the reporter for event logging in libcore EventLogger.setReporter(new EventLoggingReporter()); Security.addProvider(new AndroidKeyStoreProvider()); // Make sure TrustedCertificateStore looks in the right place for CA certificates final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId()); TrustedCertificateStore.setDefaultUserDirectory(configDir); Process.setArgV0(““); //为主线程创建Looper Looper.prepareMainLooper(); //创建ActivityThread ActivityThread thread = new ActivityThread(); //将ApplicationThread传递给AMS,通知AMS ActivityThread已经创建完毕 thread.attach(false); //初始化主线程的Handler,以后我们可以看到,对应用组件的的生命周期的回调是 //通过Handler发消息完成的 if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } //加载AsycTask,并且创建其内部的Handler。 AsyncTask.init(); if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, “ActivityThread”)); } //开启主线程的消息循环。 Looper.loop(); throw new RuntimeException(“Main thread loop unexpectedly exited”); }

可以看到main方法是该类的一个静态方法,主要完成以下操作:

为主线程创建Looper

创建ActivityThread

将ApplicationThread传递给AMS,通知AMS ActivityThread已经创建完毕

初始化主线程的Handler

加载AsycTask,并且创建其内部的Handler。

开启主线程的消息循环。

下面我们具体分析。

先看看 Looper.prepareMainLooper();

public static void prepareMainLooper() { prepare(false); synchronized (Looper.class) { if (sMainLooper != null) { throw new IllegalStateException(“The main Looper has already been prepared.”); } sMainLooper = myLooper(); } }

不难发现,它在主线程中创建了一个Looper对象。

紧接着,ActivityThread thread = new ActivityThread();创建了ActivityThread,并且会导致 mH和ApplicationThread的初始化。

然后,看看thread.attach(false):

private void attach(boolean system) { sCurrentActivityThread = this; mSystemThread = system; if (!system) { ViewRootImpl.addFirstDrawHandler(new Runnable() { @Override public void run() { ensureJitEnabled(); } }); android.ddm.DdmHandleAppName.setAppName(““, UserHandle.myUserId()); RuntimeInit.setApplicationObject(mAppThread.asBinder()); final IActivityManager mgr = ActivityManagerNative.getDefault(); try { //将ApplicationThread传递给AMS mgr.attachApplication(mAppThread); } catch (RemoteException ex) { // Ignore } // Watch for getting close to heap limit. BinderInternal.addGcWatcher(new Runnable() { @Override 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)) { if (DEBUG_MEMORY_TRIM) Slog.d(TAG, “Dalvik max=” + (dalvikMax/1024) + ” total=” + (runtime.totalMemory()/1024) + ” used=” + (dalvikUsed/1024)); mSomeActivitiesChanged = false; try { mgr.releaseSomeActivities(mAppThread); } catch (RemoteException e) { } } } }); } else { // Don’t set application object here — if the system crashes, // we can’t display an alert, we just want to die die die. android.ddm.DdmHandleAppName.setAppName(“system_process”, UserHandle.myUserId()); try { mInstrumentation = new Instrumentation(); ContextImpl context = ContextImpl.createAppContext( this, getSystemContext().mPackageInfo); //创建Application对象 mInitialApplication = context.mPackageInfo.makeApplication(true, null); //调用Application的onCreate()方法 mInitialApplication.onCreate(); } catch (Exception e) { throw new RuntimeException( “Unable to instantiate Application():” + e.toString(), e); } } //添加配置Callback ViewRootImpl.addConfigCallback(new ComponentCallbacks2() { @Override public void onConfigurationChanged(Configuration newConfig) { synchronized (mResourcesManager) { // We need to apply this change to the resources // immediately, because upon returning the view // hierarchy will be informed about it. if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) { // This actually changed the resources! Tell // everyone about it. if (mPendingConfiguration == null || mPendingConfiguration.isOtherSeqNewer(newConfig)) { mPendingConfiguration = newConfig; // sendMessage(H.CONFIGURATION_CHANGED, newConfig); } } } } @Override public void onLowMemory() { } @Override public void onTrimMemory(int level) { } }); }

可以看出 attach()主要完成以下几个步骤:

建立ApplicationThread和AMS之间的联系

创建Application对象并调用onCreat()方法,可以看到,Application对象,每个进程都会有且仅初始化一次。

添加ConfigurationCallback。

再看看AyncTask.init():

/** @hide Used to force static handler to be created. */ public static void init() { sHandler.getLooper(); }

这个方法时一个静态方法,作用是强制创建AsyncTask内部的Handler。由于异步任务是在线程池中执行任务,所以,必须使用Handler实现子线程和主线程之间的通讯。

最后 Looper.loop()方法为主线程开启消息循环。

至此,ActivityThread创建完毕,接下来,AMS就可以通过ApplicationThead来控制组件的生命周期。

参考链接

android 源码剖析之——-ActivityThread的创建过程 – 程序园

Activity启动过程

ActivityThread用来管理四大组件。其中,ApplicationThread是供AMS调用ActivityThread远程方法的Binder类,AMS管理Activity正是通过ApplicationThread调用ActivityThread的相应方法完成的。我们知道通过Binder进行IPC的方法调用,是执行在服务端的Binder线程池中的,而不是主线程中,但是应用程序组件的生命周期方法执行在主线程,如何实现子线程中回调生命周期函数呢?答案是通过ActivityThread里的mH,它是一个Handler,由它来回调组件的生命周期回调。

下面,以Activity的创建为例,从源码的角度分析一下整个过程。其他的过程与启动过程类似。

当我们使用startActivity()方法启动一个Activity时,会经过以下路径:

Activity.startActivity() —>Activity.startActivityForResult()

在Activity.startActivityForResult()里,执行如下操作:

if (mParent == null) { //通过Instrumentation启动Activity 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) { // If this start is requesting a result, we can avoid making // the activity visible until the result is received. Setting // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the // activity hidden during this time, to avoid flickering. // This can only be done when a result is requested because // that guarantees we will get information back when the // activity is finished, no matter what happens to it. mStartedActivity = true; } final View decor = mWindow != null ? mWindow.peekDecorView() : null; if (decor != null) { decor.cancelPendingInputEvents(); } // TODO Consider clearing/flushing other event sources and events for child windows. } else { if (options != null) { mParent.startActivityFromChild(this, intent, requestCode, options); } else { // Note we want to go through this method for compatibility with // existing applications that may have overridden it. mParent.startActivityFromChild(this, intent, requestCode); } } if (options != null && !isTopOfTask()) { mActivityTransitionState.startExitOutTransition(this, options); } }

可以看到,最终是通过Instrumentation.execStartActivity()来启动Activity的,再看看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= 0 ? am.getResult() : null; } break; } } } } try { intent.migrateExtraStreamToClipData(); intent.prepareToLeaveProcess(); //Activity的真正启动过程是ActivityManagerNative完成的,本质上是调用AMS里面的方法启动 int result = ActivityManagerNative.getDefault() .startActivity(whoThread, who.getBasePackageName(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target != null ? target.mWho : null, requestCode, 0, null, options); //检查Activity是否被成功创建 checkStartActivityResult(result, intent); } catch (RemoteException e) { } return null; }

可以看到Activity的真正启动过程是ActivityManagerNative完成的,而ActivityManagerService是ActivityManagerNative的实现类,通过对ServiceManager进行分析ActivityManagerNative.getDefault()得到的的确是AMS,这里就不做分析,后面会做详细的解析。

同时,我们注意到checkStartActivityResult(result, intent);这是用来对返回结果做检查:

public static void checkStartActivityResult(int res, Object intent) { if (res >= ActivityManager.START_SUCCESS) { return; } switch (res) { case ActivityManager.START_INTENT_NOT_RESOLVED: case ActivityManager.START_CLASS_NOT_FOUND: if (intent instanceof Intent && ((Intent)intent).getComponent() != null) throw new ActivityNotFoundException( “Unable to find explicit activity class ” + ((Intent)intent).getComponent().toShortString() + “; have you declared this activity in your AndroidManifest.xml?”); throw new ActivityNotFoundException( “No Activity found to handle ” + intent); case ActivityManager.START_PERMISSION_DENIED: throw new SecurityException(“Not allowed to start activity ” + intent); case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT: throw new AndroidRuntimeException( “FORWARD_RESULT_FLAG used while also requesting a result”); case ActivityManager.START_NOT_ACTIVITY: throw new IllegalArgumentException( “PendingIntent is not an activity”); case ActivityManager.START_NOT_VOICE_COMPATIBLE: throw new SecurityException( “Starting under voice control not allowed for: ” + intent); default: throw new AndroidRuntimeException(“Unknown error code ” + res + ” when starting ” + intent); } }

那些异常是不是很熟悉。

接下来看看ActivityManagerService.startActivity(),会发现会走下面的调用逻辑:

startActivity() —-

startActivityAsUser() —>ActivityStackSupervisor.startActivityMayWait()—>ActivityStackSupervisor.startActivityLocked()—> ActivityStackSupervisor.startActivityUncheckedLocked—>ActivityStack.resumeTopActivityLocked()—>ActivityStack.resumeTopActivityInnerLocked()—>ActivityStackSupervisor.startSpecificActivityLocked—- ActivityStackSupervisor.realStartActivityLocked

可以看到执行逻辑从ActivityManagerService到ActivityStackSupervisor,到ActivityStack,最后又到了ActivityStackSupervisor。

下面看看ActivityStackSupervisor.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);

可以发现,创建Activity最终是由app.thread来完成的,而app.thread是一个IApplicationThread,它是一个Binder接口,声明了很多与Activity和Service回调相关的方法。

IApplicationThread的实现类是ActivityThread中的内部类ApplicationThread,它继承自抽象类ApplicationThreadNative,而这个ApplicationThread对象正是实现AMS和ActivityThread实现IPC的媒介。

再看看ApplicationThread.scheduleLaunchActivity()是怎么处理的。

public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo, IVoiceInteractor voiceInteractor, int procState, Bundle state, PersistableBundle persistentState, List pendingResults, List pendingNewIntents, boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) { updateProcessState(procState, false); ActivityClientRecord r = new ActivityClientRecord(); r.token = token; r.ident = ident; r.intent = intent; 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; updatePendingConfiguration(curConfig); //最终通过Handler发消息,回调Activity的生命周期方法 sendMessage(H.LAUNCH_ACTIVITY, r); }

可以看到主要完成两项任务,一个是利用AMS传递的信息创建一个ActivityClientRecord 对象,第二个是发送一个创建Activity的消息

最终我们发现是这样发消息的:

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

它是通过mH发送了一条消息,mH其实是一个Handler。那么问题来了,为什么要这么做呢?因为ApplicationThread.scheduleLaunchActivity()是在应用程序的Binder’线程池中运行的,而Activity运行在主线程,因而要使用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); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break;

在H里面,可以看到,启动Activity的操作是由handleLaunchActivity(r, null)完成的。

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) { // If we are getting ready to gc after going to the background, well // we are back active so skip it. unscheduleGcIdler(); mSomeActivitiesChanged = true; if (r.profilerInfo != null) { mProfiler.setProfiler(r.profilerInfo); mProfiler.startProfiling(); } // Make sure we are running with the most recent config. handleConfigurationChanged(null, null); if (localLOGV) Slog.v( TAG, “Handling launch of ” + r); //回调,完成Activity的创建 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); if (!r.activity.mFinished && r.startsNotResumed) {

可以看到创建Activity最终是由performLaunchActivity(r, customIntent)完成的。

这个方法主要完成以下几个方面的内容:

从ActivityClientRecord中拿到Activity的组件信息

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

通过Instrumentation的newActivity方法创建Activity实例

其实Instrumentation是通过Java的反射机制创建Activity的。

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); } } catch (Exception e) { if (!mInstrumentation.onException(activity, e)) { throw new RuntimeException( “Unable to instantiate activity ” + component + “: ” + e.toString(), e); } }

创建Application对象,

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

可以知道,在一个进程中,如果Application对象已经存在,是不会再创建Application对象的。

调用Activity的attach方法,主要是创建Window

通过Instrumentation的callmInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);调用Activity的oncreate()方法。

在onCreate()方法里,我们通过调用setContentView方法,为DecorView里的内容栏设置了布局 在onCreate()方法完成之后,一个Activity就创建成功了。

继续看performLaunchActivity()这个方法:

if (!r.activity.mFinished) { activity.performStart(); r.stopped = false; } 在调用onCreate()之后,会去执行 activity.performStart(),这里会调用: mInstrumentation.callActivityOnStart(this); 而这个方法里会调用: public void callActivityOnStart(Activity activity) { activity.onStart(); } 从而在执行onCreate之后,会执行onStart()方法; 同样,在onStart之后,会判断需要不需要执行OnRestoreInstanceState方法: //调用OnRestoreInstanceState方法 if (!r.activity.mFinished) { 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); } }

在performLaunchActivity()方法返回后,这是,DecorView还处于不可见的状态,而且不能没有获得焦点。这是因为DecorView还没有关联WMS

在handleLaunchActivity()方法里,performLaunchActivity()方法执行完毕之后,接着执行:

if (a != null) { r.createdConfig = new Configuration(mConfiguration); Bundle oldState = r.state; //回调activity的onResume方法。 handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished && !r.startsNotResumed); 在handleResumeActivity()里首先执行这段代码: ActivityClientRecord r = performResumeActivity(token, clearHide); 顾名思义,这最终导致onResume方法被调用 紧接着,会执行这段代码: if (r.activity.mVisibleFromClient) { //将decorView添加到WMS中 r.activity.makeVisible(); } 我们在看看activity.makeVisible() void makeVisible() { if (!mWindowAdded) { ViewManager wm = getWindowManager(); wm.addView(mDecor, getWindow().getAttributes()); mWindowAdded = true; } mDecor.setVisibility(View.VISIBLE); }

可以看到,最终在这里DecorView被添加到WSM里,从而能够接受用户的输入,并响应窗口事件。

至此,Activity的启动过程分析完毕。

参考链接

Android源码剖析之—–Activity的启动过程 – 程序园

总结

启动一个activity的过程

(1) 我们app中是使用了Activity的startActivity方法,具体调用的是ContextImpl的同名函数。

(2) ContextImpl中会调用Instrumentation的execStartActivity方法。

(3) Instrumentation通过aidl进行跨进程通信,最终调用AMS的startActivity方法。

(4) 在系统进程中AMS中先判断权限,然后通过调用ActivityStackSupervisor和ActivityStack进行一系列的交互用来确定Activity栈的使用方式。

(5) 通过ApplicationThread进行跨进程通信,转回到app进程。

(6) 通过ActivityThread中的H(一个handler)传递消息,最终调用Instrumentation来创建一个Activity。

本文来自网络,不代表Xnewv立场,转载请注明出处:https://xnewv.com/2331.html

为您推荐

联系我们

联系我们

18873343099

在线咨询: QQ交谈

邮箱: [email protected]

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部