code: package com.paris.neuromorphic;
  
  import android.os.HandlerThread;
  import android.util.Log;
  
  import com.esotericsoftware.kryo.Kryo;
  import com.esotericsoftware.kryo.io.Output;
  
  import java.io.FileNotFoundException;
  import java.io.FileOutputStream;
  import java.text.DecimalFormat;
  import java.util.concurrent.BlockingQueue;
  
  /**
   * Created by Gregor on 12/12/2018.
   */
  
  public class ProcessingThread extends HandlerThread {
      private String TAG = getClass().getSimpleName();
  
      private volatile boolean isCameraAttached = true;
  
      private ToExchange toExchange;
      private final BlockingQueue buffer;
  
      private long startTimeStamp, currentTimeStamp, lastTimeStamp;
  
      private long iterationCounter;
  
      private Kryo kryo;
      private Output output;
  
      static final String filePath = "/data/user/0/com.vision.neuromorphic.frog/files/recording.bin";
      DecimalFormat df = new DecimalFormat("####.##");
  
  
      ProcessingThread(BlockingQueue blockingQueue) {
          super(ProcessingThread.class.getName());
          buffer = blockingQueue;
          kryo = new Kryo();
          kryo.register(ToExchange.class);
          kryo.register(byte[].class);
          Log.d(TAG, filePath);
      }
  
      @Override
      public void run() {
          Log.d(TAG, "Consumer run method");
          super.run();
      }
  
      @Override
      protected void onLooperPrepared() {
          Log.d(TAG, "Looper prepared");
          super.onLooperPrepared();
  
          //saveBufferElements();
          processBufferElements();
  
          super.quit();
      }
  
      private void saveBufferElements() {
          try {
              output = new Output(new FileOutputStream(filePath));
              while (isCameraAttached) {
                  toExchange = (ToExchange) buffer.take();
                  kryo.writeObject(output, toExchange);
                  Log.i(TAG, "Consumer: Saved Exchange to file with size " + toExchange.size
                          + ", remaining buffer capacity: " + buffer.remainingCapacity());
              }
              output.close();
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  
      private void processBufferElements() {
          while (isCameraAttached) {
              try {
                  toExchange = (ToExchange) buffer.take();
                  startTimeStamp = System.nanoTime();
                  Eventprocessor.setCameraData(toExchange.data, toExchange.size);
                  currentTimeStamp = System.nanoTime();
  
                  iterationCounter++;
                  Log.d(TAG, "Consumer: Processing Exchange no. " + iterationCounter + " with size " + toExchange.size + " took "
                          + df.format((currentTimeStamp - startTimeStamp) / 1000000f) + "ms, it's been "
                          + df.format((startTimeStamp - lastTimeStamp) / 1000000f) + "ms since last call, remaining buffer capacity: "
                          + buffer.remainingCapacity());
                  lastTimeStamp = currentTimeStamp;
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
      }
  
      void setCameraAttached(boolean flag) {
          isCameraAttached = flag;
  
          if (output != null) {
              output.close();
          }
      }
  
      @Override
      public boolean quit() {
          return super.quit();
      }
  
  }