Android Activity原理分析 联系客服

发布时间 : 星期日 文章Android Activity原理分析更新完毕开始阅读

这个图,开始进入到了关键的地方了,通过realStartActivityLocked开始真正和我们要启动的activity相关了,前面都是一些过场,通过activityThread建设基础环境; 接着往下看:

realStartActivityLocked(r, app, andResume, checkConfig)ActivityManagerService.javarealStartActivityLocked(HistoryRecord r,ProcessRecord app, boolean andResume, boolean checkConfig)ActivityManagerService.javamWindowManager.setAppVisibility(r, true);app.thread.scheduleLaunchActivity(new Intent(r.intent), r,System.identityHashCode(r), r.info, r.icicle, results, newIntents, !andResume,isNextTransitionForward());scheduleLaunchActivityApplicationThreadNative.javamRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,IBinder.FLAG_ONEWAY);左边这路是涉及显示相关的,以后分析图形系统的时候再讲这里只需要知道它在消息队列里面放了一消息,最后会触发显示流程;

右边这路是我们跟踪的路径,通过scheduleLaunchActivity开始触发activity的启动;

在Android的代码里我发现一个特点,凡是带schedule的,基本上都不会直接做事,它翻译成中文就是“安排”,这个安排通常都不是立即的,而是放入到消息队列里面等到下一个循环才能处理,不信接着看:

?Tech, 2010-2-5 Page 17 of 38

onTransactApplicationThreadNative.javacase SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION:scheduleLaunchActivity(intent, b, ident, info, state, ri, pi,notResumed, isForward)queueOrSendMessage(H.LAUNCH_ACTIVITY, r);正如我上面说的,这种带schedule的都是通过发送消息到信号队列里面完成的,这个过程我也就在附录【1】里面分析过,这里就不分析了,只需要知道,在某个循环里面会调用 handleMessage(Message msg) 来处理,而且这个图的逻辑已经回到了activityThread.java这个进程了,也就是回到了我们要启动的activity的进程,接着看:

public void handleMessage(Message msg) ActivityThread.java case LAUNCH_ACTIVITYActivityRecord r = (ActivityRecord)msg.objr.packageInfo = getPackageInfoNoCheck(r.activityInfo.applicationInfo)handleLaunchActivity(r, null)取得从消息里面传递过来的信息,然后再取得此activity的包信息,后面会用到,比如权限检查等; 最后通过handleLaunchActivity来真正启动我们的activity了;

?Tech, 2010-2-5 Page 18 of 38

5.1.4 OnCreate函数的调用

handleLaunchActivity(r, null)这边是到activity自己的代码这边是显示流程Activity a = performLaunchActivity(r, customIntent) if (a != null)performLaunchActivity(ActivityRecord r, Intent customIntent)r.createdConfig = new Configuration(mConfiguration)handleResumeActivity(r.token, false, r.isForward)这里很关键,触发了整个显示的过程 activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent);mInstrumentation.callActivityOnCreate(activity, r.state)callActivityOnCreateInstrumentation.javaactivity.onCreate(icicle);Create的调用流程最右边的分支是Resume的流程,后面讲;

这里我们看到了我们最想看到的activity.onCreate函数调用了,如果我们自己写的代码,里面会实现这个onCreate函数,做我们自己想做的事,当然我们的实现里面必须要调用: super.onCreate,其它的六个状态函数也一样,必须要调用父类的同名函数;

handleLaunchActivity还做了其它的一些事情, resume,它的逻辑在最右边的分支; 而函数performLaunchActivity这里只画出了onCreate,其实它还会触发onStart的调用;

5.1.5

OnStart的调用

前面说过,performLaunchActivity其实做了很多事情,就包括对于onStart的调用,如下所示:

?Tech, 2010-2-5 Page 19 of 38

performLaunchActivity(ActivityRecord r, Intent customIntent)mInstrumentation.callActivityOnCreate(activity, r.state)OnCreate的调用逻辑 if (!r.activity.mFinished) mActivities.put(r.token, r)这里把IBinder和activity做一个连接activity.performStartperformStartActivity.javamCalled = falsemInstrumentation.callActivityOnStart(this)allActivityOnStart(Activity activity)activity.onStart通常这个函数会被重新实现Activity.javamCalled = true当重新实现后,记得调用这个父类的同名函数,否则会抛出异常最左边的分支,是我们上面已经说过的onCreate的调用逻辑; 中间的逻辑就是我们的onStart的调用逻辑;

通常对于onCreate,onStart等七个状态的函数调用,都遵循这样一种法则:

调用之前设置mCalled=false,然后在实现的函数里面设置mCalled=true,等这个函数返回以后通过判断这个mCalled是否为true来判断父类的同名函数是否会已经被调用了,这也就是为什么我们必须要在子类的实现里面调用父类的同名方法的原因之一; 最右边的路径表示把这个IBinder和这个activity连接起来,因为一个ActivityThread很有可能管理着多个activity,以后才可以根据这个IBinder找到正确的Activity; 好下面看看onResume的调用路径;

?Tech, 2010-2-5

Page 20 of 38