0

I have a TimerTask that is causing my app to crash when I go to a different Intent. Here is the error:

06-06 02:45:54.884: E/AndroidRuntime(602): FATAL EXCEPTION: main
06-06 02:45:54.884: E/AndroidRuntime(602): android.database.StaleDataException: Access closed cursor
06-06 02:45:54.884: E/AndroidRuntime(602):  at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:217)
06-06 02:45:54.884: E/AndroidRuntime(602):  at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:41)
06-06 02:45:54.884: E/AndroidRuntime(602):  at com.myapp.ExerciseActivity$TickClass$1.run(ExerciseActivity.java:221)
06-06 02:45:54.884: E/AndroidRuntime(602):  at android.os.Handler.handleCallback(Handler.java:587)
06-06 02:45:54.884: E/AndroidRuntime(602):  at android.os.Handler.dispatchMessage(Handler.java:92)
06-06 02:45:54.884: E/AndroidRuntime(602):  at android.os.Looper.loop(Looper.java:123)
06-06 02:45:54.884: E/AndroidRuntime(602):  at android.app.ActivityThread.main(ActivityThread.java:3683)
06-06 02:45:54.884: E/AndroidRuntime(602):  at java.lang.reflect.Method.invokeNative(Native Method)
06-06 02:45:54.884: E/AndroidRuntime(602):  at java.lang.reflect.Method.invoke(Method.java:507)
06-06 02:45:54.884: E/AndroidRuntime(602):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
06-06 02:45:54.884: E/AndroidRuntime(602):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
06-06 02:45:54.884: E/AndroidRuntime(602):  at dalvik.system.NativeStart.main(Native Method)

Now here is the code for the TimerTask:

public class TickClass extends TimerTask
{
    private int columnIndex;

    @Override
    public void run() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (cursor != null) {
                        if (_index == 1) {
                            columnIndex = cursor.getColumnIndex(MySQLiteHelper.COLUMN_IMAGE_2);
                            _index = 2;
                        }
                        else {
                            columnIndex = cursor.getColumnIndex(MySQLiteHelper.COLUMN_IMAGE_1);
                            _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));
                    }
                }
            });
        }
}

All it does is animate a PNG.

Notice how I have added the if (cursor != null) conditional statement, which didn't fix it. I am not sure how to fix this, is it because it is running on the UI thread, so even though I've navigated away from the Activity, it is still running, but the cursor no longer exists since it is tied in with the Activity?

EDIT:

I've fixed the force close by cancel()ing the TimerTask onPause(). However, now when I return to the Activity, the image is no longer animated. Any thoughts?

scarhand
  • 4,269
  • 23
  • 63
  • 92
  • `cursor != null` just tell whether cursor has been initialized or not, closed `cursor` has nothing to do with it, you are definitely accessing a `cursor` that has been already **closed** – Muhammad Babar Jun 06 '13 at 04:42

2 Answers2

0

That's not appropriate way.

If you are used cursor as a global variable then you can used in runOnUiThread but my opinion is you have to used cursor this way.

//get the record in cursor
if(Cur.getCount()!=0){
    if(Cur.moveToFirst()){
        do{
        //here you can manipulate your record

        }while(Cur.moveToNext());

    }
}
Cur.close();

This is perfect way try and run.

Harshid
  • 5,701
  • 4
  • 37
  • 50
0

Cancelling the TimerTask in my onPause() fixed the issue.

scarhand
  • 4,269
  • 23
  • 63
  • 92