通过在方法中加入打印栈堆,然后通过Log被动跟踪代码走向。
在Activity.java文件,在onCreate方法中,加入一段Log , 用于打印栈堆信息。
android.util.Log.i("lpctest1","Activity onCreate"),new Excepiton());
java.lang.Exception
02-19 18:53:37.903 2196 2196 I lpctest1: at android.app.Activity.onCreate(Activity.java:990)
02-19 18:53:37.903 2196 2196 I lpctest1: at android.support.v4.app.SupportActivity.onCreate(SupportActivity.java:66)
02-19 18:53:37.903 2196 2196 I lpctest1: at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:290)
02-19 18:53:37.903 2196 2196 I lpctest1: at android.support.v7.app.AppCompatActivity.onCreate(AppCompatActivity.java:84)
02-19 18:53:37.903 2196 2196 I lpctest1: at com.android.contacts.activities.AppCompatTransactionSafeActivity.onCreate(AppCompatTransactionSafeActivity.java:33)
02-19 18:53:37.903 2196 2196 I lpctest1: at com.android.contacts.AppCompatContactsActivity.onCreate(AppCompatContactsActivity.java:81)
02-19 18:53:37.903 2196 2196 I lpctest1: at com.android.contacts.activities.ContactEditorActivity.onCreate(ContactEditorActivity.java:315)
02-19 18:53:37.903 2196 2196 I lpctest1: at android.app.Activity.performCreate(Activity.java:7000)
02-19 18:53:37.903 2196 2196 I lpctest1: at android.app.Activity.performCreate(Activity.java:6991)
02-19 18:53:37.903 2196 2196 I lpctest1: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
02-19 18:53:37.903 2196 2196 I lpctest1: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2732)
02-19 18:53:37.903 2196 2196 I lpctest1: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2857)
02-19 18:53:37.903 2196 2196 I lpctest1: at android.app.ActivityThread.-wrap11(Unknown Source:0)
02-19 18:53:37.903 2196 2196 I lpctest1: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1590)
02-19 18:53:37.903 2196 2196 I lpctest1: at android.os.Handler.dispatchMessage(Handler.java:106)
02-19 18:53:37.903 2196 2196 I lpctest1: at android.os.Looper.loop(Looper.java:164)
02-19 18:53:37.903 2196 2196 I lpctest1: at android.app.ActivityThread.main(ActivityThread.java:6495)
02-19 18:53:37.903 2196 2196 I lpctest1: at java.lang.reflect.Method.invoke(Native Method)
02-19 18:53:37.903 2196 2196 I lpctest1: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
02-19 18:53:37.903 2196 2196 I lpctest1: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
应用层为:AppCompatContactsActivity 和 ContactEditorActivity 等
系统层:ZygoteInit
、RuntimeInit
、ActivityThread
等
框架层: Instrumentation 、Activity、Handler 、Looper等
支持库层:SupporActivity、FragmentActivity、AppCompatActivity等
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2857)
此处显示,调用ActivityThread文件中的handLaunchActivity方法,执行
Activity a = performLaunchActivity(r , customIntent);
继续跟踪,点击 performaLaunchActivity方法跳转,跳转到ActivityThread.java文件中的performLaunchActivity方法中。通过Log信息得知,位置在该文件的2732行。
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2732)
进入ActivityThread.java文件的2732行,其执行 mInstrumentation.callActivityOnCreate(activity,r.state);
这段代码的整段语句为:
activity.mCalled = false;
if (r.isPersistable()){
mInstrumentation.callActivityOnCreate(activity, r.state , r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
在这个方法中,系统会恢复Activity的状态,包括临时状态和持久化状态。这段代码展示了,在Activity创建时,系统如何根据Activity是否被标记为持久化来调用不同onCreate方法。
activity.mCalled被设置为 false ,这通常是为了确保onCreate方法被正确调用,如果onCreate没被调用,系统会抛出一个异常。
r.isPersistable()是一个方法调用,用于检查ActivityRecord对象,r是否被标记为持久化。 如果 r.isPersistable()返回 true , 意味着Activity持久化,系统会调用 mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState)。
这里传递了两个Bundle对象: r.state和r.persistentState; 分别用于存储Activity的瞬时状态和持久化状态,这样区分是为了更好的管理不同类型的用户界面状态。确保在不同情况下能够正确恢复Activity状态。
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214)
这段Log显示,执行类Instrumentation.java文件中的第1214行,并且通过上一行代码,通过点击callActivityOnCreate方法跳转。进入到Instrumentation.java文件中的 callActivityOnCreate方法中。
public void callActivityOnCreate(Activity activity , Bundle icicle){
prePerformCreate(activity);
activity.performCreate(icicle); //活动执行创建
postPerformCreate(activity);
}
prePerformCreate(activity):这个方法是在Activity的onCreate方法被调用之前执行的。
activity.performCreate(icicle); 调用类Activity的onCreate方法,并将保存的Bundle对象icicle作为参数传递进去。
postPerformCreate(activity):这个方法是在Activity的onCreate方法被调用之后执行的。
android.app.Activity.performCreate(Activity.java:6991)
通过查看Log或者直接点击performCreate方法跳转,进入到Activity.java文件6991行中查看,传入的参数只有一个Bundle类为瞬时状态,持久状态处为NULL。
android.app.Activity.performCreate(Activity.java:7000)
通过Log查看,明确下一步执行Activity.java文件中的7000行代码。
进入文件后查看:
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
mCanEnterPictureInPicture = true;
restoreHasCurrentPermissionRequest(icicle); //还原当前权限请求
if (persistentState != null) { //判断当前状态是否为持久状态
onCreate(icicle, persistentState);
} else {
onCreate(icicle); //否,为暂时状态
}
该方法接收两个参数: icicle是Bundle对象,用于存储Activity的瞬时状态;persistentState是一个persistableBundle对象,用于存储Activity的持久状态。
mCanEnterPictureInPicture = ture; 用于控制Activity是否进入画中画模式(Picture-in-Picturemode),这是一种允许用户在小窗口中继续观看视频或进行其他操作的模式。
restoreHasCurrentPermissionRequest(icicle); 传入icicle参数。这个方法的目的是还原当前的权限请求状态。当Activity被销毁并重建时,可能需要恢复到之前的权限请求状态,保证用户在启动Activity时不会丢失权限请求的信息。
persistentState == null , 则重新回调 frameworkds/base/...../app 目录下的Activity.java文件中的 onCreate()方法。
这一段调用链已经清晰,那么是什么调用的handleLaunchActivity。现在重新回到android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2857)这段Log中。
重新回到ActivityThread.java文件的2857行代码,查看该代码所在的方法。点击handLaunchActivity方法或者通过Log查看:发现调用的是同一文件下的1590行代码。
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1590)
通过源码查看,是handlMessage()中,调用了handleLaunchActivity方法,向中传入类LAUNCH_ACTIVITY,下一步查看,是什么发出的这个消息。
通过查询 LAUNCH_ACTIVITY 向上寻找,定位到下面这行代码,是scheduleLaunchActivity方法。
sendMessage(H.LAUNCH_ACTIVITY, r);
通过Handler发送LAUNCH_ACTIVITY到主线程,触发后续的Activity启动流程。
那么是谁调用的scheduleLauncherActivity , 根据上述代码分析,这段设计到跨进程通信,scheduleLauncherActivity类中,调用了 updatePendingConfiguration()方法 和 updateProcessState() 方法 都涉及到跨进程通信。
(如何得知上述两个方法是跨进程通信,以updatePendingConfiguration()方法为例,点击该方法跳转到其所在类中:
private class ApplicationThread extends IApplicationThread.Stub {
...
}
发现其所在类ApplictaionThread继承自 IApplicationThread类,再通过点击IApplicationThread跳转到其中:
public interface IApplicationThread extends android.os.IInterface
{
可以看到,IApplicationThread继承类IIterface,再次点击跳转:
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接口,通过定义asBinder()方法,使得不同进程之间可以通过IBander对象进行跨进程远程通信。
接下来说回正题,也就是说scheduleLauncherActivity()方法不是ActivityThread.java文件中的其他方法调用的,而是其他方法通过跨进程的方式进来调用的。此时再通过打印堆栈不太容易找到,通过堆栈信息可以看到是通过Bander里的exeTransact,再到IApplicationThread中的onTransact,再就直接回到了ActivityThread文件的scheduleLauncherActivity中。
I lpctest1: scheculeLaunchActivity
I lpctest1: java.lang.Exception
I lpctest1: at android.app.ActivityThread$ApplicationThread.scheduleLaunchActivity(ActivityThread.java:788)
I lpctest1: at android.app.IApplicationThread$Stub.onTransact(IApplicationThread.java:196)
I lpctest1: at android.os.Binder.execTransact(Binder.java:697)
此时要继续跟,看是哪里调用了 scheduleLaunchActivity,可以选择使用查代码的方式查看。
通过指令:
grep "\.scheduleLaunchActivity" ./ -rn
找到调用该方法的文件位置,是在 frameworks/base/services/..../am 下的ActivityStackSupervisor.java文件中调用的。