1

I've already checked this SO post but to no avail: removeCallbacks not stopping runnable

What my app does: I have 2 imageViews. When app runs, one imageView should change it's image from sleep image to wake up image and then back to sleep image. Then handler used for delay before doing same thing for 2nd imageView. And then I want Runnable to stop. I'm using Android's frame animation. Please help!

public class MainActivity extends Activity {

    AnimationDrawable[] animDrawList;
    ImageView im;
    ImageView im2;

    private int curPos;
    private Handler mHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        animDrawList = new AnimationDrawable[2];
        curPos = 0;

        im = (ImageView)findViewById(R.id.image1);
        im2 = (ImageView)findViewById(R.id.image2);

        im.setBackgroundResource(R.drawable.animation_to_run);
        im2.setBackgroundResource(R.drawable.animation_to_run);

        animDrawList[0] = (AnimationDrawable) im.getBackground();
        animDrawList[1] = (AnimationDrawable) im2.getBackground();

        mHandler = new Handler();

        startTask();
    }

    Runnable myThread = new Runnable() {

        volatile boolean stopMe = false;

        @Override
        public void run() {

            if ( curPos <= 1 ) {
                animDrawList[curPos].start();
                curPos++;
            }
            if ( curPos > 1 ) {
                stopMe = true;
            }

            if ( stopMe ) {
                stopTask();
                return;
            }

            mHandler.postDelayed(myThread, 1000);
        }
    };

    void startTask() { myThread.run();  }

    void stopTask() { mHandler.removeCallbacks(myThread); }

}//end of MainActivity class

Here is my layout file that's straighforward :

 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="org.example.a.MainActivity">

    <ImageView
        android:id="@+id/image1"
        android:layout_width="90px"
        android:layout_height="90px"
        android:layout_alignParentStart="true"
        android:layout_marginStart="14dp"
        android:layout_marginTop="13dp" />

    <ImageView
        android:id="@+id/image2"
        android:layout_width="90px"
        android:layout_height="90px"
        android:layout_marginEnd="49dp"
        android:layout_marginBottom="93dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentEnd="true" />
</RelativeLayout>

Here is my xml file.

 <?xml version="1.0" encoding="utf-8"?>

<animation-list xmlns:android="http://schemas.android.com/apk/res/android"

    android:oneshot="false">

    <item android:drawable="@drawable/restState" android:duration="1000" />
    <item android:drawable="@drawable/upState" android:duration="1000" />
    <item android:drawable="@drawable/restState" android:duration="1000" />

</animation-list>

The app runs, no crashes, but it doesn't stop. I want the Runnable to stop after animating, why isn't my flag "stopMe" doing it's job?

UPDATE FROM JUN 4, 2017: I removed the animation code inside the run method and and added logcat output insted in run method and Runnable does stop with "stopMe" boolean so it's issue with the frame animation, is it I can't combine Android's frame animation with Runnable? I'll look into it...

Bawb
  • 31
  • 6
  • Provide your layout file, and any error logs. Also, "its not working" isn't a very useful error/problem description. – scb998 Jun 01 '17 at 06:05

2 Answers2

1

you just need to add a condition in the run method

public void run() {
  while(!stopMe)
   {
    if ( curPos <= 1 ) {
        animDrawList[curPos].start();
        curPos++;
    }
     if ( curPos > 1 ) {
        stopMe = true;
    }

    if ( stopMe ) {
        stopTask();
        return;
    }

    mHandler.postDelayed(myThread, 1000);
  }
}
Rassil
  • 11
  • 1
  • Thanks for sharing, no this only makes both imageViews animate at SAME TIME and Runnable doesn't end. – Bawb Jun 02 '17 at 02:07
1

I've solved it! I had to set the AnimationDrawable object's setOneShow(boolean playAnimationOncePerAnimationDrawableObject) to true! Voila!

Bawb
  • 31
  • 6