这几天心情很不好,我也不知道是什么原因,虽然一直的习惯是找到事物/念想产生的原因,但是这一回却真是找不到原因了,哈哈,人丑还是要多读书啊。不过,不管怎样,不管周围的人的变得怎样,周围的世界变得怎样,依然要保持学习,做自己想做的事,做一个开心而有价值的人。
想起一首诗以自勉:
自小刺头深草里,而今渐觉出蓬蒿。
时人不识凌云木,直待凌云始道高。
-唐代杜荀鹤 《小松》
Activity的启动从startActivity起:
startActivity(new Intent(MainActivity.this, LayerListActivity.class));
会调到Activity的源码:
/**
* Same as {@link #startActivity(Intent, Bundle)} with no options //方法的多态,同名不同参;
* specified.
*
* @param intent The intent to start.
*
* @throws android.content.ActivityNotFoundException//如果在清单文件中没找到对应的activity,会抛出这个异常;
*
* @see {@link #startActivity(Intent, Bundle)}
* @see #startActivityForResult
*/
@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
先了解一下 类ActivityNotFoundException:
//是运行时异常的子类
//包含两个构造方法
package android.content;
public class ActivityNotFoundException extends RuntimeException
{
public ActivityNotFoundException()
{
}
public ActivityNotFoundException(String name)
{
super(name);
}
};
关于Java 异常类层次结构图:
回到正题,然后调用同名方法:
@Override
public void startActivity(Intent intent, @Nullable 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);
}
}
其中作为if 条件的ActivityOptions,兼容包是ActivityOptionsCompat,和页面切换的转场动画相关。它的主要方法是:
不管怎样,最后都调到 activity.startActivityForResult :
public class Activity extends ContextThemeWrapper
implements LayoutInflater.Factory,
Window.Callback, KeyEvent.Callback,
OnCreateContextMenuListener, ComponentCallbacks {
......
public void startActivityForResult(Intent intent, int requestCode) {
if (mParent == null) {
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode);
......
} else {
......
}
......
}
- 这里的mInstrumentation的类型是Intrumentation,定义在frameworks/base/core/java/android/app/Instrumentation.java文件中,它用来监控应用程序和系统的交互。ActivityResult 是它的内部静态类。
- 这里的mMainThread也是Activity类的成员变量,它的类型是ActivityThread,它代表的是应用程序的主线程。
- 通过mMainThread.getApplicationThread获得它里面的ApplicationThread成员变量,它是一个Binder对象,后面我们会看到,ActivityManagerService会使用它来和ActivityThread来进行进程间通信。
- 需注意的是,这里的mMainThread代表的是Launcher应用程序运行的进程。
- 这里的mToken也是Activity类的成员变量,它是一个Binder对象的远程接口。
public ApplicationThread getApplicationThread()
{
return mAppThread;
}
private class ApplicationThread extends ApplicationThreadNative{
}
public abstract class ApplicationThreadNative extends Binder
implements IApplicationThread {
}
public interface IApplicationThread extends IInterface {
void schedulePauseActivity();
void scheduleStopActivity();
void scheduleResumeActivity();
void scheduleDestroyActivity();
......
}
其中IInterface 接口如下:
package android.os;
/**
* Base class for Binder interfaces. When defining a new interface,
* you must derive it from IInterface.
*/
public interface IInterface
{
public IBinder asBinder();
}
其中IBinder 接口如下:
public interface IBinder {
public boolean transact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException;
}
紧接着调用:
public abstract class ActivityManagerNative extends Binder implements IActivityManager
{
/**
* Cast a Binder object into an activity manager interface, generating
* a proxy if needed.
*/
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IActivityManager in =
(IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ActivityManagerProxy(obj);
}
/**
* Retrieve the system's default/global activity manager.
*/
static public IActivityManager getDefault() {
return gDefault.get();
}
}
返回的是ActivityManagerProxy 对象:
class ActivityManagerProxy implements IActivityManager
{
public ActivityManagerProxy(IBinder remote)
{
mRemote = remote;
}
public IBinder asBinder()
{
return mRemote;
}
public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
data.writeString(callingPackage);
intent.writeToParcel(data, 0);
data.writeString(resolvedType);
data.writeStrongBinder(resultTo);
data.writeString(resultWho);
data.writeInt(requestCode);
data.writeInt(startFlags);
if (profilerInfo != null) {
data.writeInt(1);
profilerInfo.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;
}
}
关于ActivityManager家族的结构图:
通过上述代码中的mRemote.transact 与AMS进行通信,由Binder驱动程序进入到ActivityManagerService的startActivity函数:
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
......
public final int startActivity(IApplicationThread caller,
Intent intent, String resolvedType, Uri[] grantedUriPermissions,
int grantedMode, IBinder resultTo,
String resultWho, int requestCode, boolean onlyIfNeeded,
boolean debug) {
return mMainStack.startActivityMayWait(caller, intent, resolvedType,
grantedUriPermissions, grantedMode, resultTo, resultWho,
requestCode, onlyIfNeeded, debug, null, null);
}
......
}
这里只是简单地将操作转发给成员变量mMainStack的startActivityMayWait函数,这里的mMainStack的类型为ActivityStack。
public class ActivityStack {
......
final int startActivityMayWait(){}; //1、解析Intent,保存ActivityInfo;
final int startActivityLocked(){};//2、创建即将要启动的Activity的相关信息,并保存在ActivityRecord 变量中;
final int startActivityUncheckedLocked(){};//3、获得intent的标志值---activity的启动方式;
private final void startActivityLocked(ActivityRecord r, boolean newTask,
boolean doResume){};
final boolean resumeTopActivityLocked(){};//4、看要启动的Activity是否就是当前处理Resumed状态的Activity,如果是的话,那就什么都不用做,直接返回就可以了;否则再看一下系统当前是否休眠状态,如果是的话,再看看要启动的Activity是否就是当前处于堆栈顶端的Activity,如果是的话,也是什么都不用做。
private final void startPausingLocked(){};//5、prev.app.thread是一个ApplicationThread对象的远程接口,通过调用这个远程接口的schedulePauseActivity来通知Launcher进入Paused状态;
}
对参数intent的内容进行解析,得到要启动的Activity的相关信息,保存在aInfo变量中:
ActivityInfo aInfo;
try {
ResolveInfo rInfo =
AppGlobals.getPackageManager().resolveIntent(
intent, resolvedType,
PackageManager.MATCH_DEFAULT_ONLY
| ActivityManagerService.STOCK_PM_FLAGS);
aInfo = rInfo != null ? rInfo.activityInfo : null;
关于ActivityInfo:
从ActivityStack类的startPausingLocked 方法进入ApplicationThreadProxy :
class ApplicationThreadProxy implements IApplicationThread {
......
public final void schedulePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges) throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
data.writeStrongBinder(token);
data.writeInt(finished ? 1 : 0);
data.writeInt(userLeaving ? 1 :0);
data.writeInt(configChanges);
mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,
IBinder.FLAG_ONEWAY);
data.recycle();
}
......
}
这个函数通过Binder进程间通信机制进入到ApplicationThread.schedulePauseActivity函数中。
与ApplicationThread相关的类调用关系结构图:
ApplicationThread.schedulePauseActivity:
public final class ActivityThread {
......
private final class ApplicationThread extends ApplicationThreadNative {
......
public final void schedulePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges) {
queueOrSendMessage(
finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
token,
(userLeaving ? 1 : 0),
configChanges);
}
......
}
......
}
这里调用的函数queueOrSendMessage是ActivityThread类的成员函数。
public final class ActivityThread {
......
private final void queueOrSendMessage(int what, Object obj, int arg1) {
queueOrSendMessage(what, obj, arg1, 0);
}
private final void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {
synchronized (this) {
......
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
mH.sendMessage(msg);
}
}
......
}
这里首先将相关信息组装成一个msg,然后通过mH成员变量发送出去,mH的类型是H,继承于Handler类,是ActivityThread的内部类,因此,这个消息最后由H.handleMessage来处理。
public final class ActivityThread {
......
private final class H extends Handler {
......
public void handleMessage(Message msg) {
......
switch (msg.what) {
......
case PAUSE_ACTIVITY:
handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);
maybeSnapshot();
break;
......
}
......
}
......
}
ActivityThread.handlePauseActivity( ) 做了三件事:
- 如果userLeaving为true,则通过调用performUserLeavingActivity函数来调用Activity.onUserLeaveHint通知Activity,用户要离开它了;
- 调用performPauseActivity函数来调用Activity.onPause函数,我们知道,在Activity的生命周期中,当它要让位于其它的Activity时,系统就会调用它的onPause函数;
- 它通知 ActivityManagerService,这个Activity已经进入Paused状态了,ActivityManagerService现在可以完成未竟的事情,即启动MainActivity了。
class ActivityManagerProxy implements IActivityManager
{
......
public void activityPaused(IBinder token, Bundle state) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(token);
data.writeBundle(state);
mRemote.transact(ACTIVITY_PAUSED_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
reply.recycle();
}
......
}
这里通过Binder进程间通信机制就进入到ActivityManagerService.activityPaused函数中去了。
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
......
public final void activityPaused(IBinder token, Bundle icicle) {
......
final long origId = Binder.clearCallingIdentity();
mMainStack.activityPaused(token, icicle, false);
......
}
......
}
这里,又再次进入到ActivityStack类中,执行activityPaused函数。
参考致谢:
(1)、Android应用程序内部启动Activity过程(startActivity)的源代码分析
(2)、Android FrameWork——ActivityManager框架
(3)、深入理解Activity启动流程(三)–Activity启动的详细流程1
(4)、Android Activity学习笔记——Activity的启动和创建