title: Android: Synchronizing Threads and Handler
body: <p>I am having some trouble with my App. I'm very new to Android development so i hope it's an easy mistake.
  So I'm trying to write an app that gets some raw data via Wifi(first Thread), do some calculations(second Thread), create a Bitmap out of the calculated Data(third Thread) and update the Display(Handler).
  Some Parameters are adjusted by SeekBars. Everything works fine. But sometimes when I change the seekBarValues the Picture isn't updated Anymore. the Threads and the Handler are still running so i dont't get an Error.</p>
  
  <p>Here some Code:</p>
  
  <p>MainActivity:</p>
  
  <pre><code>public class MainActivity extends Activity implements OnClickListener {
      private Handler outputHandler = new Handler();
      private SeekBar  seekBarBrightness,
      seekBarContrast,
      seekBarGamma;
  
      public static volatile double gamma = 1;
      public static volatile double brightness = 500;
      public static volatile double contrast = 500; 
      public static volatile double min = 0;
      public static volatile double max = 0;
  
      public static volatile boolean isRunning = false;
  
      public static volatile int r = 0;
      public static volatile int g = 0;
      public static volatile int b = 0;
      public static volatile int width = 400;
      public static volatile int height = 250;
  
      public volatile double inputExchangeFrame[][ ]= new double[400][250], outputExchangeFrame[][]= new double[400][250];
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
  
  
          seekBarBrightness = (SeekBar) findViewById(R.id.seekBarBrightness); 
          seekBarContrast = (SeekBar) findViewById(R.id.seekBarContrast);
          SeekBarGamma = (SeekBar) findViewById(R.id.seekBarGamma);
  
          newImage = Bitmap.createBitmap(width, height, BitmapConfig.ARGB_8888);              
          picture.setImageBitmap(newImage);
  
  
      }    
  
      @Override   
      public void onClick(View v) { 
          if(v==toggleButtonStartStop){
              if(toggleButtonStartStop.isChecked()==true){ 
                  isRunning=true; 
                  getFrame();
                  calculateFrame();
                  showFrame();
              }
              else{ 
                  isRunning = false;
              }
          }
      }            
  }
  </code></pre>
  
  <p>And the Other Methods declared also in MainACtivity:
  getFrame():</p>
  
  <pre><code>private synchronized void getFrame(){
       inputThread = new Runnable(){
            public void run(){
                 while(isRunning == true){
  
                     //inputFrame fron WIFI
  
                      inputExchangeFrameLock.lock();
                      //synchronized(inputExchangeFrame){
                           for(int x_1=0 ; x_1&lt;width ; x_1++){
                                for(int y_1=0 ; y_1&lt;height ; y_1++){
                                     inputExchangeFrame[x_1][y_1]=inputFrame[x_1][y_1];
                                }
                           }
                      //}
                     inputExchangeFrameLock.unlock();
  
                     try {                        
                          Thread.sleep(120);
                     } 
                     catch (InterruptedException e) {
                          e.printStackTrace();
                     }
                }
           }
       };new Thread(inputThread).start();
  };
  </code></pre>
  
  <p>calculateFrame:</p>
  
  <pre><code>private synchronized void calculateFrame(){
       calculationThread = new Runnable(){
            public void run(){
                 while(isRunning == true){    
                 //get Data from InputThread to applicate several Filter
                 inputExchangeFrameLock.lock();
                 //synchronized(inputExchangeFrame){
                      for(int x_2=0 ; x_2&lt;width ; x_2++){
                           for(int y_2=0 ; y_2&lt;height ; y_2++){
                                calculationFrame[x_2][y_2]=inputExchangeFrame[x_2][y_2];
                           }
                      }
                 //}
                 inputExchangeFrameLock.unlock();
  
                   //Do some calculations on calculationFrame  
  
                 outputExchangeFrameLock.lock();
                 //synchronized(outputExchangeFrame){ 
                      for(int x_3=0 ; x_3&lt;width ; x_3++){
                           for(int y_3=0 ; y_3&lt;height ; y_3++){
                                outputExchangeFrame[x_3][y_3] = calculationFrame[x_3][y_3];
                           }
                      }
                 //}
                 outputExchangeFrameLock.unlock();
                 }
            }
       }; new Thread(calculationThread).start();
  };
  </code></pre>
  
  <p>showFrame():</p>
  
  <pre><code>private synchronized void showFrame(){
       outputThread = new Runnable(){
            public void 
                 while(isRunning == true){
                      contrast =  seekBarContrast.getProgress() +1;
                      brightness = seekBarBrightness.getProgress() + 1;
                      gamma = seekBarGamma.getProgress() + 1;
  
                      outputExchangeFrameLock.lock();
                      //synchronized(outputExchangeFrame){
                      for(int x_4=0 ; x_4&lt;width ; x_4++){
                           for(int y_4=0 ; y_4&lt;height ; y_4++){
                                outputFrame[x_4][y_4] = outputExchangeFrame[x_4][y_4];
                            }
                       }  
                       //}
                       outputExchangeFrameLock.unlock();
  
                       for (int x_14=0 ; x_14&lt;width ; x_14++){
                            for(int y_14=0; y_14&lt;height; y_14++){
  
                               //Calculation of r,g,b  using gamma, brightness and contrast
                            }
                            synchronized(newImage){
                                 newImage.setPixel(x_14, y_14, Color.rgb(r,g,b));
                            }
                       }
  
                       outputHandler.removeCallbacks(pictureUpdate);
                       outputHandler.post(pictureUpdate);
  
                       try {
                            Thread.sleep(50);
                       } 
                       catch (InterruptedException e) {
                            e.printStackTrace();
                       }
                  }
             }
       }; new Thread(outputThread).start();   
  };
  </code></pre>
  
  <p>and the Handler:</p>
  
  <blockquote>
    <p>private Runnable pictureUpdate = new Runnable(){<br>
         public void run(){
    synchronized(newImage){ 
    picture.setImageBitmap(newImage);<br>
    }
    }<br>
    };</p>
  </blockquote>
  
  <p>I know thats a lot of Text. But I really don't know where to start searching and what I could do to find the mistake.</p>
  
  <p>Any suggestions would be great!</p>
  
  <p>thanks</p>
  
  <p>Michael</p>