react-native-image-picker / react-native-image-picker

:sunrise_over_mountains: A React Native module that allows you to use native UI to select media from the device library or directly from the camera.
MIT License
8.48k stars 2.08k forks source link

Library does not handle Activity re-creation by Android system #1502

Open zandrei opened 3 years ago

zandrei commented 3 years ago

Description

On low end Android hardware (2 GB of RAM), at some point in the functioning of an application, when trying to take some pictures with the library, the Android OS will kill the host application and re-create it after the takePictures intent is finished. Applications should handle these lifecycle methods themselves, but so should the react-native-image-picker library. When Android starts killing background tasks, the picture which was last taken will not be available to the host application and the library should be able on restart to provide this to the host application. Expo-image-picker recently implemented a similar functionality here: https://github.com/expo/expo/pull/9697/files although it is not complete there as well. They only take one case into consideration, the one where the activity is killed by the OS, but not the application. I don't know if in the latter case there might be a solution in the react-native ecosystem.

How to repeat issue and example

Use the react-native-image-picker library to launch the camera (or choose image, they should behave the same). Go to "Developer options" and set to true the option to "Don't keep activities". Take a picture. The picture taken won't be available to the calling application. For the second issue (when the application gets destroyed instead of the activity), also change the "Background process limit" in "Developer options" to "No background process".

Solution

Persist the image information onHostDestroy and provide a callback for the host application to check if it was restarted and there is a pending image request. For the second issue I am not sure what solution can be applied

Additional Information

Note: There are multiple issues opened on this platform which are actually related to this specific particularity. The issues labeled: "Application restarts without error after taking picture" or similar titles are related to this issue that the Android OS will restart the background application if it needs to free up memory.

ravirajn22 commented 3 years ago

Thanks for the report. I know the issue exist, but don't know the right way to solve it. From what I know react-native uses just single activity for whole app lifecycle. So if the activity is recreated, then your apps unsaved data all be lost. Your app will open from first screen. So you need to handle the navigation to the screen he was before restart and handle the new image data.

I will look into it, but solution may not be straightforward as you think and sometimes may be not worth adding (because there is no 1gb android phones in even Indian market).

zandrei commented 3 years ago

Thank you for the reply. As I said in the report, the application will handle navigation and recreation of the previous screen on startup (for e.g. my application allows the user to upload multiple pictures before submitting them to a back-end API. When the activity goes to background, we persist the state (what images were already taken) and we are able to show them when the application restarts). The main issue is with the last picture the user will take because for that one we get no response from the ImagePicker. If the ImagePicker itself hold the last taken image somewhere and will provide a callback that the host activity can call upon re-creation then the application may fully restore it's state, even with the latest image taken.

The issue is present on a Samsung Galaxy TabA7 tablet (i think it is 2018) which has 2Gb of RAM memory an uses ~1.5 Gb from startup. It might be that Samsung OS more aggresively kills background tasks than other OS but Samusng devices are still a big market share.

I started working on a solution for what our project needs (only the basic launchCamera functionality) and I am storing the latest picture in sharedPreferences and provide a callback that the host may call to check and retrieve the pendingImage if there is one. Initial tests are quite promising. I will let you know if we are successful and with what solution (I started working on the 2.x version for the moment as I do not want to handle permissions myself).

ravirajn22 commented 3 years ago

Good, but you can work on 3.x.x because there is no permission for android. Check docs.

deadlock commented 3 years ago

Just adding some information.

I have a 4GB ram phone and experiencing the same issue.

To reproduce it i leave the app in background for about 20 minutes and the first attempt to take a picture makes de app restarts. The second attempt work normally as well as the next ones.

deadlock commented 3 years ago

I have founded this PR about this problem, i think its a good shot: https://github.com/react-native-image-picker/react-native-image-picker/pull/763/files

Issue related: https://github.com/react-native-image-picker/react-native-image-picker/issues/732

ravirajn22 commented 3 years ago

I have founded this PR about this problem, i think its a good shot: https://github.com/react-native-image-picker/react-native-image-picker/pull/763/files

Thats a different error case, can you paste your android stacktrace if any. Use logcat

zandrei commented 3 years ago

Unfortunately this is beyond the scope of this library since there is an issue with how react-native handles onActivityResult after the react context is re-created. The issue can be followed here: https://github.com/facebook/react-native/issues/30277. I was unable to adapt this library to do something about these use cases. @deadlock indeed it can happen on devices with more memory if the OS is highly constrained in memory or the current application uses too much memory. It may also vary between devices with the same memory capacity since different proprietary OS may be more aggressive in killing background tasks.

livnunes commented 3 years ago

To me it seems like this only started happening after I updated Android Studio to 4.1, targetSDK to 29 and also gradle. After that this started happening and I have no clue why. Everytime I take a picture the app just restarts, I was actually using react-native-crop-image-picker on the app before, then changed to this one but the exact same issue happens. I'm also currently on react-native@0.59.10. Does anyone know a workaround for this, I'm still searching around but losing a bit of hope.

