Activity具体是怎么创建的?又是怎么显示出来的?
Posted lll123
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Activity具体是怎么创建的?又是怎么显示出来的?相关的知识,希望对你有一定的参考价值。
带着这些问题往下看!!!
先来一张大概的程序调用流程图
startActivity
通常启动一个activity都是通过以下的方式:
startActivity(new Intent(this, MainActivity.class));
跟踪源码到 android.app.Activity.Java
@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
startActivityForResult(intent, -1);
}
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, null);
}
不管是调用startActivity() 还是 startActivityForResult(),最终都会调用下面的函数!
Activity#startActivityForResult
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
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) {
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
在这个方法体内,调用了 Instrumentation 的 execStartActivity() 函数!接收返回的 Instrumentation.ActivityResult 对象!
当返回对象不为空时,调用 ActivityThread 的 sendActivityResult() 用来返回结果!
Instrumentation#execStartActivity
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
// ...
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
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 。
ActivityManagerNative#getDefault().startActivity
static public IActivityManager getDefault() {
return gDefault.get();
}private static final Singleton gDefault = new Singleton() {
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;
}
};
Singletion 是系统内部提供的单例的封装类!
第一次调用get()方法时,会回调create() 创建对象,后序调用则直接返回第一次创建的对象!
从这个方法体可以明显的观察出,这是一个 AIDL 操作!
首先从ServiceManager中拿到Binder对象!
然后在 asInterface() 中进行判断,如果调用者与服务端不在同一进程,则返回代理对象!
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);
}
asInterface() 就是用于将服务端的Binder对象转换成客户端所需的AIDL接口类型的对象。如果客户端和服务端处于同一进程,则返回服务端的IActivityManager对象,否则返回代理对象。
代理对象就是ActivityManagerProxy 。
看到这里,会发现这是一个典型的AIDL模式!
只不过这里没有xxx.aidl 文件!
IActivityManager.java 就相当于编译aidl之后生成的类文件,继承 IInterface.java 这个接口!
普通aidl文件编译生成的 Ixxx.java文件中,包含两个内部类,一个是Stub,一个是Proxy!但是在这里分为两个文件!
ActivityManagerNative.java 就相当于Stub,同样是继承Binder类,实现了IActivityManager 。通Stub类一样,里面包含 asInterface(), asBinder(), onTransact() 等函数!
ActivityManagerProxy.java 相当于Proxy(从名称很明显就看的出来)。它是ActivityManagerNative 的内部类!
ActivityManagerService.java 是 ActivityManagerNative.java 的具体实现。也就是说AMS才是服务端的具体实现!
因字数限制,完整内容请点击左下角原文链接查看~~
阅读原文
大连男科检查医院 http://www.39552222.com/
大连妇科 http://www.dlfkyy.net/
以上是关于Activity具体是怎么创建的?又是怎么显示出来的?的主要内容,如果未能解决你的问题,请参考以下文章