0

I am using android's thread pool executor framework (initialized as below).

BlockingQueue<Runnable> taskQueue = new LinkedBlockingQueue<>();
ExecutorService executorService = new ThreadPoolExecutor(totalCores, totalCores * 3, 10, TimeUnit.SECONDS, taskQueue);

Now, consider the following function onFrameProcessed -

public void onFrameProcessed(RenderedImage renderedImage) {
String timeNow = new SimpleDateFormat("d-M-Y_HH_mm_ss_SSS").format(new Date()).toString();
CustomRunnable3 customRunnable3 = new CustomRunnable3(renderedImage, timeNow);
executorService.execute(customRunnable3);
}

Definition of CustomRunnable3 is as follows:

class CustomRunnable3 implements Runnable {
    RenderedImage renderedImageLocal;
    String basePath, timeNowCopy;
    int hashCode;

    CustomRunnable3(RenderedImage renderedImage, String timeNow) {
        renderedImageLocal = renderedImage;
        this.basePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString();
        this.timeNowCopy = timeNow;
        hashCode = renderedImageLocal.hashCode();
    }

    @Override
    public void run() {
        if (renderedImageLocal.imageType() == RenderedImage.ImageType.ThermalRadiometricKelvinImage) {
            int[] thermalData = renderedImageLocal.thermalPixelValues();
            String dataPath = basePath + "/" + this.timeNowCopy + ".csv";
            try {
                PrintWriter printWriter = new PrintWriter(dataPath);
                int dataLen = thermalData.length;
                for (int i = 0; i < dataLen; i++) {
                    printWriter.println(thermalData[i]);
                }
                printWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            String imgPath = basePath + "/" + this.timeNowCopy + ".jpg";
            try {
                if (hashCode != renderedImageLocal.hashCode()) {
                    Log.e("Checking", "Hash code changed..");
                }
                renderedImageLocal.getFrame().save(new File(imgPath), frameProcessor);
                if (hashCode != renderedImageLocal.hashCode()) {
                    Log.e("Checking", "Hash code changed after writing..");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
}

Usage Scenario : onFrameReceived is being called multiple times per second(like 4-5 times). In each call to onFrameReceived, I am saving two files from renderedImage object (1 csv file, 1 jpg file). Both of these files must be related to each other because both are created from one parent and have same name(except the extension).

Problem : But that is not happening and somehow I am ending up with jpg file content from 1 renderedImage and csv content from another renderedImage object. What are the possible reasons for this problem, please share your opinion.

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Amit Sharma
  • 131
  • 1
  • 2
  • 12
  • I think that the problem could be related to the fact that you are always passing on a reference to renderedImage. A bit more context around the onFrameProcessed callback would be helpful – nsndvd Sep 07 '18 at 09:25
  • @nsndvd: But when I am creating CustomRunnable3 instance, the constructor is copying the reference to renderedImage, so in next call to onFrameProcessed, should't renderedImage point to a new object and the CustomRunnable3 instance should have previous object reference still? About the onFrameProcessed : It is actually a callback which is called whenever a raw frame is processed and a renderedImage object (just a processed form of frame) is passed to it which as far as I understand is a new object reference every time. – Amit Sharma Sep 07 '18 at 10:23
  • Yeah what you write is correct. I am not so familiar with the API that you are using and I am wondering if there could be some kind of buffer that is actually reused across instances – nsndvd Sep 07 '18 at 11:12

0 Answers0