I'm implementing a test for some code I've written which I have
distilled down into a sample project pasted below.
The problem I am having is that the test hangs the test runner and
none of the test in my test case run.
I have tracked the problem down to a call to invalidate() in
getChildStaticTransformation(View child, Transformation t) which I am
overriding to do some scaling effects.
If I comment out the call to invalidate() then the tests run.  The
reason I'm calling invalidate() is to ensure that the view gets
redrawn after I apply the scaling effect.
If I do not call invalidate() then the view dosen't look right until a
user action forces the screen to get redrawn.

Following is the output of the Eclipse Android Console showing where
the test hangs :
[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...


Two questions :

1.  Why is invalidate() blocking the test from running?
2.  Should I be doing the scaling of my view differently that does not
require invalidate() to be called?


Below is the sample project code and test case I've written that
exhibits the problem I have described above.
HelloGallery.getChildStaticTransformation(View child, Transformation
t) is the method which has the call to invalidate().
The other files included below are for completeness incase you want to
try and build the project and observe the behavior I have described.


#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.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);
        }
}


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/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/drawable/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   ( <----  this file goes in the test
project !!)
-----------------------------
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-FILES

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to