我是靠谱客的博主 着急寒风,最近开发中收集的这篇文章主要介绍说明android应用开发过程,Android应用开发之Android Activity的启动过程源码解析,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

本文将带你了解Android应用开发Android Activity的启动过程源码解析,希望本文对大家学Android有所帮助。

前言

Activity是Android中一个很重要的概念,堪称四大组件之首,关于Activity有很多内容,比如生命周期和启动Flags,这二者想要说清楚,恐怕又要写两篇长文,更何况分析它们的源码呢。不过本文的侧重点不是它们,我要介绍的是一个Activity典型的启动过程,本文会从源码的角度对其进行分析。我们知道,当startActivity被调用的时候,可以启动一个Activity,但是你知道这个Activity是如何被启动的吗?每个Activity也是一个对象,你知道这个对象是啥时候被创建的吗(也就是说它的构造方法是什么时候被调用的)?为什么onCreate是Activity的执行入口?所有的这一切都被系统封装好了,对我们来说是透明的,我们使用的时候仅仅是传递一个intent然后startActivity就可以达到目的了,不过,阅读了本文以后,你将会了解它的背后到底做了哪些事情。在分析之前,我先介绍几个类:

Activity:这个大家都熟悉,startActivity方法的真正实现在Activity中

Instrumentation:用来辅助Activity完成启动Activity的过程

ActivityThread(包含ApplicationThread + ApplicationThreadNative   +   IApplicationThread):真正启动Activity的实现都在这里

源码分析

首先看入口

code:Activity#startActivity

@Override

public void startActivity(Intent intent) {

startActivity(intent, null);

}

@Override

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);

}

}

public void startActivityForResult(Intent intent, int requestCode) {

startActivityForResult(intent, requestCode,   null);

}

说明:显然,从上往下,最终都是由startActivityForResult来实现的

接着看

code:Activity#startActivityForResult

public void startActivityForResult(Intent intent, int requestCode, Bundle options) {

//一般的Activity其mParent为null,mParent常用在ActivityGroup中,ActivityGroup已废弃

if (mParent == null)   {

//这里会启动新的Activity,核心功能都在mMainThread.getApplicationThread()中完成

Instrumentation.ActivityResult ar =

mInstrumentation.execStartActivity(

this, mMainThread.getApplicationThread(), mToken,   this,

intent, requestCode, options);

if (ar   != null)   {

//发送结果,即onActivityResult会被调用

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;

}

final View decor = mWindow != null ?   mWindow.peekDecorView() : null;

if (decor != null)   {

decor.cancelPendingInputEvents();

}

// TODO Consider clearing/flushing other event sources and   events for child windows.

} else {

//在ActivityGroup内部的Activity调用startActivity的时候会走到这里,内部处理逻辑和上面是类似的

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);

}

}

}

说明:上述代码关键点都有注释了,可以发现,真正打开activity的实现在Instrumentation的execStartActivity方法中,去看看

code:Instrumentation#execStartActivity

public ActivityResult execStartActivity(

Context who, IBinder contextThread, IBinder token, Activity   target,

Intent intent, int requestCode, Bundle options) {

//核心功能在这个whoThread中完成,其内部scheduleLaunchActivity方法用于完成activity的打开

IApplicationThread whoThread = (IApplicationThread)   contextThread;

if (mActivityMonitors != null)   {

synchronized (mSync) {

//先查找一遍看是否存在这个activity

final int N = mActivityMonitors.size();

for (int i=0;   i

final ActivityMonitor am =   mActivityMonitors.get(i);

if (am.match(who, null,   intent)) {

//如果找到了就跳出循环

am.mHits++;

//如果目标activity无法打开,直接return

if (am.isBlocking()) {

return requestCode >= 0 ? am.getResult() : null;

}

break;

}

}

}

}

try {

intent.migrateExtraStreamToClipData();

intent.prepareToLeaveProcess();

//这里才是真正打开activity的地方,核心功能在whoThread中完成。

int result = ActivityManagerNative.getDefault()

.startActivity(whoThread,   who.getBasePackageName(), intent,

intent.resolveTypeIfNeeded(who.getContentResolver()),

token, target != null ? target.mEmbeddedID : null,

requestCode, 0, null,   null, options);

//这个方法是专门抛异常的,它会对结果进行检查,如果无法打开activity,

//则抛出诸如ActivityNotFoundException类似的各种异常

checkStartActivityResult(result, intent);

} catch   (RemoteException e) {

}

return null;

}

说明:我想再说一下这个方法checkStartActivityResult,它也专业抛异常的,看代码,相信大家对下面的异常信息不陌生吧,就是它干的,其中最熟悉的非Unable

to find explicit activity   class莫属了,如果你在xml中没有注册目标activity,此异常将会抛出。

/*package*/ static void checkStartActivityResult(int res, Object intent) {

if (res >= ActivityManager.START_SUCCESS) {

return;

}

switch (res) {

case ActivityManager.START_INTENT_NOT_RESOLVED:

case ActivityManager.START_CLASS_NOT_FOUND:

if (intent instanceof   Intent &&   ((Intent)intent).getComponent() != null)

throw new ActivityNotFoundException(

"Unable to find explicit activity class   "

+   ((Intent)intent).getComponent().toShortString()

+ "; have you declared this activity in your   AndroidManifest.xml?");

throw new ActivityNotFoundException(

"No Activity found to handle   " + intent);

case ActivityManager.START_PERMISSION_DENIED:

throw new SecurityException("Not allowed to start activity   "

+ intent);

case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:

throw new AndroidRuntimeException(

"FORWARD_RESULT_FLAG used while also   requesting a result");

case ActivityManager.START_NOT_ACTIVITY:

throw new IllegalArgumentException(

"PendingIntent is not an   activity");

default:

throw new AndroidRuntimeException("Unknown error code   "

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之Android频道!

最后

以上就是着急寒风为你收集整理的说明android应用开发过程,Android应用开发之Android Activity的启动过程源码解析的全部内容,希望文章能够帮你解决说明android应用开发过程,Android应用开发之Android Activity的启动过程源码解析所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部