ActivityInstrumentationTestCase2问题 - 测试挂起因为代码中的invalidate()调用我正在编写测试

时间:2011-08-23 22:59:21

标签: java android testing junit instrumentation

我正在为我编写的一些代码实现测试 蒸馏成下面粘贴的示例项目。 我遇到的问题是测试挂起了测试运行器和 在我的测试用例中没有一个测试运行。

我已将问题跟踪到对invalidate()的调用 getChildStaticTransformation(查看孩子,转型t)我是谁 重写做一些缩放效果。

如果我注释掉对invalidate()的调用,则运行测试。该 我调用invalidate()的原因是为了确保视图得到 应用缩放效果后重新绘制。

如果我没有调用invalidate()那么视图看起来不正常,直到a 用户操作强制屏幕重绘。

两个问题:

  1. 为什么invalidate()阻止测试运行?
  2. 我是否应该以不同的方式对视图进行缩放 要求invalidate()被调用吗?
  3. 以下是Eclipse Android Console的输出显示位置 测试挂起:

    [2011-08-19 13:51:27 - HelloGalleryTest]
    ------------------------------
    [2011-08-19 13:51:27 - HelloGalleryTest] Android Launch!
    [2011-08-19 13:51:27 - HelloGalleryTest] adb is running normally.
    [2011-08-19 13:51:27 - HelloGalleryTest] Performing
    android.test.InstrumentationTestRunner JUnit launch
    [2011-08-19 13:51:27 - HelloGalleryTest] Automatic Target Mode: using
    device '428024642BF9457'
    [2011-08-19 13:51:27 - HelloGalleryTest] Uploading
    HelloGalleryTest.apk onto device '428024642BF9457'
    [2011-08-19 13:51:27 - HelloGalleryTest] Installing
    HelloGalleryTest.apk...
    [2011-08-19 13:51:29 - HelloGalleryTest] Success!
    [2011-08-19 13:51:29 - HelloGalleryTest] Project dependency found,
    installing: HelloGallery
    [2011-08-19 13:51:29 - HelloGallery] Uploading HelloGallery.apk onto
    device '428024642BF9457'
    [2011-08-19 13:51:29 - HelloGallery] Installing HelloGallery.apk...
    [2011-08-19 13:51:31 - HelloGallery] Success!
    [2011-08-19 13:51:31 - HelloGalleryTest] Launching instrumentation
    android.test.InstrumentationTestRunner on device 428024642BF9457
    [2011-08-19 13:51:31 - HelloGalleryTest] Collecting test information
    [2011-08-19 13:51:32 - HelloGalleryTest] Sending test information to
    Eclipse
    [2011-08-19 13:51:32 - HelloGalleryTest] Running tests...
    

    下面是我编写的示例项目代码和测试用例 表现出我上面描述的问题。 HelloGallery.getChildStaticTransformation(查看子项,转换 t)是调用invalidate()的方法。

    下面包含的其他文件是为了您想要的完整性 尝试构建项目并观察我所描述的行为。

    START :: HELLO_GALLERY_PROJECT-FILES

    HelloGallery.java

    package com.hello;
    
    import android.content.Context;
    import android.graphics.Camera;
    import android.graphics.Matrix;
    import android.util.AttributeSet;
    import android.view.View;
    import android.view.animation.Transformation;
    import android.widget.Gallery;
    
    public class HelloGallery extends Gallery {
    
           private Camera mCamera = new Camera();
    
           /**
            * The position (index) of the centered view in the gallery.
            */
           public int mCenterViewPositionIndex;
    
           public HelloGallery(Context context, AttributeSet attrs) {
                   super(context, attrs);
                   this.setStaticTransformationsEnabled(true);
           }
    
           /**
            * {@inheritDoc}
            *
            * @see #setStaticTransformationsEnabled(boolean)
            */
           protected boolean getChildStaticTransformation(View child,
    Transformation t) {
                   t.clear();
    
                   mCamera.save();
                   final Matrix imageMatrix = t.getMatrix();
                   int position = getPositionForView(child);
                   t.setTransformationType(Transformation.TYPE_MATRIX);
    
                   if (child == getSelectedView()) {
                           mCenterViewPositionIndex = position;
    
                           t.setAlpha(1f);
                           mCamera.translate(-20, 20, -200);
                   }
                   else if(((mCenterViewPositionIndex - 1) == position )) {
                           t.setAlpha(0.5f);
                           // no need to zoom this view.
                   }
                   else if((mCenterViewPositionIndex + 1) == position ) {
                           t.setAlpha(0.5f);
                           // no need to zoom this view.
                   }
    
                   else if(((mCenterViewPositionIndex - 2) == position )) {
                           t.setAlpha(0.35f);
                           mCamera.translate(0, 0, 250);
                   }
                   else if((mCenterViewPositionIndex + 2) == position ) {
                           t.setAlpha(0.35f);
                           mCamera.translate(0, 0, 250);
                   }
    
                   else if(((mCenterViewPositionIndex - 3) == position )) {
                           t.setAlpha(0.1f);
                           mCamera.translate(0, 0, 350);
                   }
                   else if((mCenterViewPositionIndex + 3) == position ) {
                           t.setAlpha(0.2f);
                           mCamera.translate(0, 0, 350);
                   }else {
                           t.setAlpha(0.1f);
                           mCamera.translate(0, 0, 450);
                   }
    
                   mCamera.getMatrix(imageMatrix);
                   mCamera.restore();
    //              invalidate();  //  <----  commenting out this line allows the Test
    to run.   Uncommenting this line will not allow the Test to run.
    
                   return true;
           }
    }
    

    HelloGalleryActivity.java

    package com.hello;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.View.OnTouchListener;
    import android.widget.AdapterView;
    import android.widget.AdapterView.OnItemClickListener;
    import android.widget.Gallery;
    
    public class HelloGalleryActivity extends Activity implements OnItemClickListener {
        private Gallery mGallery;
    
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
    
            mGallery=(Gallery)findViewById(R.id.gallery);
    
            //String array holding the values
            String [] text=new String[]{"Hello","Hi","Alloha","Bonjour","Hallo","¡Hola"};
    
            //Circular Array adapter to display our values in the gallery control
            HomeGalleryAdapter adapter = new HomeGalleryAdapter(this, R.layout.gallery_item_layout, text);
            mGallery.setAdapter(adapter);
            mGallery.setSelection(adapter.MIDDLE);
            mGallery.setOnItemClickListener(this);
            mGallery.setOnTouchListener(new OnTouchListener() {
    
                public boolean onTouch(View arg0, MotionEvent arg1) {
                    Log.d("HelloGalleryActivity", " --> onTouch");
                    return false;
                }
            });        
        }
    
        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
            Log.d("HelloGalleryActivity", " --> onItemClick");  
        }
    }
    

    HelloGalleryAdapter.java

    package com.hello;
    
    import android.app.Activity;
    import android.content.Context;
    import android.graphics.Color;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ArrayAdapter;
    import android.widget.TextView;
    
    public class HomeGalleryAdapter extends ArrayAdapter<String> {
           private LayoutInflater mLayoutInflater;
           private TextView mText;
           private int mLayoutId;
    
           public static final int HALF_MAX_VALUE = Integer.MAX_VALUE/2;
       public final int MIDDLE;
       private String[] mObjects;
    
           public HomeGalleryAdapter(Context context, int layoutId, String[]
    lables) {
                   super(context, 0, lables);
    
                   mLayoutInflater = ((Activity) context).getLayoutInflater();
                   mLayoutId = layoutId;
    
               mObjects = lables;
               MIDDLE = HALF_MAX_VALUE - HALF_MAX_VALUE % lables.length;
           }
    
           public int getCount() {
                   return Integer.MAX_VALUE;
           }
    
           public String getItem(int position) {
                   return mObjects[position % mObjects.length];
           }
    
           public long getItemId(int position) {
                   return position % mObjects.length;
           }
    
           public View getView(int position, View convertView, ViewGroup group)
    {
                   if (convertView == null) {
                           convertView = mLayoutInflater.inflate(mLayoutId, group, false);
                   }
    
                   mText = (TextView) convertView.findViewById(R.id.gallery_item_text);
    
                   mText.setText((String) getItem(position));
                   mText.setTextColor(Color.WHITE);
    
                   convertView.setTag(mText.getText());
    
                   return convertView;
           }
    }
    

    RES /布局/ main.xml中

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
           xmlns:android="http://schemas.android.com/apk/res/android"
           android:orientation="vertical"
           android:layout_width="fill_parent"
           android:layout_height="fill_parent">
    
           <TextView
                   android:id="@+id/textview"
                   android:layout_width="fill_parent"
                   android:layout_height="wrap_content"
                   android:text="@string/hello" />
    
           <com.hello.HelloGallery
                   android:id="@+id/gallery"
                   android:layout_gravity="center"
                   android:spacing="0dp"
                   android:layout_width="fill_parent"
                   android:layout_height="fill_parent" />
    </LinearLayout>
    

    RES /布局/ gallery_item_layout.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
           xmlns:android="http://schemas.android.com/apk/res/android"
           android:id="@+id/home_gallery_item_layout"
           android:orientation="vertical"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:layout_gravity="center">
    
           <RelativeLayout
                   android:id="@+id/gallery_item_background"
                   android:layout_width="100dip"
                   android:layout_height="100dip"
                   android:orientation="horizontal"
                   android:background="@drawable/gallery_item_selector">
    
                   <ImageView
                           android:src="@drawable/icon"
                           android:id="@+id/gallery_item_icon"
                           android:layout_width="wrap_content"
                           android:layout_height="wrap_content"
                           android:layout_centerInParent="true" />
    
           </RelativeLayout>
    
           <TextView
                   android:id="@+id/gallery_item_text"
                   android:layout_width="wrap_content"
                   android:layout_height="wrap_content"
                   android:layout_gravity="center"
                   android:textSize="20sp" />
    </LinearLayout>
    

    RES /抽拉/ gallery_item_selector.xml

     <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_pressed="true"
              android:drawable="@drawable/background_selected" /> <!--
    pressed -->
        <item android:drawable="@drawable/background_normal" /> <!--
    default -->
     </selector>
    

    RES /抽拉/ background_normal.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
       <gradient
           android:startColor="#80000000"
           android:endColor="#80FFFFFF"
           android:angle="45"/>
       <padding android:left="7dp"
           android:top="7dp"
           android:right="7dp"
           android:bottom="7dp" />
       <corners android:radius="8dp" />
    </shape>
    

    RES /抽拉/ background_selected.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
       <gradient
           android:startColor="#80000000"
           android:endColor="#807EB6FF"
           android:angle="45"/>
       <padding android:left="7dp"
           android:top="7dp"
           android:right="7dp"
           android:bottom="7dp" />
       <corners android:radius="8dp" />
    </shape>
    

    的AndroidManifest.xml

    <?xml version="1.0" encoding="utf-8"?>
    <manifest
           xmlns:android="http://schemas.android.com/apk/res/android"
           package="com.hello"
           android:versionCode="1"
           android:versionName="1.0">
           <uses-sdk
                   android:minSdkVersion="7" />
    
           <application
                   android:icon="@drawable/icon"
                   android:label="@string/app_name">
                   <activity
                           android:name=".HelloGalleryActivity"
                           android:label="@string/app_name">
                           <intent-filter>
                                   <action
                                           android:name="android.intent.action.MAIN" />
                                   <category
                                           android:name="android.intent.category.LAUNCHER" />
                           </intent-filter>
                   </activity>
    
           </application>
    </manifest>
    

    END :: HELLO_GALLERY_PROJECT-FILES

    START :: HELLO_GALLERY_TEST_PROJECT-FILES

    HelloGalleryActivityTest.java(&lt; ----此文件进入测试项目!!)

    package com.hello.test;
    
    import android.test.ActivityInstrumentationTestCase2;
    import android.widget.Gallery;
    import android.widget.SpinnerAdapter;
    
    import com.hello.HelloGalleryActivity;
    
    public class HelloGalleryActivityTest extends
    ActivityInstrumentationTestCase2<HelloGalleryActivity> {
           private HelloGalleryActivity mActivity; // the activity under test
           private Gallery mGallery;
           private String[] mGalleryDataTestArray;
           private SpinnerAdapter mGalleryData;
    
           public HelloGalleryActivityTest() {
                   super("com.hello", HelloGalleryActivity.class);
                   mGalleryDataTestArray = new String[] { "Hello", "Hi", "Alloha",
    "Bonjour", "Hallo", "¡Hola" };
           }
    
           @Override
           protected void setUp() throws Exception {
                   super.setUp();
                   setActivityInitialTouchMode(false);
    
                   mActivity = this.getActivity();
                   mGallery = (Gallery) mActivity.findViewById(com.hello.R.id.gallery);
                   mGalleryData = (SpinnerAdapter) mGallery.getAdapter();
           }
    
           public void testPreconditions() {
                   assertNotNull(mActivity);
                   assertNotNull(mGallery);
                   assertNotNull(mGallery.getOnItemClickListener());
                   assertNotNull(mGalleryData);
           }
    
           public void testInitialGalleryPosition() {
                   int position = mGallery.getSelectedItemPosition();
                   String galleryItemLabel = (String)
    mGallery.getItemAtPosition(position);
    
                   assertEquals(mGalleryDataTestArray[0], galleryItemLabel);
           }
    }
    

    的AndroidManifest.xml

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.hello.test"
         android:versionCode="1"
         android:versionName="1.0">
       <uses-sdk android:minSdkVersion="12" />
       <instrumentation android:targetPackage="com.hello"
    android:name="android.test.InstrumentationTestRunner" />
       <application android:icon="@drawable/icon" android:label="@string/
    app_name">
    
       <uses-library android:name="android.test.runner" />
       </application>
    </manifest>
    

    END :: HELLO_GALLERY_TEST_PROJECT-FILE

2 个答案:

答案 0 :(得分:0)

尝试postInvalidate()而不是invalidate()。

我不是100%确定发生了什么,但我怀疑你的代码中存在阻止UI线程的内容。使用postInvalidate()将立即返回并让您的代码完成,这将取消阻止UI线程。

答案 1 :(得分:0)

问题解决了!

不需要无效调用..它会使事情变得紧张!

诀窍是向HelloGallery.java添加一个方法来设置中心位置并在超类上调用setPosition。

<强> HelloGallery.java

public void setSelectionToCenter(int position) {
    mCenterViewPositionIndex = position;
    setSelection(mCenterViewPositionIndex);
}

然后在HelloGalleryActivity中调用setSelectionToCenter方法而不是setSelection。

<强> HelloGalleryActivity

public void onCreate(Bundle savedInstanceState) {
    ...
    ((HelloGallery)mGallery).setSelectionToCenter(adapter.MIDDLE);
    ...
}

现在,测试就像一个魅力!活泉!
感谢神秘开发人员Betsy为我追踪这个!