Fixed Android app black screen issue when reopening after incomplete closing #3227
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The problem mentioned in issue #3127 has been fixed.
The black screen problem was therefore linked to several problems:
The fact that the application remains in the background despite the end of
android_main
and activities. (it seems that this is a normal behavior of android to reload resources faster and that this is not managed from the same way depending on the system. I would have to try on a second device to see how it handles it).When we called
CloseWindow()
at the end of our programAPP_CMD_TERM_WINDOW
was also "called" (like when we quit the application without closing it) but given that the context was already destroyed, the second calls surface destruction, etc. led to a firstEGL_BAD_DISPLAY
error.Again in
APP_CMD_TERM_WINDOW
, after destroying the surface, we setcontextRebindRequired
to true, the application closes and we return to the Android home, but part of the memory is kept (like the stack). Then when reopening (if we haven't closed the application ourselves in the task manager, or that Android does not close it itself) the app still hascontextRebindRequired
set to true and therefore tries to rebind with a non-existent context, etc. And so we get black screen with a second timeEGL_BAD_DISPLAY
However, there are two other minor issues that I have noticed.
This behavior (part of the app that remains in memory) seems to vary depending on the device, overlay, Android version, etc. However, the static global variables that I have defined in my C program remain unchanged after closing and reopening (by closing, I mean the call to
ANativeActivity_finish(app->activity)
and the end ofandroid_main
). This can be problematic, although in normal cases, we define them within functions, but it's worth noting.The fact that we don't fully manage the app's lifecycle via
AndroidCommandCallback
poses certain minor problems. For example, if the user manually exits the application using the Android task manager while the app is running, we receive this error in the logs:This error is often related to memory leaks according to StackOverflow responses. However, a proper operating system should be able to handle this upon program termination, I suppose, so I consider it minor, right? 🤔
Other than that, the app closes properly,
APP_CMD_DESTROY
is indeed "called" and the Java methodonDestroy
as well. So, if the application remains in the background, that is up to Android. No more error messages appear, and there are no apparent memory leaks in normal usage that could explain this.Video example
I made a short video capture to show that everything was working correctly now (and without the use of
exit(0)
), and I also wanted to demonstrate the issue of the stack being kept in memory even after closing the application. However, since I was recording the video and it was taking up a lot of memory on my device, the system automatically unloaded the entire application, except at one point where you can see thatcounter
was preserved despite the closure.So, for the users of raylib on Android, remember to initialize your global variables inside functions each time the application starts to avoid problems related to this behavior.
This variable
counter
is a static global variable that is only initialized once to 0 during its declaration. Theexit
button simply breaks the mainwhile
loop, callsCloseWindow()
, and themain
ends.XRecorder_06082023_195642.mp4
If ever things are not clear or poorly explained do not hesitate to ask me.