I write an app which will continuously request data from a sensor board and send data to server. I use a Motorola Droid phone which have not be activated to test my app. I find that sometimes after several hours the phone will reboot. I just want to know does it cause by my app run out of memory. And if an app runs out of phone's memory, should just the app be force closed or the phone be reboot?
If this causes by app running out of memory how could I release and clear variables. Should the system automatically do this? I think the main problem might be that I set a global json variable to receive and send all data. After sending the data, I just user new JSONObject() to initiate the variable. I just want to know does the old one will be released automatically? If not, how can I do to release it?
Thanks
If an app runs out of phone's memory, an exception will be thrown and if the exception will not be catched - an app will be force closed.
System automatically clean unused memory. Yes, your old JSONObject should be autoreleased by garbage collector.
To learn how to find memory leaks in Android programs, read the article in Android developers blog: Memory Analysis for Android Applications
Related
Your phone's memory is low - error message on my android application using camera
"Your phone's memory is low" notice appears on my Android application (java), which uses a custom camera, at random.
Is there a way for Android to catch this issue.I need to handle this without user interaction within my programme.
Any Java method to find this? I experimented with deleting the cache after an action(on destoy,cleared cache). But that doesn't resolve the problem.
I want to get the location of the device once when the service is running in the background (the tracker monitors the change in the database and then executes the code that should get the geolocation of the phone). I encountered a problem: the program receives location data when the application is running, but when it goes into the background, the location data stops being received in a few seconds. I tried all the codes and options that I could find, but everything stops working when the program goes into the background. For this I use AndroidStudio Java. So how do I implement this and is it even possible? Thanks.
On Android there are two types of Services- foreground and background. Background (the default) on modern Android are killed 2 minutes after your app is no longer in the foreground. Foreground services are kept for longer, require you to have a notification so the user knows you're tacking him (think of Uber and the notification you can't swipe away you get while its running), but can still be killed for resources if other apps need it. You cannot rely on any Service running permanently.
So the answer is going to be either Foreground Service, or its going to be a completely different architecture for your program. The second really depends on exactly when and why you want to get the location.
There are many limitations on getting on getting location in background, refer to this
Do you target API level 29 or up? if yes, have you add ACCESS_BACKGROUND_LOCATION permission in manifest? If this is not declared, app can only access location while in foreground.
Even after declaring ACCESS_BACKGROUND_LOCATION permission, app can only get location data a few time in an hour due to limitations. Maybe you can consider using foreground service instead to avoid such limitations.
I'm currently developing and maintaining an Android Legacy app, native in Java. The App has been growing slowly throughout the years and I think the original architecture design it falling a bit short.
The app opens the native android camera, and for some reason, it kills the process in background, perhaps due to lack of resources. I've tested different flows with the android profiler, and wasted a lot of time trying to pinpoint what its happening. The flow goes as this:
The app is filled with data, using a SQL DB and static variables, then at some point the user is required to use the native camera to retrive a photo, then return to the app and keep on with the process. Sometimes, the process dies while being in the native camera app, and when returning, all the data stored on the static variables are empty, thus crashing the app and restarting itself.
Using the Android Studio Profiler, I found that when the process dies, it prints this in the console:
2021-11-18 22:19:54.906 9177-9762/es.myapp I/PhenotypeProcessReaper: Memory state is: 400
2021-11-18 22:19:54.906 9177-9762/es.myapp I/PhenotypeProcessReaper: Killing process to refresh experiment configuration
2021-11-18 22:19:54.906 9177-9762/es.myapp I/Process: Sending signal. PID: 9177 SIG: 9
Does anyone has any idea of what is happening? What is PhenotypeProcessReaper?
I'm trying to write a class to save the states of all the data to be able to recover the app after the process, but in the mean time I would really appreciate some help. Thanks!
The background services are not encouraged any more from Android Oreo (>25). I want the socket to keep connected in my chat application even when the app is closed.
How can I implement new changes to android 26?
Some people says, use JobIntentService
Some people says, use JobService
Some people says, use JobScheduler
Some people says, start service as Foreground Service
Any help would be appreciated.
I faced the exact same problem working on a chat application so I know your pain. Our conclusion was:
you don't keep a connection alive 24/7, if you need to deliver a
message to an user that has no connection alive, send a push message
via Firebase.
If you want to keep a connection alive in background, you will face many problems. The first one, targeting Oreo, is that if your app is in background (definition of "background" in this context is here) it won't be allowed to run except for small time windows.
You can definitely use JobScheduler to run periodic tasks, they won't be executed at exact intervals or times to reduce battery usage (which is good) but it won't help you in keeping a connection alive. At best, you can use JobScheduler to periodically pull messages from you server. In order to use JobScheduler you need to create a JobService class.
JobIntentService is a new class introduced in API 26 of support library. It is a replacement for IntentService, it will run as a JobService on android API 26+ and as a Service (similar to IntentService in the sense that it will execute code in a background thread) on older APIs. On Oreo its background execution will still be limited so it won't help you in keeping a connection alive.
Using a foreground Service can really help you reducing the likelihood of the process being killed, but, you will need to display a permanent notification. It doesn't sound like a good solution for a chat app.
If you still think that having a 24/7 connection alive is a viable option, you need to consider also doze mode. You could ask the user to whitelist your app to run even in doze mode but you should have a very good reason to do that. Again, you would face the other bg execution limit in Oreo.
Another issue you will face is other apps. There are resources management apps that will aggressively kill other apps in bg to reduce memory and battery usage. For instance, I cursed this one quite a bit.
Another issue is created by android. When the system is running low on memory, it will start killing processes of apps in bg. There is a an order in which they're killed, if I recall correctly should take into account last time it was in fg and current memory usage. Not the worst of the problems but still, it happens.
Then, if I still haven't convinced you in giving up the idea of the permanent connection, let me share with you yet another problem you would face. Some vendors implements extremely aggressive policies when it comes to killing bg processes, so that they're battery will last longer. For instance, Xiaomi.
Last tip, unrelated, but it took us a while to figure this out so I'm going to share it. If the user force stops your app from settings, your app is dead (that is, "stopped state") until the user actively launches it again, it won't even receive Firebase push messages.
If your server is configured on XMPP, then it would be easy for you.
Actually, there isn't any need to keep the socket alive at all the time. This is very expensive for the battery and I'm sure you don't want that.
Case: You are working on a Messaging app.
If your socket is broken, then the client will receive the message in the form of Google FIREBASE notification. And the moment your client will receive a notification from firebase, just enable the socket, and you'll be back on track.
The reason I suggested you to use XMPP is because XMPP maintains a queue of undelivered/offline messages. And when your socket is connected again, you simply pull the offline messages from the server.
I don't think this will help you out, but this may make a room for some another idea for you.
I am told that the Android OS (>=SDK14) is able in a real lean memory situation to start extinguishing tasks without sending onDistroy()-messages. It is very interesting (app quality issue) to stress test apps in such environments.
So this is a question about extreme cases, all memory is gone and the OS starts to extinguish stopped tasks to get more memory. Is it possible to provoke such a situation, to be able to test it? Shall I write a JNI program (making hello-jni looping a calloc or something)? This to chew up all the memory to provoke this situation of poverty?
How do I best memory choke my app/the Android OS environment? Any ideas? Any tried such stress tests?
Are there any total OS memory monitors available?
Can anyone explain if the Java and JNI parts of memory are from each other isolated heaps (chunks of memory) or allocated from the same common memory by the OS? Is it possible to choke the Java apps with JNI memory allocation?
So 7 years later, updated question:
Wh I know today it is not possible to provoke a JNI-memory shut down, just appears with no warning? It is not possible to test the topic in code?
This topic is a general design issue on how to design an editor the best way.
Still there are two main questions:
There is not yet a message to the Java app that the OS intends to shut down the JNI memory part, as far as I understand.
So the app can do the shut down itself instead and be aware the JNI part is shut down. It would be just as good if the app is notified that the entire app should be closed and all the mines will disappear, but that is not done either. The app may live but the JNI memory is gone and the app has no idea it happened.
Where the main problem is not knowing, not being able to test as it just crashes when the JNI memory is gone och det anropas.
Must be very tricky technically because there is such a given solution that is missing?
Given that users who are in the middle of app work jump between apps, the app can't close down the JNI part for each jump. The best solution is still to let the app crash if the JNI part is gone and let the user restart again by pressing a second time on the app icon? It's not a pretty situation?
Also, you can't assume that JNI is gone after a few days and just restart from scratch. Because then you fill the memory with unused JNI memory allocations if this is not the case. You can't test because then it crashes.
My app is a bookkeeping accounting browser and does not edit the files, but in 2023 I intend to come up with a complete accounting program based on the browser's functions with extensions. The situation is like an Office program, but works with inbdustry standard bookkeeping accounting documents/files. It requires that this question be thought through properly once more.
All views and suggestions are welcome
Data recovery and the new regulations/restrictions for saving files in the public folders
It means that you cannot use fopen() in JNI, but must use java byte streaming of the Picker. Where you can of course save the resolver and uri and reuse it for saving. See also NDK fopen() in the common storage of Android API 31
I have solved this situation for "open the last opened file on startup" by saving a copy of the last opened file in the app's local storage as well as the name of the last opened file.
To save, you must start the Picker at least once, but if the file is opened with the picker, you can reuse the resolver and uri for the file update. While it is the last opened file, you have to start the picker for an OK.
For the browser, this is a minimal problem. But for an accounting editor, it is a central question how to update documents that are worked on for a long time, and the user very likely jumps to other apps, during the work? If the JNI part disappears, it can be devastating.
I think it can save in a temp file during the work and then have a save button for the user. A temp file that can be restored after a JNI is gone crash and the app is restarted from scratch. One can probably find a way to save where the user was last and arrange a rollback?
It's so strange that there is so much trouble just because a "We intend to discard JNI stored memory for the app" message is missing, because then you have full control. Hope it still comes.
Also here all views and suggestions are welcome