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具体是怎么创建的?又是怎么显示出来的?的主要内容,如果未能解决你的问题,请参考以下文章

有的浏览器可以显示图片有的不行,怎么回事,具体如下:

android listView底部分割线怎么显示出来

android开发中,像浏览器导航页面那样点击怎么跳转到另一个Activity页面显示出来。怎样传值和接收……

C#开发的OpenRA的游戏主界面怎么样创建

C#开发的OpenRA的游戏主界面怎么样创建

奇特:子线程的Toast怎么显示不出来?