1
\$\begingroup\$

I have a server side operation which takes a percentage value from 0 - 100. The user controls this percentage using a SeekBar on the android client.

Time-wise the operation is expensive, so I don't want to send commands faster than the server can update. To limit the amount of actions sent, I have limited the client it to 10 calls per second by doing the following:

public class ControlPanel extends Activity {
    private SeekBar seekbar;

    private Thread updateServerThread;
    private final Runnable updateServerRunnable = new Runnable() {
        @Override
        public void run() {
            try {
                updateServer(seekbar.getProgress());
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.control_panel);

        seekbar = (SeekBar) findViewById(R.id.my_seekbar);

        seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekbar, int progress, boolean fromUser) {
                if (updateServerThread == null || !updateServerThread.isAlive()) {
                    updateServerThread = new Thread(updateServerRunnable);
                    updateServerThread.start();
                }
            }
            @Override public void onStartTrackingTouch(SeekBar seekbar) { }
            @Override public void onStopTrackingTouch(SeekBar seekbar) { }
        });
    }
    ...
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

I see several problems with your code:

  1. You're mixing server code with UI

  2. You're leaking activity reference in the Runnable

  3. Your call takes longer time than 100ms

  4. With code inside of you runnable you will miss changes to values that happened after the thread started (if it's not finished yet)

It is quite extensive to solve the first point. But all other points are quite easy to do:

  1. Make inner class static and use a static variable to be delivered to server. This is not a nice solution, since everything should be stateless but at least you will fix the memory leak. If you make a presenter or uploader class that I would always notify it about UI updates and this new class will be resposnsible about removing back pressure from network uploading

  2. I don't know if it is problem or not but I will do it a bit differently. I would create a Handler and submit Runnable to upload with delay 1 second (or your preferrable delay). And if there are changes are happening I would just reschedule the submission with same delay to later. So it will guarantee that you submit only "final" values in the delay context

  3. Will be solved by #3

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.