Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is posting & cancelled a runnable on a View and Handler result in different bahviour?

I've been playing about with Runnables and have discovered that if you postDelayed a Runnable on a View then removing the callback won't work, however if you do the same but post the Runnable on a Handler then removing the callback does work.

Why does this work (Runnable run() code never gets executed):

Runnable runnable = new Runnable() {
    @Override
    public void run() {
        // execute some code
    }
};

Handler handler = new Handler();
handler.postDelayed(runnable, 10000);
handler.removeCallbacks(runnable);

where as this doesn't (Runnable run() code always gets executed)?:

Runnable runnable = new Runnable() {
    @Override
    public void run() {
        // execute some code
    }
};

View view = findViewById(R.id.some_view);
view.postDelayed(runnable, 10000);
view.removeCallbacks(runnable);
like image 282
Martyn Avatar asked Mar 19 '12 10:03

Martyn


1 Answers

If the View is not attached to a window, I can see this happening, courtesy of what looks like a bug in Android. Tactically, therefore, it may be a question of timing, making sure that you do not post or remove the Runnable until after the View is attached to the window.

If you happen to have a sample project lying around that replicates this problem, I'd like to take a look at it. Otherwise, I will try making my own, so I can have something I can use to report my presumed bug.


UPDATE

As mentioned in the comments, removeCallbacks() on more ordinary widgets works, so it appears this is a WebView-specific problem, per the OP's sample code.

like image 186
CommonsWare Avatar answered Oct 27 '22 03:10

CommonsWare