4

I am using android.os.Handler's “postDelayed” method to turn ON and OFF a relay. There are 2 runnable - one for sending ON command and another for sending OFF command. The relay needs to be kept on for fixed ms and turned OFF for fixed ms again.

I referred this old android post http://android-developers.blogspot.in/2007/11/stitch-in-time.html to send repeating commands to the relay

The start command needs to be sent at the same time from different devices - each connected to a different relay. So the effect should be that all relays should turn ON at the same time.

I ensure that the command is sent at the same time from each device, using GPS time sync on all devices. Once all devices are GPS time synced, I send ON command at start of second for the first time and then add the fixed delays to the postDelay methods in both runnables.

I still notice that the relays are not turned ON at the same time the first time itself. I notice a delay upto 1 sec.

I need to know how reliable is "postDelayed" method? Can I trust it for a precision upto 5 ms? Is there a more reliable way to send a repeating command at a fixed delay?

Here is part of the code

public class RelayAsyncTask extends AsyncTask<Void, Integer, Boolean>
    {
        private Activity context = null;
        private Handler handler = null;
        private Runnable offRunnable,onRunnable;


        @Override
        protected void onPreExecute() 
        {
            handler = new Handler();
            onRunnable = new Runnable() {
                               
                                @Override
                                 public void run() {
                                               new RelayTurnOnAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null);
                                               publishProgress(1);  // used to display on UI that a command has been sent
                                               handler.postDelayed(offRunnable, 500);
                                      
                                }
                        };

            offRunnable = new Runnable() {
                               
                                @Override
                                public void run() {
                                               new RelayTurnOffAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null);
                                               publishProgress(2);  // used to display on UI that a command has been sent
                                               handler.postDelayed(onRunnable, 1000);
                                                
                                       
                                }
                         };
            super.onPreExecute();
        }


        @Override
        protected Boolean doInBackground(Void... params) {
            try {
                // Code to calculate diff when first ON command should be sent
                .
                .
                handler.postDelayed(onRunnable, diff);

            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            switch (values[0]) {
            case 0:
            {
                break;
            }
            case 1:
            {   //code to update UI
                .
                .
                break;
            }
            case 2:
            {   //code to update UI
                .               .
                .
                break;
            }
            default:
                break;
            }

        }


        @Override
        protected void onPostExecute(Boolean result) {
            super.onPostExecute(result);
        }
    }   

I also notice a delay upto 10 ms when RelayTurnOnAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null) is called.

random
  • 10,238
  • 8
  • 57
  • 101

1 Answers1

0

Try doing it directly without asynctask.

I mean if all you do in doInBackground is call postDelayed then you can do it directly on UI thread and inside handler runnable instead of publishProgress directly set progress.

vipul mittal
  • 17,343
  • 3
  • 41
  • 44
  • I am also calculating difference and start of sec besides just calling the postDelayed method inside doInBackground. I don't think calling postDelayed from UI thread will improve performance. – random Jul 30 '14 at 08:41
  • Also if I remove asynctask, and send relay command on UI thread, UI will hang if relay gets unresponsive for even a few ms. – random Jul 30 '14 at 08:50