ActivityInstrumentationTestCase2-Probleme - Test hängt wegen des Aufrufs von invalidate () im Code, für den ich einen Test schreibe

  • Ich implementiere einen Test für einen Code, den ich geschrieben habe, und den ich in ein Beispielprojekt destilliert habe. Das Problem, das ich habe, ist, dass der Test hängt der Testläufer und keiner der Tests in meinem Testfall.

    Ich habe das Problem bis zu einem Aufruf von invalidate () in getChildStaticTransformation (View.) verfolgt Kind, Transformation t), das ich überschreibe, um Skalierungseffekte auszuführen.

    Wenn ich den Aufruf von invalidate () auskommentiere, werden die Tests ausgeführt. Der Grund, warum ich invalidate () anrufe, soll sicherstellen, dass die Ansicht nach dem Anwenden des Skalierungseffekts neu gezeichnet wird.

    Wenn ich invalidate nicht anrufe ( ) Die Ansicht sieht dann nicht richtig aus, bis eine Benutzeraktion den Bildschirm zwingt, neu gezeichnet zu werden.

    Zwei Fragen:

    1. Warum wird der Test durch invalidate () blockiert?
    2. Sollte ich die Skalierung meiner Ansicht anders machen als dies nicht der Fall ist verlangen, dass invalidate () aufgerufen wird?

    Im Folgenden ist die Ausgabe der Eclipse-Android-Konsole angegeben, wo der Test hängt:

     [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...
     

    Nachfolgend finden Sie den Beispiel-Projektcode und den Testfall, den ich geschrieben habe, dass das beschriebene Problem aufweist oben. HelloGallery.getChildStaticTransformation (View child, Transformation t) ist die Methode, die den Aufruf von invalidate () enthält.

    Die folgenden Dateien sind für Vollständigkeit, wenn Sie versuchen möchten, das Projekt zu erstellen und das Verhalten zu beobachten, das ich ha habe Wie beschrieben.

    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 / layout / 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 / layout / 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 / drawable / 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 / drawable / bac

    24 August 2011
    Akos Cz
2 answers
  • Versuchen Sie postInvalidate () anstelle von invalidate ().

    Ich bin nicht zu 100% sicher, was los ist, aber ich vermute, dass etwas in Ihrem Code den UI-Thread blockiert. Wenn Sie postInvalidate () verwenden, wird der Code sofort beendet und der UI-Thread freigegeben.

    28 September 2011
    Emmanuel
  • Problem gelöst!

    Der Aufruf zum Annullieren ist NICHT erforderlich. Er macht alles in Ordnung, PERIOD!

    Die Der Trick bestand darin, HelloGallery.java eine Methode hinzuzufügen, um die Mittelposition festzulegen und setPosition für die Superklasse aufzurufen.

    HelloGallery.java

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

    Rufen Sie dann in HelloGalleryActivity die setSelectionToCenter-Methode anstatt setSelection auf.

    HelloGalleryActivity

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

    Der Test läuft jetzt wie ein Zauber! Woot!
    Danke an Betsy, den Mystery-Entwickler, der das für mich ausfindig gemacht hat!

    18 February 2012
    Akos Cz