Activity的启动过程(Android开发艺术探索学习笔记)
来源:互联网 发布:写作软件app 编辑:程序博客网 时间:2024/05/21 19:40
在Android系统中,应用程序是由Launcher启动起来的。其实,Launcher本身也是一个应用程序,其它的应用程序安装后,就会在Launcher界面上出现一个相应的图标,点击这个图标时,Launcher就会把对应的应用程序启动起来。Launcher部分源码如下(Launcher源码地址):
public final class Launcher extends Activity implements View.OnClickListener, OnLongClickListener { …… /** * Launches the intent referred by the clicked shortcut. * * @param v The view representing the clicked shortcut. */ public void onClick(View v) { Object tag = v.getTag(); if (tag instanceof ApplicationInfo) { // Open shortcut final Intent intent = ((ApplicationInfo) tag).intent; startActivitySafely(intent); } else if (tag instanceof FolderInfo) { handleFolderClick((FolderInfo) tag); } } void startActivitySafely(Intent intent) { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); try { startActivity(intent); } catch (ActivityNotFoundException e) { Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); } catch (SecurityException e) { Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); e(LOG_TAG, "Launcher does not have the permission to launch " + intent + ". Make sure to create a MAIN intent-filter for the corresponding activity " + "or use the exported attribute for this activity.", e); } } ……}
从上面的代码可以知道,在Launcher的onClick()中调用了startActivitySafely(),在startActivitySafely()中又调用了startActivity()。startActivity()有多个重载,最终会调用startActivityForResult():
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) { if (mParent == null) { 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; } cancelInputsAndStartExitTransition(options); // 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); } } }
可以看到调用了mInstrumentation的execStartActivity(),mInstrumentation是一个Instrumentation类型的成员变量。看一下Instrumentation类的定义:
/** * Base class for implementing application instrumentation code. When running * with instrumentation turned on, this class will be instantiated for you * before any of the application code, allowing you to monitor all of the * interaction the system has with the application. An Instrumentation * implementation is described to the system through an AndroidManifest.xml's * <instrumentation> tag. */
从定义可知Instrumentation用来监控应用程序和系统的交互。
我们还看到execStartActivity()传进去的一个变量是mMainThread.getApplicationThread(),这里的mMainThread也是Activity类的成员变量,它的类型是ActivityThread,它代表的是应用程序的主线程。这里通过mMainThread.getApplicationThread获得它里面的ApplicationThread成员变量,它是一个Binder对象,后面我们会看到,ActivityManagerService会使用它来和ActivityThread来进行进程间通信。从源码中可以看到ApplicationThread是ActivityThread的一个内部类。
接着继续看Instrumentation的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); 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.mEmbeddedID : null, requestCode, 0, null, options); checkStartActivityResult(result, intent); } catch (RemoteException e) { throw new RuntimeException("Failure from system", e); } return null; }
从上面代码可以看出调用了ActivityManagerNative.getDefault()的startActivity()。ActivityManagerService(简称AMS)继承自ActivityManagerNative,而ActivityManagerNative继承自Binder并且实现了IActivityManager,因此AMS也是一个Binder,它是IActivityManager的具体实现。
在ActivityManagerNative中AMS这个Binder以单例模式对外提供,getDefault()返回的是一个Singleton的泛型类。
public abstract class ActivityManagerNative extends Binder implements IActivityManager{ …… /** * Retrieve the system's default/global activity manager. */ static public IActivityManager getDefault() { return gDefault.get(); } …… 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; } }; ……}
Instrumentation的execStartActivity()调用ActivityManagerService的startActivity()后又调用了checkStartActivityResult():
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); case ActivityManager.START_NOT_CURRENT_USER_ACTIVITY: // Fail silently for this case so we don't break current apps. // TODO(b/22929608): Instead of failing silently or throwing an exception, // we should properly position the activity in the stack (i.e. behind all current // user activity/task) and not change the positioning of stacks. Log.e(TAG, "Not allowed to start background user activity that shouldn't be displayed" + " for all users. Failing silently..."); break; default: throw new AndroidRuntimeException("Unknown error code " + res + " when starting " + intent); } }
很明显可以看出,checkStartActivityResult()就是在检查启动Activity的结果。当无法正确地启动一个Activity时,这个方法会抛出异常。其中熟悉的一条就是”Unable to find explicit activity class; have you declared this activity in your AndroidManifest.xml?“
接着我们继续分析AMS的startActivity():
@Override public final int startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle options) { return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, options, UserHandle.getCallingUserId()); } @Override public final int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { enforceNotIsolatedCaller("startActivity"); userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY, "startActivity", null); // TODO: Switch to user app stacks here. return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, null, null, options, false, userId, null, null); }
startActivity()调用了startActivityAsUser(),然后Activity的启动过程又转移到了ActivityStackSupervisor的startActivityMayWait()。startActivityMayWait()中又调用了startActivityLocked(),startActivityLocked()调用了startActivityUncheckedLocked(),startActivityUncheckedLocked()调用了resumeTopActivitiesLocked(),resumeTopActivitiesLocked()又调用了ActivityStack的resumeTopActivityLocked()。这个时候启动过程已经从ActivityStackSupervisor转移到了ActivityStack。
然后resumeTopActivityLocked()调用了resumeTopActivityInnerLocked(),resumeTopActivityInnerLocked()调用了ActivityStackSupervisor的startSpecificActivityLocked()。这个时候启动过程又从ActivityStack转移到了ActivityStackSupervisor。然后startSpecificActivityLocked()调用了realStartActivityLocked()。realStartActivityLocked()中有这样一段代码:
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration), new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
这段代码很重要,其中app.thread的类型是IApplicationThread。IApplicationThread继承了IInterface:
/** * Base class for Binder interfaces. When defining a new interface, * you must derive it from IInterface. */public interface IInterface{ /** * Retrieve the Binder object associated with this interface. * You must use this instead of a plain cast, so that proxy objects * can return the correct result. */ public IBinder asBinder();}
从IInterface的定义可知,IApplicationThread继承了它,所以是一个Binder类型的接口。阅读IApplicationThread的源码,可以发现其内部包含了大量启动、停止Activity的接口,此外还包含了启动和停止服务的接口。那么IApplicationThread的实现类是什么,答案就是ActivityThread的内部类ApplicationThread。ApplicationThread继承自ApplicationThreadNative,ApplicationThreadNative是一个抽象类继承自Binder并且实现了IApplicationThread。
绕了一圈,Activity的启动最终回到了ApplicationThread,ApplicationThread通过scheduleLaunchActivity()来启动Activity:
// we use token to identify this activity without having to send the // activity itself back to the activity manager. (matters more with ipc) @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); }
最后发送了一个消息,不断调用重载方法:
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是一个H类型的成员变量,它继承了Handler:
private class H extends Handler { public static final int LAUNCH_ACTIVITY = 100; public static final int PAUSE_ACTIVITY = 101; public static final int PAUSE_ACTIVITY_FINISHING= 102; public static final int STOP_ACTIVITY_SHOW = 103; public static final int STOP_ACTIVITY_HIDE = 104; public static final int SHOW_WINDOW = 105; public static final int HIDE_WINDOW = 106; public static final int RESUME_ACTIVITY = 107; public static final int SEND_RESULT = 108; public static final int DESTROY_ACTIVITY = 109; …… 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; case RELAUNCH_ACTIVITY: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart"); ActivityClientRecord r = (ActivityClientRecord)msg.obj; handleRelaunchActivity(r); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break; case PAUSE_ACTIVITY: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause"); handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2, (msg.arg1&2) != 0); maybeSnapshot(); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; …… } } }
从H对”LAUNCH_ACTIVITY”的处理可以看到,Activity的启动过程又转移到了handleLaunchActivity()。handleLaunchActivity()又调用了performLaunchActivity(),performLaunchActivity()主要完成如下几件事:
1.从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); }
2.通过Instrumentation的newActivity()使用类加载器创建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); } } public Activity newActivity(ClassLoader cl, String className, Intent intent) throws InstantiationException, IllegalAccessException, ClassNotFoundException { return (Activity)cl.loadClass(className).newInstance(); }
3.通过LoadedApk的makeApplication()创建Application对象:
public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) { if (mApplication != null) { return mApplication; } Application app = null; String appClass = mApplicationInfo.className; if (forceDefaultAppClass || (appClass == null)) { appClass = "android.app.Application"; } try { java.lang.ClassLoader cl = getClassLoader(); if (!mPackageName.equals("android")) { initializeJavaContextClassLoader(); } ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this); app = mActivityThread.mInstrumentation.newApplication( cl, appClass, appContext); appContext.setOuterContext(app); } catch (Exception e) { if (!mActivityThread.mInstrumentation.onException(app, e)) { throw new RuntimeException( "Unable to instantiate application " + appClass + ": " + e.toString(), e); } } mActivityThread.mAllApplications.add(app); mApplication = app; if (instrumentation != null) { try { instrumentation.callApplicationOnCreate(app); } catch (Exception e) { if (!instrumentation.onException(app, e)) { throw new RuntimeException( "Unable to create application " + app.getClass().getName() + ": " + e.toString(), e); } } } // Rewrite the R 'constants' for all library apks. SparseArray<String> packageIdentifiers = getAssets(mActivityThread) .getAssignedPackageIdentifiers(); final int N = packageIdentifiers.size(); for (int i = 0; i < N; i++) { final int id = packageIdentifiers.keyAt(i); if (id == 0x01 || id == 0x7f) { continue; } rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id); } return app; }
从以上代码可以看出,如果Application已经被创建过了就不会被再创建了,这意味着一个应用只能有一个Application对象。Application对象的创建也是通过Instrumentation来完成的,同样通过类加载器来实现。Application对象创建完毕后,会调用Instrumentation的callApplicationOnCreate()来调用Application的onCreate():
public void callApplicationOnCreate(Application app) { app.onCreate(); }
4.创建ContextImpl对象并通过Activity的attach()来完成一些重要数据的初始化
Context appContext = createBaseContextForActivity(r, activity); CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager()); Configuration config = new Configuration(mCompatConfiguration); if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity " + r.activityInfo.name + " with config " + config); 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);
5.调用Instrumentation的callActivityOnCreate()来调用Activity的onCreate()
/** * Perform calling of an activity's {@link Activity#onCreate} * method. The default implementation simply calls through to that method. * * @param activity The activity being created. * @param icicle The previously frozen state (or null) to pass through to onCreate(). */ public void callActivityOnCreate(Activity activity, Bundle icicle) { prePerformCreate(activity); activity.performCreate(icicle); postPerformCreate(activity); } /** * Perform calling of an activity's {@link Activity#onCreate} * method. The default implementation simply calls through to that method. * @param activity The activity being created. * @param icicle The previously frozen state (or null) to pass through to * @param persistentState The previously persisted state (or null) */ public void callActivityOnCreate(Activity activity, Bundle icicle, PersistableBundle persistentState) { prePerformCreate(activity); activity.performCreate(icicle, persistentState); postPerformCreate(activity); }
- Activity的启动过程(Android开发艺术探索学习笔记)
- Android开发艺术探索笔记一:Activity的启动模式
- Android 开发艺术探索 学习笔记 Activity
- 《Android开发艺术探索》之学习笔记(一)Activity的生命周期和启动模式
- android开发艺术探索 学习笔记(二) Activity的启动模式
- **读Android开发艺术探索学习笔记--Activity的生命周期**
- Service的工作过程(Android开发艺术探索学习笔记)
- Android 开发艺术探索笔记-Activity启动方式
- android开发艺术探索 3 Activity的启动模式
- 《Android开发艺术探索》读书笔记----第一章:Activity的启动模式
- Android开发艺术探索-Activity的启动模式
- 《Android开发艺术探索》学习笔记---Activity详解
- 《Android开发艺术探索》笔记之Activity的生命周期和启动模式
- Android开发艺术探索(研读笔记)——02-Activity的启动模式
- 《Android开发艺术探索》笔记 — Activity的生命周期和启动模式
- Android开发艺术探索笔记——第一章:Activity的生命周期和启动模式
- Android开发艺术探索笔记(2)- Activity的启动模式
- Android开发艺术探索笔记(一) Activity的生命周期和启动模式(1)
- PHP面向对象三大特性之多态基础
- oracle 语句优化解析
- web页面打开本地App
- 入门级整合ssh框架
- Hibernate
- Activity的启动过程(Android开发艺术探索学习笔记)
- Attributions——属性控件
- H5直播避坑指南
- c语言解析类似json类型的字符串
- 从输入 URL 到页面展示,到底发生了什么
- 最短路
- 信赖域(Trust Region)
- 使用ANT打包Android应用
- IDEA Maven打包时去掉test