Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Only the original thread that created a view hierarchy can touch its views

I'm trying to get an ImageView to animate between 2 images in my drawable folder.

I thought everything would work fine, but the log is showing an error: Only the original thread that created a view hierarchy can touch its views.

Heres my code:

public class ExerciseActivity extends Activity {
    private ExercisesDataSource datasource;
    private Cursor cursor;
    private ImageView image_1_view;
    private Timer _timer;
    private int _index;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_exercise);     

        datasource = new ExercisesDataSource(this);
        datasource.open();

        cursor = datasource.fetchExercise(exerciseDataID);

        image_1_view = (ImageView) findViewById(R.id.exercise_image);

        _index = 1;
        _timer = new Timer();
        _timer.schedule(new TickClass(), 1000);

    }

    public class TickClass extends TimerTask
    {
        private int columnIndex;

        @Override
        public void run() {
            if (_index == 1) {
                columnIndex = cursor.getColumnIndex(MySQLiteHelper.COLUMN_IMAGE_1);
                _index = 2;
            }
            else {
                columnIndex = cursor.getColumnIndex(MySQLiteHelper.COLUMN_IMAGE_2);
                _index = 1; 
            }   

            String image_1 = cursor.getString(columnIndex);
            image_1 = image_1.replace(".png", "");
            int resourceId = getResources().getIdentifier(getPackageName() + ":drawable/" + image_1, null, null);
            image_1_view.setImageDrawable(getResources().getDrawable(resourceId));
        }
    }
}

I went ahead and set the classes and functions to public but that did not fix it.

All of the resources and everything are fine, how do I fix this error?

like image 584
scarhand Avatar asked Jan 12 '13 14:01

scarhand


2 Answers

Your code in TickClass runs on another thread. To do UI work from here use runOnUiThread. See the docu for details.

runOnUiThread(new Runnable() {
    public void run() {
        image_1_view.setImageDrawable(getResources().getDrawable(resourceId));
    }
});
like image 67
Henry Avatar answered Sep 28 '22 08:09

Henry


You should use a Handler. http://developer.android.com/reference/android/os/Handler.html

Create the handler in the onCreate. Then use the handler in with the other thread. Wrap the code in within the post and this code will be executed on the UI thread which may change the UI components.

"public final boolean post (Runnable r) Added in API level 1

Causes the Runnable r to be added to the message queue. The runnable will be run on the thread to which this handler is attached."

    handler.post( new Runnable() {

        @Override
        public void run() {
            image_1_view.setImageDrawable(getResources().getDrawable(resourceId));
        }
    });
like image 43
Nicklas Gnejs Eriksson Avatar answered Sep 28 '22 06:09

Nicklas Gnejs Eriksson