ACTION_IMAGE_CAPTURE intent: Avoid Activity being destroyed / process being killed

1k Views Asked by At

This question is for Android developers who are familiar with the Activity Lifecycle.

I'm developing an app that performs face detection and facial landmark recognition.

The according machine learning models take a long time to be parsed from the SD storage and loaded into memory. On current average Android devices, it easily takes up to 20 seconds. By the way, all of this face analysis stuff and model loading happens in C++ native code, which is integrated using the Android NDK + JNI.

Because the model loading takes a long time, the actual parsing and loading is scheduled early in the background via AsyncTasks, so that the user does not notice a huge delay.

Before the actual face analysis is performed, the user can take a selfie via the MediaStore.ACTION_IMAGE_CAPTURE. This will call a separate camera app installed on the device and receive the picture via onActivityResult.

Now the problem starts: Almost always the whole app process will be killed while the user is in the separate camera Activity/App. Mostly it seems to happen right before returning from the Camera app (the timing seems odd). I did another test to confirm that it happens when the capture button is pressed inside the camer app. At that moment, my app is killed. When pressing the 'Accept image' button, the app is recreated. The reason given in logcat by the ActivityManager for the process kill is 'prev LAST' (I've found nothing via Google on the meaning of this, but I saw that many other apps are also killed with this reason, so it seems to happen quite often).

Thus, all of the Activities of my app need to be recreated by Android (fine by me, because it happens fast), but also the face analysis models must be loaded again from scratch, and the user will notice a huge delay before his selfie can be processed.

My question is: Is there any possibility to tell Android that an Activity/App has a legitimate reason to not be killed while being in the background temporarily to get a camera picture? After all, the ActivityManager makes a wrong decision to kill the app. Having to reload the models so frequently takes up a lot of CPU and memory resources.

It seems like an oversight in the Android lifecycle architecture. I know that few apps have the specific requirements of my app, but still, it seems stupid. The only way I can think of to 'fix' this issue is to implement my own camera Activity inside the app, but this goes counter Android's own best practices.

There is also some 'android:persistent' flag that you can stick to your Activity via AndroidManifest.xml, but the docs are totally unclear about the implications of this. See the docs on this.

By the way: onDestroy is not called when the app process is killed. I've read somewhere that there is no guarantee that onDestroy will be called, and this is actually not a problem for me. Although I wonder why the Android docs do not state this clearly.

1

There are 1 best solutions below

5
On BEST ANSWER

Almost always the whole app process will be killed while the user is in the separate camera Activity/App

This is not surprising. A camera app can consume quite a bit of memory, so Android needs to free up memory by terminating background apps' processes.

After all, the ActivityManager makes a wrong decision to kill the app

Given that a likely alternative is the OS crashing, I suspect the user would agree with the OS decision to terminate your process.

Having to reload the models so frequently takes up a lot of CPU and memory resources.

Then perhaps you should not be starting another app from yours. Take the photo yourself. Use the camera APIs directly, or use libraries like Fotoapparat and CameraKit-Android as simpler wrappers around those APIs.

The only way I can think of to 'fix' this issue is to implement my own camera Activity inside the app, but this goes counter Android's own best practices.

By that argument, no devices would ever have a camera app, as writing any camera app "goes counter Android's own best practices".

Any app that needs a camera must use the camera APIs (directly or indirectly) to have any shot at reliable behavior. You are assuming that thousands of camera apps are all properly written and will correctly honor your ACTION_IMAGE_CAPTURE Intent (e.g., putting the results in the place that you designate with EXTRA_OUTPUT). Many camera apps have buggy ACTION_IMAGE_CAPTURE implementations. ACTION_IMAGE_CAPTURE is not unreasonable for cases where you and the user can live without the picture being taken (e.g., a note-taker app that has an "attach photo" feature), but that would not seem to be the case with your app.