zandrei commented 3 years ago

Reverting here with some more information. For anyone not looking for fancy camera options, just the ability to take pictures or start video recording, you can use the React Native Camera library (https://github.com/react-native-camera/react-native-camera) to overcome this issue with activity being re-created by the Android system. The difference is that the RNCamera library does not launch a new Android activity (just embeds the camera wherever you specify it to do it) which means that your current React application will remain active, even when taking picture/recording video.

If you want to allow the users of your application to launch an intent with their preferred choice of camera application then you need to find other solutions. Regarding this specific library, we will need to wait for the react native issue to be addressed. @ravirajn22 I don't know if you want to close this issue or just keep it as a reference for all similar issues that might pop up. I don't think there is anything you or any other library contributor can do regarding this issue until the react-native team tackles their issue.

ravirajn22 commented 3 years ago

Thanks @zandrei for the info.

tomNjerry commented 3 years ago

Issue still persist of app restarted when clicked for camera after installing react-native-camera. Any solution , thanks in advance

zandrei commented 3 years ago

@tomNjerry if you started using the react-native-camera library then you should redirect your issues to the react native camera github page (link in the post above). Normally, if you used the react-native-camera and embedded the action to take pictures in one of your pages then the react application never goes to background and cannot be killed by the Android OS. Bear in mind though that if the user minimizes your application (by pressing the home button), your app might still be killed by the Android OS so you should still think about what you need to do for your specific application to persist its state and re-create it when it is re-created by the Android OS. (this might mean you would need to persist navigation state and also any other information that was not persisted to a back-end API when the application goes to background and then read from the storage when your application is re-created by the Android OS).

lunajing commented 3 years ago

Just adding some information.

I have a 4GB ram phone and experiencing the same issue.

To reproduce it i leave the app in background for about 20 minutes and the first attempt to take a picture makes de app restarts. The second attempt work normally as well as the next ones.

Mine is 6GB, also happen.

zandrei commented 3 years ago

indeed it can happen on devices with more memory if the OS is highly constrained in memory or the current application uses too much memory. It may also vary between devices with the same memory capacity since different proprietary OS may be more aggressive in killing background tasks.

@lunajing read the previous reply to deadlock user. The most important factor is the memory already in use. You can use my suggestion here https://github.com/react-native-image-picker/react-native-image-picker/issues/1502#issuecomment-749447624 to fix your problem for now

Return-1 commented 3 years ago

We are also facing this

papiahs commented 3 years ago

Hello, I also encountered this difficulty. Is there any way to know if the phone has this behavior? So know if I show the image picker or use the rn-camera

zandrei commented 3 years ago

Any phone can have this behavior if it already uses a large amount of RAM memory. The key is not to yield control to another activity and always remain in foreground so that the Android OS will not kill your react-native application to save memory. To do that you can use the rn-camera library but you need to handle all the other operations (flash, front/rear camera, etc.) from that library or through other means. It's no point in adding more issues to this library since the problem is in the react-native code, ticket which is linked in the previous comments. It might be better to upvote that one in order to get more attention since there does not seem to be any activity from the react-native team. There is a comment there, mentioning a workaround: https://github.com/facebook/react-native/issues/30277#issuecomment-784292271 but I did not test it so I cannot say if it works or not.

ghost commented 3 years ago

also facing the same issue on Android 10 App restart after taking pictures from camera please help with any solution!!!

pmella16 commented 3 years ago

i have this erro Caused by: java.lang.IllegalStateException: Screen fragments should never be restored. Follow instructions from https://github.com/software-mansion/react-native-screens/issues/17#issuecomment-424704067 to properly configure your main activity.

medonagy45 commented 3 years ago

I am facing the same issue for launchCamera launchImageLibrary The application re starts

Is there any fix for that

ZaikinaEvgeniya-2 commented 3 years ago

Hi, any changes? how resolve this? on ios works fine, on some android after take a video/photo - restart the app

AhmedAbuelenin commented 2 years ago

I am still facing this issue, any updates on this. using react-native 0.67.3 & react-native-image-picker 4.8.2

aallvi commented 1 year ago

same issue at jul 2023 in phone with 4 ram an i open the app with nothing in background.

dprevost-LMI commented 1 year ago

Anyone encountering this might want to try the foreground service of Notifee. See this issue where I explained how to use it: https://github.com/react-native-image-picker/react-native-image-picker/issues/2239

muhammadvsashfaq commented 4 months ago

Still facing same app restart issue.

mannoeu commented 3 months ago

Still facing same app restart issue.

dprevost-LMI commented 3 months ago

Yep, see the workaround example I did but closed since I had no feedback, that should help you have something: https://github.com/react-native-image-picker/react-native-image-picker/pull/2245

dprevost-LMI commented 3 months ago

Yep, see the workaround example I did but closed since I had no feedback, that should help you have something: https://github.com/react-native-image-picker/react-native-image-picker/pull/2245