Search code examples
androidmultithreadinglistenerseekbar

Threads in Android. HELP?


I am trying to write a new feature for a flashlight app. I am pretty sure I need a new Thread to do this. HOWEVER, I am new to Threads and do not know how to do it at all. What I am trying to do is on the change of a SeekBar, I want the strobe to get faster/ slower. If it is 0 or 1 resume to constant light.

This is wrong, but this is what I have. Whenever I move the SeekBar it correctly strobes, but you cannot make it stop..

In onCreate():

    mSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener(){
      public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
        final int myInt = progress;
        new Thread (new Runnable() {
          public void run() {
            if (myInt>1)
                strobeLight(myInt);
            else {}
                // Stop Strobe
          } }).start();
      }
      public void onStartTrackingTouch(SeekBar seekBar) {}
      public void onStopTrackingTouch(SeekBar seekBar) {}          
    });

strobeLight() method:

public void strobeLight(int myInt){
    do {
    if (myInt>1){
            if (strobe){
                processOffClick();
                try { Thread.sleep(300/myInt); }
                    catch (InterruptedException e) {}
                strobe=false; 
                strobeActivated=true;}
            else{
                processOnClick();   
                try { Thread.sleep(300/myInt); }
                    catch (InterruptedException e) {}                       
                strobe=true; }
        }
    else{
        processOnClick();
        strobe=false; 
        Thread.currentThread().interrupt(); 
        strobeActivated=false;}

    } while (strobeActivated);
} 

Solution

  • I am unsure about the need of creating a new thread every time the progress changes, a better approach might be to create a final runnable in which you change the integer value:

    onProgressChange:

        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
            toRun.interval = progress;
        }
    

    A runnable-implementation:

        class StrobeRunnable implements Runnable {
            volatile boolean running;
            volatile int interval = 0;
            private boolean lightIsOn = false;
    
            @Override
            public void run() {
                while(running){
                    if (interval > 1){
                        Thread.sleep(300/interval);
                        lightIsOn = !lightIsOn;
                        switchLight(lightIsOn);
                    }
                    else{
                        Thread.sleep(600/interval);
                        if( !lightIsOn ){
                            lightIsOn = true;
                            switchLight(lightIsOn);
                        }
                    }
                }
            }
        };
    

    Note that I created new names for some methods, switchLight(boolean isLightOn) is what I believe your processXClick did before, namely switch the light on or of. And interval used to be called myInt.

    To start a thread I prefer to use Executors:

        StrobeRunnable toRun = new StrobeRunnable();
        Executor exec = Executors.newSingleThreadExecutor();
        exec.execute(toRun);
    

    To completely stop the thread from running, set the toRun.running to false, and this will stop the running loop.

    I haven't tested this but it should work. It also depends a bit on how your processClick-method looks.