Activity.startActivity()分析:本地进程部分
来源:互联网 发布:知乎稿费 编辑:程序博客网 时间:2024/05/16 10:01
主要内容
基本分析过程是一个Activity,a调用startActivity()启动b Activity(),Android系统内部进行的一些工作过程,主要分为三个过程,a Activity中的操作, AMS中的操作,B Activity中的操作,当中会有WMS相关的操作,基本目的是比较全面的分析一个Activity启动的全过程。
第一个A Activity中的工作
/framework/base/core/java/android/app/Activity.java
这个类中有许多的以startActivity开头的方法:
public void startActivityForResult(Intent intent, int requestCode),
public void startActivityForResult(Intent intent, int requestCode, Bundle options),
public void startActivity(Intent intent),
public void startActivity(Intent intent, Bundle options),
public void startActivities(Intent[] intents),
public void startActivities(Intent[] intents, Bundle options),
public boolean startActivityIfNeeded(Intent intent, int requestCode),
public boolean startActivityIfNeeded(Intent intent, int requestCode, Bundle options),
public void startActivityFromChild(Activity child, Intent intent,int requestCode) ,
public void startActivityFromChild(Activity child, Intent intent, int requestCode, Bundle options)
参数少的方法都是直接调用参数多的方法,其中参数多的方法中的参数options为null.
2.1 startActivity(Intent intent, Bundle options)
这个方法应该是最常用的方法,他的第一个参数是启动目标Activity的意图对象,Intent对象实质是一个Parcelable对象,因为这个对象需要进行跨进程传递给AMS,以使AMS能够根据这个对象找到正确的目标Activity信息。第二个参数用于传递数据,因为也是跨进程的,所以Bundle本身是一个Parcelable对象。
这个方法的实现就是直接调用startActivityForResule()方法。
public void startActivity(Intent intent, 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); } }
2.2 startActivityForResult(Intent intent, int requestCode, Bundle options)
这个方法多了一个int型的参数,这个参数其实是一个返回值,如果这个值大于0,则这个值会在此Activity退出时返回给调用他的Activity。当直接startActivity()时,这个值是-1,所以默认是不会返回的。
public void startActivityForResult(Intent intent, int requestCode, 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; } } 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); } } }这个方法根据mParent是否为空来进行分支处理。这个变量声明为Activity mParent,他也是一个Activity,这个变量在Activity本地创建时会被赋值,具体是在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) { attachBaseContext(context); mFragments.attachActivity(this); mWindow = PolicyManager.makeNewWindow(this);<span style="white-space:pre"></span>//这里申请一个surface mWindow.setCallback(this); mWindow.getLayoutInflater().setPrivateFactory(this); ... mParent = parent; ... }这个方法attach()是在ActivityThread-->handleLaunchActivity-->performLaunchActivity中调用的,调用activity.attach(..., r.parent,...);这个r为一个ActivityClientRecord对象,是一个ActivityRecord的本地对象。mParent赋值具体原则是如果新建的Activity是ActivityTask的根Activity,则mParent为null,否则为ActivityTask的根Activity
如果mParent不为空,则调用startActivityFromChild()方法,否则调用mInstrumentation.execStartActivity(...);方法;而startActivityFromChild(..)方法的实现也是调用了mInstrumentation.execStartActivity(...)方法
public void startActivityFromChild(Activity child, Intent intent, int requestCode, Bundle options) { Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(), mToken, child, intent, requestCode, options); if (ar != null) { mMainThread.sendActivityResult( mToken, child.mEmbeddedID, requestCode, ar.getResultCode(), ar.getResultData()); } }即startActivity方法最终都会调用mInstrumentation.execStartActivity(...)方法,最终调用AMS启动新的Activity的操作也是在这个方法中执行的。
2.3 Instrumentation.java
/framework/base/core/java/android/app/Activity.java
/** * 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. */public class Instrumentation这个类的对象会在Application之前创建对象,用于监督系统和Application直接的交互。
public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, Activity 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<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, null, options); checkStartActivityResult(result, intent); } catch (RemoteException e) { } return null; }可以知道他调用的是ActivityManagerNative里的startActivity方法。ActivityManagerNative是ActivityManagerService的本地代理类,由他代理和AMS之间的跨进程交互。这个类里面有很多的callActivityOnXx的方法,对应Activity的OnCreate等方法,即Activity的生命周期方法是在这个类里面调用的。ActivityManagerNative.startActivity方法会将调用者的进程信息,目标Activity的信息传递给AMS,一遍AMS去真正启动一个Activity组件。
2.4 ActivityManagerNative
public int startActivity(IApplicationThread caller, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, String profileFile, ParcelFileDescriptor profileFd, Bundle options) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(caller != null ? caller.asBinder() : null); intent.writeToParcel(data, 0); data.writeString(resolvedType); data.writeStrongBinder(resultTo); data.writeString(resultWho); data.writeInt(requestCode); data.writeInt(startFlags); data.writeString(profileFile); if (profileFd != null) { data.writeInt(1); profileFd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); } else { data.writeInt(0); } if (options != null) { data.writeInt(1); options.writeToParcel(data, 0); } else { data.writeInt(0); } mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0); reply.readException(); int result = reply.readInt(); reply.recycle(); data.recycle(); return result; }方法一开始获取两个Parcel对象,data和reply,分别用于往AMS写数据,和从AMS获取结果。
然后开始往data中写入相关数据:
data.writeStrongBinder(caller != null ? caller.asBinder() : null);写入调用者进程信息。
intent.writeToParcel(data, 0);写入Intent信息
最重要的语句:mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);这段代码将开启AMS远程服务,注意这里传递的flag是
START_ACTIVITY_TRANSACTION<span style="font-family: Arial, Helvetica, sans-serif;">。mRemote对象是一个Binder的客户端,由ServiceManager返回,具体代码为:</span>
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; }可见mRemote是通过ServiceManager获取的系统服务。transact方法里面会进行跨进程调用,具体使用Binder机制如何通信这里先不说,这一步的最后会调用ActivityManagerService里面的onTransact方法,而这个方法的具体实现也是在ActivityManagerNative里面,就是说在客户端和服务器端都有一个此类的对象。
/framework/base/core/java/android/app/ActivityManagerNative.java
这个方法有1500多行,会处理所有四大组件的相关事务,
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { switch (code) { case START_ACTIVITY_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); IApplicationThread app = ApplicationThreadNative.asInterface(b); Intent intent = Intent.CREATOR.createFromParcel(data); String resolvedType = data.readString(); IBinder resultTo = data.readStrongBinder(); String resultWho = data.readString(); int requestCode = data.readInt(); int startFlags = data.readInt(); String profileFile = data.readString(); ParcelFileDescriptor profileFd = data.readInt() != 0 ? data.readFileDescriptor() : null; Bundle options = data.readInt() != 0 ? Bundle.CREATOR.createFromParcel(data) : null; int result = startActivity(app, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, options); reply.writeNoException(); reply.writeInt(result); return true; }
<span style="white-space:pre"></span>...
<span style="white-space:pre"></span>}这个方法首先从data中取出数据,然后执行Activity启动过程中最重要的方法startActivity();
0 0
- Activity.startActivity()分析:本地进程部分
- Activity.startActivity源码分析
- Android中启动Activity(startActivity)流程图分析
- Android中启动Activity(startActivity)流程图分析
- Android中启动Activity(startActivity)流程图分析
- Android中启动Activity(startActivity)流程图分析
- Android中启动Activity(startActivity)流程图分析
- Android中启动Activity(startActivity)流程图分析
- Activity启动流程源码分析之startActivity启动(三)
- activity FLAG_ACTIVITY_REORDER_TO_FRONT 无法startActivity
- Activity之startActivity&finishActivity
- Kotlin activity跳转-startActivity
- Android Activity.startActivity流程简介
- android Activity启动过程-startActivity
- Android Activity.startActivity流程简介
- Android Activity.startActivity流程简介
- Android Activity.startActivity流程简介
- Activity的启动过程--startActivity()
- SDL2.0_07_classes
- windows平台下检测电池实现自动关机
- iOS单例模式
- java之UDP(datagramsocket,datagramPacket)实例
- 【干货】国外程序员整理的 C++ 资源大全
- Activity.startActivity()分析:本地进程部分
- use dynamic sql to output the result
- 金山WPS笔试题
- Java创建线程的两个方法
- DWR 报错:Error: java.lang.SecurityException, Session Error 和 Allocate exception for servlet 问题的解决办法
- ie6中的透明图片的解决办法
- 常见算法:C语言求最小公倍数和最大公约数三种算法
- 5个日志数据:让你轻松分析系统性能
- 第九周项目三—输出星号图e