SDK中为我们提供了非常好的对Activity进行测试的方式,那么Activity的内部机制是如何支持的呢?比如如何在Activity的生命周期变化中加入测试代码?如何监控到Activity的各种变化?如何获得Activity启动的性能参数?如何自动向Activity发送按键消息以进行测试?带着这些问题,我们要再次深入Activity源码来一探究竟。
首先想到的就是,如果要想监控到Activity生命周期的变化,必然会在Create或Start等处有代码来进行处理,所以我们把重点放在Activity那近4000行代码中与此相关的函数部分。
遗憾的是在onCreate()、onStart()等处没有发现任何有效的线索,不过不要气馁,继续向下找。
在startActivityForResult()函数中,mInstrumentation.execStartActivity()一句让我们看到至少有一个mInstrumentation的对象受委托在启动Activity,这个委托是有可能加入监控动作的。
public void startActivityForResult(Intent intent, int requestCode) {
if (mParent == null) {
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
mStartedActivity = true;
}
} else {
mParent.startActivityFromChild(this, intent, requestCode);
}
}
继续向下,在以perform开头的几个函数中,我们再次发现了对mInstrumentation对象的调用。例如performStart()函数。
final void performStart() {
mCalled = false;
mInstrumentation.callActivityOnStart(this);
if (!mCalled) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onStart()");
}
}
到此为止,我们必须得对Instrumentation类进行深入了解了,方式有二种,一是通过SDK了解该类的功能和接口,二是直接看源码。如果二种方式都用也没有问题,先通过SDK,我们知道了该类是一个基类,会在我们自己的应用程序运行之前被系统实例化,以允许我们监控所有与系统的交互(太伟大了),实现的方式是通过在AndroidManifest.xml文件中加入 <instrumentation> 标签。看来这个一定是我们想要找到的答案了,赶紧打开源码来学习一下吧。
整体上看,该类的接口主要有以下几类:对Activity监控对象的处理接口,Activity状态改变时的回调通知接口,生成Activity和Application的接口,向Activity发送事件通知的接口,性能处理的接口等。
下面我们就找几个典型的函数来看一下Instrumentation与Activity的交互机制。
先来看callActivityOnCreate()函数。
public void callActivityOnCreate(Activity activity, Bundle icicle) {
if (mWaitingActivities != null) {
synchronized (mSync) {
final int N = mWaitingActivities.size();
for (int i=0; i<N; i++) {
final ActivityWaiter aw = mWaitingActivities.get(i);
final Intent intent = aw.intent;
if (intent.filterEquals(activity.getIntent())) {
aw.activity = activity;
mMessageQueue.addIdleHandler(new ActivityGoing(aw));
}
}
}
}
activity.onCreate(icicle);
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
am.match(activity, activity, activity.getIntent());
}
}
}
}
注意activity.onCreate(icicle);这句的含义,调用了我们自己的Activity重写的onCreate()函数。
在来看我们前文提到的execStartActivity()函数。
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode) {
……// 处理ActivityMonitor
try {
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
null, 0, token, target != null ? target.mEmbeddedID : null,
requestCode, false, false);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
}
return null;
}
在这里,处理完ActivityMonitor后,真正启动一个Activity的是ActivityManagerNative.getDefault().startActivity()语句,这也符合我们的预期,真正的Activity的操作应该是由ActivityManager来完成的,当然对于ActivityManager来说,内部还有很复杂的代码和类关系,以后有时间我们再来一一拆解吧。
还有一个很重要的函数startActivitySync(),这是一个同步方式启动Activity的功能,在正常的startActivity()之后,一直进入等待状态,直到Activity运行起来该函数才返回,这样,当我们想知道一个Activity的启动性能的时候,这个是非常重要的实现。
public Activity startActivitySync(Intent intent) {
……
getTargetContext().startActivity(intent);
do {
try {
mSync.wait();
} catch (InterruptedException e) {
}
} while (mWaitingActivities.contains(aw));
……
}
余下像性能快照、事件发送等功能就留给大家自己研究了。
最后要说的是对Instrumentation的使用是要实现自己的子类的,并且为我们预留了onCreate()、onStart()等接口,在Android的测试包里也有子类的示例,可以参考。另外别忘了要在AndroidManifest.xml文件中加入 <instrumentation> 标签才行。
——欢迎转载,转载请注明出处,谢谢——
分享到:
相关推荐
12. **测试框架**:如JUnit和Espresso,源码中可以看到如何编写单元测试和UI自动化测试,确保代码质量。 通过深入学习和分析"Android程序源码--测试",开发者不仅能掌握Android开发的基本技能,还能提升问题定位和...
【标签】虽然没有具体的标签,但我们可以推断出一些关键主题:Android开发、Activity管理、动画效果、源码学习。 【压缩包子文件】中的各个部分分别代表: 1. **proguard.cfg** - 这是ProGuard配置文件,用于混淆...
此外,学习这个插件的源码也可以帮助开发者理解如何扩展IDEA的插件功能,例如如何解析注解、生成代码以及与IDE的交互等,这对于提升自身的Android开发技能和工具链使用技巧非常有帮助。 总之,`android-parcelable-...
这篇文档将深入解析《Android应用源码讯飞语音测试源码》这个项目,它是一个针对Android平台的App开发示例,特别适用于毕业设计学习。在分析这个项目时,我们将涵盖以下几个核心知识点: 1. **Android应用程序开发...
Robotium是一个基于Instrumentation的黑盒自动化测试框架,适合对Android应用进行全面的UI测试。它提供了丰富的API,模拟各种手势操作,支持对各种控件进行操作,包括Activity、Dialog、Toast和Menu。Robotium4.0...
在"Android-轻量级自动化埋点方案"中,我们可以在BaseActivity中集成自动打点的逻辑,这样每次Activity生命周期发生变化时,埋点代码都会自动执行,无需在每个具体的Activity中重复编写。 BaseActivity是所有自定义...
Android自动化测试能够显著提高测试效率,减少手动测试的工作量,并确保应用的稳定性和质量。今天我们将深入探讨一个名为Robotium的自动化测试框架,它是专门为Android应用设计的。 **Robotium简介** Robotium是一...
【Android应用源码之-app-master.rar】是一个包含Android应用程序源代码的压缩文件,它为开发者提供了深入理解Android应用开发的机会。源代码是任何软件开发的基础,对于Android应用来说也不例外。通过分析源码,...
11. **持续集成/持续部署(CI/CD)**:源码可能配置了如Jenkins、Travis CI或GitHub Actions等工具,实现自动化构建和测试。 12. **版本控制**:项目使用Git进行版本控制,你可以从源码中学习到如何使用Git进行协同...
在这个名为"Android应用源码之roboguice"的压缩包中,我们可以深入研究如何在实际项目中运用RoboGuice来提升开发效率和代码质量。 首先,RoboGuice是基于Google的Guice框架,专门为Android平台定制的版本。Guice是...
Android Studio内置的JUnit和Espresso可以帮助进行自动化测试。 11. **发布准备**:最后,打包应用前需要完成签名配置,设置版本信息,并确保应用符合Google Play的发布政策。 这个压缩包"demo-uhf_example2"可能...
9. **单元测试和自动化测试**:为了确保代码质量,应用开发过程中应包含单元测试和集成测试。AndroidJUnitRunner和Espresso库可以帮助你编写针对UI的自动化测试。 10. **版本控制和持续集成**:使用Git进行版本控制...
在Android应用开发中,Activity和Intent是两个至关重要的概念,它们构成了Android应用程序的基本交互机制。这篇笔记将深入探讨这两个核心组件以及它们之间的关联。 Activity在Android系统中扮演着视图窗口的角色,...
我们将探讨该项目的关键组件、技术栈以及如何通过源码学习Android开发。 1. **项目结构分析**: - 项目的目录结构通常遵循MVP(Model-View-Presenter)或MVVM(Model-View-ViewModel)架构,这有助于代码组织和...
源码可能包含Gradle构建脚本,用于自动化构建过程。 7. ** MVP 或 MVVM 设计模式**:现代Android开发中,为了提高可维护性和测试性,开发者可能会采用Model-View-Presenter或Model-View-ViewModel架构模式。查看...
10. **持续集成/持续部署(CI/CD)**:可能有Gradle插件配置,用于自动化构建、测试和发布流程。 11. **代码规范与风格**:通过源码,可以学习到开源项目遵循的编码规范,如Google的Android代码风格指南。 12. **...
它包含了一个完整的构建系统,支持Gradle自动化构建工具。 2. **项目结构**:在Android Studio中,贪吃蛇游戏的源码会按照标准的Android项目结构组织。主要包含以下几个部分: - `app`模块:包含所有的源代码、...
此外,Zirco-browser可能还采用了持续集成(CI)工具,如Jenkins或Travis CI,确保代码质量并自动化构建和测试过程。 总之,Zirco-browser的源码提供了一个深入了解Android浏览器开发的绝佳机会,无论是对于初学者...
【Android应用源码之MusicBox】是一个专门为IT计算机专业学生准备的毕业设计项目,它涵盖了Android平台上的移动应用开发知识,对于想要深入理解和实践Android应用开发的学生来说,这是一个宝贵的资源。这个项目主要...
### Java和Android源码设计模式解析 #### 前言:设计模式的重要性 设计模式是软件工程中的一个重要概念,它代表了一种最佳实践,能够帮助开发者解决常见的编程问题。掌握设计模式不仅能够提升代码的质量,还能提高...