Why publish and cancel launch in View and Handler in different versions of bahviour?

I played with Runnable and found that if you postDelayed a Runnable on View , then deleting the callback will not work, however if you do the same but place Runnable on a Handler then deleting the callback really works.

Why is this work ( Runnable run () never starts):

 Runnable runnable = new Runnable() { @Override public void run() { // execute some code } }; Handler handler = new Handler(); handler.postDelayed(runnable, 10000); handler.removeCallbacks(runnable); 

where it does not execute ( Runnable run () code always executes) ?:

 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); 
+6
source share
3 answers

If the View not tied to the window, I see this happening, kindly provided what looks like an error in Android. Thus, this can be a matter of time, so you do not send or remove Runnable until after that, the View is attached to the window.

If you have a sample project lying around that replicates this problem, I would like to take a look at it. Otherwise, I will try to make my own, so that I can have something that I can use to report my alleged error.


UPDATE

As mentioned in the comments, removeCallbacks() for more ordinary widgets works, so it seems that this is a WebView specific problem, modeled on OP code.

+4
source

For various reasons, the View handler (view.getHandler ()) may not be ready if you want to start the animation.

Therefore, you should probably wait before assigning a runnable to your mind.

Assuming you're trying to do this from within an Activity, here is the code that expects the handler to be available before the runnable is published:

 private void assignRunnable(final View view, final Runnable runnable, final int delay) { if (view.getHandler() == null) { // View is not ready, postpone assignment this.getView().postDelayed(new Runnable() { @Override public void run() { assignRunnable(view, runnable, delay); } }, 100); //Abort return; } //View is ready, assign the runnable view.postDelayed(runnable, delay); } 
0
source

Looking at ViewRootImpl.java , the semantics of View.removeCallbacks () seem obscure, to say the least.

RunQueue.removeCallbacks simply removes Runnables from the ArrayList. See here .

If RunQueue.executeActions is called before removeCallbacks, then the ArrayList is cleared in all cases, making removeCallbacks no-op. See here .

RunQueue.executeActions is called for each crawl .... See here .

Therefore, if I do not miss something, View.removeCallbacks will not work if the crawl has occurred since you called View.post .

I will stick with @ james-wald comment above and not use View.post

0
source

Source: https://habr.com/ru/post/911083/


All Articles