Android测试用例执行线程和UI线程
来源:互联网 发布:荆门第四届网络作文 编辑:程序博客网 时间:2024/06/07 21:54
在做Android的AsyncTask测试的时候,发现测试用例在执行的时候是在一个名为“Instr: android.test.InstrumentationTestRunner”的线程中执行的,而activity是在main线程,个人这里也将其理解成UI线程。对此的原因做一些探究。
在Android测试工程的AndroidManifest.xml文件中,instrumentation标签的内容一般如下
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="xxxxxx" />
在进行测试的时候是通过android.test.InstrumentationTestRunner来运行的。这个类的父类是android.app.Instrumentation,也就是常说的Instrumentation类了。与Android中activity的生命周期类似,也是通过调用InstrumentationTestRunner的onCreate方法来开始测试的执行,onCreate中有下图所示的一部分代码
前面部分主要是环境解析,加载测试类和测试用例的一些操作,可以理解通过前面的操作在testSuiteBuilder中已经保存测试类和测试用例的全部信息,然后是通过getAndroidTestRunner方法获得一个运行测试用例的AndroidTestRunner对象,然后是对mTestRunner的一些设置。关键是最后的start方法的调用。这个方法是继承自android.app.Instrumentation类,代码如下图
在其中生成了一个新的InstrumentationThread线程对象,并且启动了这个线程,由于是通过android.test.InstrumentationTestRunner对象来调用此方法的,因此getClass().getName()的返回结果就是字符串"android.test.InstrumentationTestRunner",所以这个新线程名就是“Instr: android.test.InstrumentationTestRunner”。再看InstrumentationThread类的源代码,这是一个Instrumentation的内部类,如下图所示
设置线程的运行级别,然后调用onStart方法。由于是通过InstrumentationTestRunner对象进入的调用,并且在InstrumentationTestRunner中对Instrumentation的onStart方法进行了重写,所以调用的是InstrumentationTestRunner的onStart方法,所以这时对onStart方法的执行是在新生成的“Instr: android.test.InstrumentationTestRunner”线程中。onStart代码如下
@Override
public void onStart() {
prepareLooper();
if (mJustCount ) {
mResults.putString(Instrumentation. REPORT_KEY_IDENTIFIER , REPORT_VALUE_ID );
mResults.putInt( REPORT_KEY_NUM_TOTAL , mTestCount );
finish(Activity. RESULT_OK , mResults );
} else {
if (mDebug ) {
Debug. waitForDebugger();
}
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
PrintStream writer = new PrintStream(byteArrayOutputStream);
try {
StringResultPrinter resultPrinter = new StringResultPrinter(writer);
mTestRunner .addTestListener(resultPrinter);
long startTime = System.currentTimeMillis();
mTestRunner .runTest();
long runTime = System.currentTimeMillis() - startTime;
resultPrinter.print( mTestRunner .getTestResult(), runTime);
} catch (Throwable t) {
// catch all exceptions so a more verbose error message can be outputted
writer.println(String. format( "Test run aborted due to unexpected exception: %s",
t.getMessage()));
t.printStackTrace(writer);
} finally {
mResults.putString(Instrumentation. REPORT_KEY_STREAMRESULT ,
String. format( "\nTest results for %s=%s",
mTestRunner .getTestClassName(),
byteArrayOutputStream.toString()));
if (mCoverage ) {
generateCoverageReport();
}
writer.close();
finish(Activity. RESULT_OK , mResults );
}
}
}
这主要是执行测试用例,收集结果了。这也就解释了为什么测试用例执行的线程与activity运行线程不一致的了。那activity运行的线程呢?onStart方法最后调用了finish,代码如下
public void finish(int resultCode, Bundle results) {
if (mAutomaticPerformanceSnapshots ) {
endPerformanceSnapshot();
}
if (mPerfMetrics != null) {
results.putAll( mPerfMetrics );
}
mThread.finishInstrumentation(resultCode, results);
}
其中有对mThread对象的使用,这是一个ActivityThread类型的对象,是Instrumentation类的私有属性,在Instrumentation类的init方法中,有对mThread字段的赋值,并且只在这里有对mThread字段的赋值操作,猜测它就代表着activity运行所在的线程,也就是UI thread。所以反推,init方法应该在OnCreate方法调用之前。
- Android测试用例执行线程和UI线程
- Android测试用例执行线程和UI线程
- Android 普通线程里面执行UI线程
- Android UI线程和非UI线程
- Android UI线程和非UI线程
- Android UI线程和非UI线程
- Android UI线程和非UI线程
- Android UI线程和非UI线程
- Android UI线程和非UI线程
- Android UI线程和非UI线程
- Android UI线程和非UI线程
- Android UI线程和非UI线程
- Android UI线程和非UI线程
- Android UI线程和非UI线程
- Android UI线程和非UI线程
- Android UI线程和非UI线程
- Android UI线程和非UI线程
- Android UI线程和非UI线程
- Android中异步类AsyncTask的理解
- 关系型数据库基础之:聚合函数与分组
- 学习教程
- Consistent Hash
- SVN 打基线
- Android测试用例执行线程和UI线程
- linux下如何设置用户密码过期时间
- Ubuntu server 12.04 install matlab
- MFC序列化
- 黑马程序员——>第五天<面向对象(匿名对象-封装-构造代码块-this关键字)>
- android 创建webview悬浮窗口
- 更好理解贝叶斯定律(Bayes Law)和卡曼滤波器(Kalman Filter)原理
- 修改/etc/fstab文件后无法登录系统
- android199-传递序列化对象