1

I am building an Android application and attempting to implement a slideshow through using the timer class. The first image loads fine and then my app crashes. Any idea what the issue might be?

import android.app.Service;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.IBinder;
import android.service.dreams.DreamService;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.widget.ImageView;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

public class screenSaver extends DreamService {
    ArrayList<Bitmap> imageList = new ArrayList<Bitmap>();
    int slideCounter = 0;
    ImageView slide;
    Cursor images;
    private int counter = 0;
    public screenSaver() {

    }

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        setInteractive(false);
        setFullscreen(true);
        setContentView(R.layout.screen_saver);
        databaseHelper dbHelper = new databaseHelper(this);
        SQLiteDatabase db = dbHelper.getReadableDatabase();
       images = db.rawQuery("SELECT " + databaseHelper.IMAGE + " FROM " + databaseHelper.TABLE_NAME + " where " + databaseHelper.LTO + " = 1", null);
        images.moveToFirst();

        while(!images.isAfterLast()) {
            imageList.add(BitmapFactory.decodeByteArray(images.getBlob(images.getColumnIndex(databaseHelper.IMAGE)), 0, images.getBlob(images.getColumnIndex(databaseHelper.IMAGE)).length ));
            images.moveToNext();
        }


        }




    @Override
    public void onDreamingStarted() {

        slide = (ImageView) findViewById(R.id.slider);
        class flipper extends TimerTask {

            @Override
            public void run() {

                slide.setImageBitmap(imageList.get(counter));
                if(counter == (imageList.size())) {
                    counter = 0;
                } else {
                    counter++;
                }

            }


        }
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new flipper(), 0, 5000);


    }
}

I have been struggling with this for quite some time so I really, really appreciate any guidance.

Thanks so much!

EDIT: Error

  Process: midamcorp.com.burgerkingapp, PID: 2126
                                                                           android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
                                                                               at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6556)
                                                                               at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:942)
                                                                               at android.view.ViewGroup.invalidateChild(ViewGroup.java:5081)
                                                                               at android.view.View.invalidateInternal(View.java:12713)
                                                                               at android.view.View.invalidate(View.java:12677)
                                                                               at android.view.View.invalidate(View.java:12661)
                                                                               at android.widget.ImageView.invalidateDrawable(ImageView.java:246)
                                                                               at android.graphics.drawable.Drawable.invalidateSelf(Drawable.java:385)
                                                                               at android.graphics.drawable.Drawable.setBounds(Drawable.java:165)
                                                                               at android.widget.ImageView.configureBounds(ImageView.java:1116)
                                                                               at android.widget.ImageView.updateDrawable(ImageView.java:898)
                                                                               at android.widget.ImageView.setImageDrawable(ImageView.java:472)
                                                                               at android.widget.ImageView.setImageBitmap(ImageView.java:605)
                                                                               at midamcorp.com.burgerkingapp.MainActivity$1flipper.run(MainActivity.java:48)
                                                                               at java.util.Timer$TimerImpl.run(Timer.java:284)
KellyM
  • 2,472
  • 6
  • 46
  • 90
  • Post the Logcat message please. – T D Nguyen Apr 14 '16 at 21:27
  • Unfortunately, that is one of the major obstacles for me. Since this is a Service instead of an Activity, I cannot figure out how to test it on the emulator and I do not have a device to debug with (I could not find an adb bridge for my tablet). – KellyM Apr 14 '16 at 21:32
  • Have you try this: http://stackoverflow.com/questions/4008081/debugging-a-service – T D Nguyen Apr 14 '16 at 21:34
  • I could not get the service to work right; however, I tested the code in an activity and have added the error output above. Thanks! – KellyM Apr 14 '16 at 21:57

1 Answers1

5

From the debug message, the error is caused by the thread as it is not in the same thread with the UI.

slide.setImageBitmap(imageList.get(counter));

Possible solutions are to use Handler or runOnUIThread

Community
  • 1
  • 1
T D Nguyen
  • 7,054
  • 4
  • 51
  • 71
  • 3
    You will need to use `Handler.postDelayed` to take the delay into account. I'm not sure `runOnUIThread` supports delays. You can call `postDelayed` again from your Runnable to call your code periodically. – mbonnin Apr 14 '16 at 22:17
  • Thank you both so much! I am not in a position to test the code at the moment, but just to make I get the general idea, would something like this work: handler = new Handler(Looper.getMainLooper()); handler.postDelayed(flipper, 5000)? Thanks again! – KellyM Apr 15 '16 at 01:57