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方法调用之前。
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 爬个三楼就喘了怎么办 头被篮球砸了怎么办 打球手指肿了很久怎么办 客人吃饭跑单了怎么办 脑子总是记不住东西怎么办 穿的鞋有味道怎么办 生完孩子血糖高怎么办 生了孩子子宫大怎么办 生完孩子阴吹怎么办 怀孕初期感冒嗓子发炎怎么办 脑子转不过来弯怎么办 他说我道行不深怎么办 鞋子内测磨破了怎么办 老公拉肚子拉的很厉害怎么办 老公拉肚子拉得很厉害怎么办 和老公吵架很厉害怎么办 新鞋鞋底吱吱响怎么办 新鞋鞋底滑了怎么办 工作中同事不配合怎么办 做体力活一身疼怎么办 大脑左则中动脉血管狭窄?怎么办 儿童体质差免疫力差怎么办 nba篮球大师体力不够怎么办 一千米差10秒怎么办 四十岁以后体力和耐力差怎么办 打篮球一打比赛就紧张怎么办 耐克空军鞋鞋底边胶掉了怎么办 鞋底踩到老鼠胶怎么办 头蒙怎么办最快最有效 备孕老公压力大怎么办 宝宝太兴奋不睡怎么办 我很烦只睡三小时觉怎么办才好 柯基精力太旺盛怎么办 孩子学习熬夜精力不足怎么办 肺癌晚期吃不下饭怎么办 这俩天吃药太多肝肾功能不好怎么办 跑步跑得头疼晕怎么办 吃完辣的想吐怎么办 体育生暑假训练太累怎么办 高强度运动后性功能不好怎么办 运动后第二天全身酸痛怎么办