user1282637
user1282637

Reputation: 1867

Stopping a Handler Runnable after activity finishes

I have a method where I am making a TextView act as a "loading..." indicator.

I am doing this with a Runnable that updates the TextView every .5 seconds. Here is my function:

public void displayFlash() {
    animate = true;
    Handler handler = new Handler();
    Runnable runnable = new Runnable() {
        public void run() {
            while(animate) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                handler.post(new Runnable() {
                    public void run() {
                        System.out.println("Running");
                        numFrames++;
                        switch (numFrames % 3) {
                        case 0:
                            loading.setText("Loading.");
                            break;
                        case 1:
                            loading.setText("Loading..");
                            break;
                        case 2:
                            loading.setText("Loading...");
                            break;

                        }
                    }
                });
            }
    }
    };
    new Thread(runnable).start();
}

The problem is, after this activity is finished (and destroyed), the thread continues running. I have a System.out.println("running"); in the Runnable and this continues to log after this activity is finished. What do I need to do to kill this? I have tried handler.removeCallbacks(runnable); and Thread.interrupt(); with no luck.

Upvotes: 3

Views: 6406

Answers (2)

Gennadii Saprykin
Gennadii Saprykin

Reputation: 4573

public void displayFlash() {
    animate = true;
    final Handler handler = new Handler();
    Runnable yourRunnable = new Runnable() {
        @Override
        public void run() {
            System.out.println("Running");
            numFrames++;
            switch (numFrames % 3) {
                case 0:
                    loading.setText("Loading.");
                    break;
                case 1:
                    loading.setText("Loading..");
                    break;
                case 2:
                    loading.setText("Loading...");
                    break;
            }
            handler.postDelayed(this, 500);
        }
    }
    handler.post(yourRunnable);
}

Once you are done, call handler.removeCallbacks(yourRunnable);

Upvotes: 5

StG
StG

Reputation: 257

How abbout using an AsyncTask? It's a class bonded with the activity that lets you override 4 methods, one doing background jobs and the other 3 communicating directly with the activity. For what I know, it automatically stops working after the Activity is dismissed, but, if I am being terribly wrong about this, you can always call the AsyncTask.cancel() method to stop it in Activity.onPause() method. It is not a conventional solution, for AsyncTask is usually used for short tasks, but could work. See Android Developers for documentation if you think the class can do the hack.

Upvotes: 0

Related Questions