Optimal onEvent snooze method?

In my small application, I get a series queued onEventXXX (), from a system (not controlled by me).

Time frames for these onEventXXX () are not guaranteed. The only thing guaranteed is that they are received in the order in which they were queued.

Inside onEventXXX (), I need to start an operation (O) that I cannot start while another process (P) continues.

But I can’t just give up on this “Operation Shooting (O)”. I have to wait for this process to complete (P), and then start it.

IOW, I have to stand in line, or at least postpone this “shooting operation” until this process (P) is complete.

My immediate idea for implementing this was that instead of starting operation (O), I would:

  • Start the timer with one shot, which will periodically check the process (P)
  • When the timer expires, if the process (P) is not completed, run the time again (self).
  • When the timer expires, if the process (P) is completed, work fire (O).

But, knowing the wealth of Android, I suspect that there is a better way to do this, already built into the system / API.

If there is a better way to implement the above, what will it be?

+6
source share
3 answers

CountDownLatch would be a better solution.

I don't have a detailed example, but I think you can use it with ease.

Process looks below

  • define CountDownLatch varaiable named latch
  • set the number of latches to 1
  • When the received O event is received, create a new ThreadO. in ThreadO, wait until the number of latches reaches 0.
  • when process P ends, the countdown.

If you code like this, you can easily deal with many situations.

  • If O is received first, you can wait for the completion of P.
  • If P is received first, you can immediately start O.
  • you can use the timeout function provided by the CountDownLatch function.

I am using CountDownLatch in asyc unit test. You can see my code here: http://kingori.egloos.com/4554640

Although this doesn't sound like your business, you can get a hint from my code. Also, javadoc CountDownLatch is a good example.

+3
source

I would do it like this:

  • in onEventX, check if the process has completed, if so, take your action immediately (you can also skip this step and take only the second step)

  • otherwise, create an AsyncTask where you call Process.waitfor () in doInBackground, when that is done, do your action in onPostExecute

With this approach, you invoke the action in the user interface thread and as soon as possible.

Do not use timers for this task. A timer is a polling method. If your timer ticks too fast, you simply lose CPU time. If it is too slow, your action will be triggered with a possible delay.

+3
source

Firstly, I would suggest that if the user clicked on something, he should see some immediate result, in your case, if the button action should wait for something, add a circle loading animation to the button to immediately tell the user the action will happen soon.

Now for the action itself, if there is only one (or several) of such possible actions that occur after one (or several) possible background processes, I would add a button to raise the flag synchronously (possibly through a constant member of the class) and execute a lengthy process synchronously , to check this flag after completion of the process and perform the requested action at completion.

Another possible option, if you use wait and notify so that the button code waits for the process to complete, is usually considered a very high-performance solution in Java:

for example (ignore typos, this is in place):

button.setOnClickListener(new OnClickListener() { public void onClick(View v) { v.post(new Runnable() { @Override public void run() { synchronized (lockObject) { try { lockObject.wait(); doAction(); } catch (InterruptedException e) {} } } } } } 

Then complete the notify process when it finishes.

Note that new Runnable() does not create a new thread, it just adds Runnable to the View thread queue

As suggested by the mice, the onClick button handler should check if the process is currently running, and if it is so simple to immediately execute the action.

This way you do not need to create a new thread (or AsyncTask, which is actually a thread pool)

+2
source

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


All Articles