Long list of EDT errors when capturing an image with a set size - possible instability on iOS

33 views
Skip to first unread message

nickk...@gmail.com

unread,
Oct 5, 2017, 10:33:50 PM10/5/17
to CodenameOne Discussions
I have an issue where the app crashes completely 'sometimes' when taking photos.

The code that I'm using this is always run on the EDT:
       String imagePath = Capture.capturePhoto(960, -1);
            if (imagePath != null) {
                savePicture(imagePath);
            }

This code saves the file into the file system in a way that the native code can access - FormManager.runOnEDT just takes a runnable and checks if we are already on the EDT or if we need to callSerially in order to run:
    public void savePicture(String imagePath) {
        FormManager.runOnEDT(() -> {
            Log.p("imagePath" + imagePath);

            try {
                Image img = Image.createImage(imagePath);
                String host = FileSystemStorage.getInstance().getAppHomePath();
                if (!isSimulator() && "ios".equals(getPlatformName())) {
                    if (host.indexOf("file://") == 0 && host.indexOf("file:///") == -1) {
                        host = StringUtil.replaceAll(host, "file://", "file:///");
                    }
                }
                String newPath = host + Integer.toHexString((int) (System.currentTimeMillis() / 1000)) + ".jpg";
                Log.p("newPath" + newPath);
                OutputStream out = FileSystemStorage.getInstance().openOutputStream(newPath);

                ImageIO.getImageIO().save(img, out, ImageIO.FORMAT_JPEG, 1);
                img.dispose();
                imagePaths.add(newPath);
                revalidate();

            } catch (IOException ex) {
                Log.e(ex);
            }
        });
    }

ONE call to capture the image triggers a 17,000 line trace complaining about the EDT violation (attached)

Now I know that the EDT violation detection is specific to the simulator and not perfect. But I also know that image manipulation off the EDT can crash iOS devices and this looks very suspicious that this is the point where iPhones are crashing. Its not all the time, but after taking enough photos the app will immediately shut down when the button is pressed that triggers the capture code. What logs I can get don't have memory warnings any more now that the dispose method is called on the image after saving it out, so I'm not sure that that is the problem. The random and platform specific nature of this error feels like a thread issue but I'm lost as to how to resolve this.


EDTViolation.txt

Shai Almog

unread,
Oct 6, 2017, 1:16:05 AM10/6/17
to CodenameOne Discussions
I don't see how 17,000 lines can be generated from this? I'd investigate that first as it looks really suspicious. I think you invoke savePicture in a loop causing out of memory at some point for this.

Also dispose() might not be ideal, if you do that and still have a reference to the image "somewhere" it's an instant crash.

nickk...@gmail.com

unread,
Oct 8, 2017, 6:09:37 PM10/8/17
to CodenameOne Discussions
Adding a breakpoint before saveImage is called shows that the log attached is generated only from this line:
String imagePath = Capture.capturePhoto(960, -1);

And saveImage is only called once per image.

I can provide a minimal example that shows this too, but the steps are fairly easy:
1. Make a button that calls Capture.capturePhoto(960,-1); in the action listener
2. Run in the simulator with EDT debugging turned on
3. Press the button, upload the image, watch the logs.

The image isn't used again by CN1 code, the path is stored as a string and passed as a string to native code later on. In any case the dispose is the difference between it crashing after a few photos on all iOS devices and it crashes only after a lot of photos only on some iOS devices. I'm sure its necessary and it isn't causing issues unless there are other side effects.

Because of the hit and miss nature of whether this crashes it 'feels' like a memory or thread issue but there are no memory warnings in the logs that I've seen from users that have this happen and there is this significant EDT strangeness going on at the same point in the simulator - seems like something that should be fixed and eliminated as a potential cause of the issue I'm seeing.

nickk...@gmail.com

unread,
Oct 8, 2017, 6:20:29 PM10/8/17
to CodenameOne Discussions
Looks like getRGB is called for each pixel in the image and checkEDT is called for each call to getRGB = a lot of EDT violations.

I think whatever is going on under the hood for Capture.capturePhoto should make sure its on the EDT and this issue would go away and hopefully the side effect would be better stability on iOS

Shai Almog

unread,
Oct 9, 2017, 12:34:38 AM10/9/17
to CodenameOne Discussions
OK, I see the problem. I'll fix the log so it doesn't make noise.

This isn't a problem in native code as the scale method is implemented in the native OS ports and doesn't use this approach.

If this is indeed an EDT issue you can verify that by copying the code from Capture.java and changing it to do the scaling on the EDT. 

nickk...@gmail.com

unread,
Oct 12, 2017, 7:57:46 PM10/12/17
to CodenameOne Discussions
Copying the code from Capture.java and ensuring it runs on the EDT seems to make a significant difference in stability on iOS.

Shai Almog

unread,
Oct 13, 2017, 1:30:01 AM10/13/17
to CodenameOne Discussions
OK, please file an issue or submit a pull request. Thanks.
Reply all
Reply to author
Forward
0 new messages