Shut down when the response comes back from the server, but wait for the animation to finish

I am sending a request to the server through Volley; And after sending, increase the variable showing the number of requests.

VolleyGeneral.getInstance().addToRequestQueue(jsonObj,TAG); numberOfReq++; 

Then, when I get the answer, reduce this variable.

 @Override public void onResponse(JSONObject response){ numberOfReq--; } 

On the other hand, I show the image using a fade in the animation for 2 seconds, then complete the action and move on to the next action.

But I want to wait for all server responses to complete the operation. Therefore, I write this part as follows:

 @Override public void onAnimationEnd(Animation anim){ while(numberOfReq == 0){ numberOfReq = -1; startActivity(intent); finish(); break; } } 

If the server sends responses within 2 seconds, all this is Okey.

But , if a response is received after 2 seconds, the action does not end.

+6
source share
5 answers

Perhaps I do not understand the question, because the answer seems incredibly simple. Just set the flag when the activity is "ready to complete", and then check this condition in onResponse() too.

Either onAnimationEnd() or the last onResponse() will be launched first, and the second should trigger the second action. For instance:

 private boolean mReadyToProceed; @Override public void onAnimationEnd(Animation anim) { if (numberOfReq == 0) startOtherActivityAndFinish(); else mReadyToProceed = true; } @Override public void onResponse(JSONObject response) { numberOfReq--; if (mReadyToProceed && numberOfReq == 0) startOtherActivityAndFinish(); } 

(Note: make sure that the reduction and comparison are not affected by other finish request streams, possibly with locks or with AtomicInteger ).

+3
source

You know that Volley creates and supports multiple threads, right?

Increments / contractions are not thread safe. Instead, use something like:

 AtomicInteger numberOfReq = new AtomicInteger(0); numberOfReq.incrementAndGet(); // ++ numberOfReq.decrementAndGet(); // -- 

Not sure if this is the cause of your problem, but an event, if not, is an error awaiting occurrence.

EDIT:

Setting the value of OffReq as volatile int will not solve the problem.

Volatile does not guarantee atomicity. this only ensures that the next thread for reading the variable will see its exact value after the operations performed on the previous topic.

Now the increment (and decrease) operation is actually a triple:

 a = x; b = a + 1; x = b; 

If atomicity is not forced into this calculation, for example, using AtomicInteger, nothing will stop another thread, visiting even an unstable field in the middle of such a calculation and basically get rid of the increment in the process.

+3
source

As matiash said, you can use the set onResponse () flag and you can check this value to get the desired result, or you can use broadcast receivers, which can also be an effective solution.

0
source

Why not do a check in two ways instead of one ie

If the answer comes during the animation, your onAnimationEnd () should be responsible for completing and starting a new activity.

Repeat one more round (image animation ends before answering) onResponse () should be responsible for completing work and new activity.

Ps: Regarding thread safe variables, @matiash seems to have selected enough light

0
source

You must separate the method in which you start another action. Something like that:

 private boolean animationEnded = false; @Override public void onResponse(JSONObject response){ numberOfReq--; checkStartOtherActivity(); } @Override public void onAnimationEnd(Animation anim){ animationEnded = true; checkStartOtherActivity(); } public void checkStartOtherActivity(){ if (numberOfReq == 0 && animationEnded){ startActivity(intent); finish(); } } 
0
source

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


All Articles