I'm working an Android AudioRecord app. If I do not call the release() method on the AudioRecord object at the end of the script, it will not run correctly until I restart the phone.
This becomes a major hassle when working on this project because if the app should ever crash (which happens sometimes while testing and there's an unexpected buffer overflow, etc.) then I have to restart the phone every time.
I have the method to release the buffers inside the finalize() method of my AudioListener class, and I also call them onStop() of the main Activity.
Neither of these seem to work when the app freezes or crashes. Is there a way to attach the release action to an error handler or some general way of ensuring that an app will execute some code to release resources properly even after a crash.
Thanks for any help.
Create your own Application class (need to be declared in AndroidManifest.xml) and then overwrite methods:
Application.onLowMemory();
Application.onTerminate();
More about it can be read in Android manuals for Application
Related
For the purpose of profiling, I instrumented my android application so that it collects some log at the beginnings and ends of all functions. I do so by calling a public static method called keepLog(String log) at method boundaries. I also wrote another public static method called writeCollectedLogs() which is supposed to write all collected logs into disk. It is important that all logs are written at once because I do not want to use write system-call every time (instead I prefer to keep logs in memory and write everything on disk only once at the end)
My problem is I do not know where to call writeCollectedLogs(). I am looking for some onTerminate() method for the whole android app. However, non of android default onDestroy and onTerminate() seems to work in my case. It is important to note that I have 2 methods of running my application. Sometimes I run my app using android instrumentation test runner and sometimes I use adb to start activities and send touch events manually.
Instrumentation test runner opens my app, runs the tests and then closes the app. In the second scenario however, I have control over my app life cycle. I am looking for a universal way of calling for writeCollectedLogs just before the app closes.
Any suggestions?
This is a bit complicated because there is no universal answer for this problem. If you are using only Activities, onPause() is the only method that is always called (except application crash). Unfortunately, onStop() and onDestroy() are not called with 100% probability. However the android documentation advises to avoid CPU-intensive work in onPause().
I've recently started using Crashlytics to monitor my app performance, however, I've noticed several occasions where my app would crash, but no crash report was sent to my dashboard.
This article says that it's okay to call Crashlytics.start() inside a Base activity class, but doesn't suggest it as a best practice.
I'm curious if not doing so would result in missing crash reports? I'd rather not make unnecessary calls if I don't have to. Currently I'm only calling Crashlytics.start() inside my app's launch activity specified by my androidmanifest.xml file.
I'm curious as to what happens when the user closes my app (by pressing the home button or launching a different activity) and the GC disposes of my activity while it's in the background. When the activity gets recreated and there is no call to Crashlytics.start(), will I be missing those crash reports?
If you don't want to lose any crashes, it is recommended to put the start() call as soon as possible.
And because the Application class is the first class to be instanced when you start your application, its onCreate() method is exactly where you should initialize the library.
If you refuse to do so, you may lose crashes related to your main Activity's inflation, for example.
I recently began writing a phonegap android application and noticed that when the app is resumed from the background (so I deploy the app to an android tablet, press the home button and then reopen the app from the menu) it gives a timeout error (something to the effect of Error code =-6 The connection to the server was unsuccessful) and then crashes. From what I've tested this only seems to happen when the "Don't keep activities" option is checked in the developer options, when that option is not checked the app works as intended.
It's also worth noting that I recreated the default phonegap application, ran it and encountered the same issue.
Can anyone explain why this happens, or suggest a solution? Obviously I can get around this problem by simply leaving the Don't keep activities option unchecked, but I'm guessing the problem will persist on any android device that has this option checked, which just won't do.
I'm using phonegap 2.5.0 and testing on a device running Android 4.0.3,
Thanks,
Josh
"Don't keep activities" is a developer tool to simulate user activity that would be extremely hard to test for. I personally believe all apps should be tested a second time (at least run automated tests) with this setting turned on, and devs should turn it on / off during development.
Your issue (which I've just ran into on v2.7) comes from a silly implementation of a timeout feature. CordovaWebView.loadUrlIntoView creates and locks (wait()) a thread for 20 seconds (default value), after which time it checks a value to see if the url finished loading - if it hasn't finished, it shows an error message.
This thread exists outside of the lifetime of your activity, so if the activity stops running, the Webview can never finish loading the url, and when the thread wakes up, it does Bad Things trying to show the error.
The same crash could happen without using "Don't keep activities" by simply having the user leave the application and then the system reclaiming the activity's resources (because it is low on memory or something) within 20 seconds.
Using a Handler seems like a more appropriate way to handle this timeout, but without changing the source there are a couple of hacky work arounds.
Call System.exit(0) at the end of your Activity.onDestroy() - this is horrible, but if you only have the one activity and no services, it might be an option
Use reflection to change CordovaWebView.loadUrlTimeout - this is horrible, but it should work, this is the value that the thread checks to see if the url loaded (inc by 1).
I have a multi-Threaded android application. One of the things my application does is saves various data to a database on a server via webservices. I was trying to figure out why things were not saving to the server correctly, and saw in one of my log files, that the application objects onCreate() method and constructor were called in the middle of one of the requests going up to the server. These request are in the background and are sent via an intentservice.
I have my application set to catch unhandled exceptions and log them, and I did not see anthing in there. The application onCreate() and constructor was called, the application was kicked back to the main/first screen, the user then had to re-login, and it seems that the database was wiped(which is something else I am wondering about).
So, my main questions are: Why did the application object onCreate() and Constructor get called(why did the application get killed), why did the database get wiped when the above happened because if I do a force stop from inside of settings, applications, it never kills my db.
two words: low memory
I have the same problem. No solution for now. Try to take advantage of the onLowMemory() method, maybe the OS will spare your app.
My application object gets restarted randomly (not any time) when I am coming back from an external application (ex. camera or gallery) for onActivityResult().
Hope that helps someone.
If the application is not a service, but a 'normal' application that calles your intentservice, it is subject to the normal application lifecycle: this means it will get killed when in the background.
Look for the explaining image on this site: http://developer.android.com/guide/topics/fundamentals/activities.html
Take note of the red "Process is killed" part on the left, an the subsequent "onCreate()" afterwards.
I've actually seen very similar behaviour that was caused by a NumberFormater trying to parse a null String. After the call to parse(), the application simply reset itself back to the splash screen with no errors at all. Wasn't fun to track down, pretty much stepped through half the code base trying to find out what was happening - the debugger disconnected and the app restarted when stepping past the parse call.
I have an android service that uses a native library via NDK/JNI. The native library is statically loaded/initialized as suggested...
static {
System.loadLibrary("mylibrary");
if (!nativeClassInit())
throw new RuntimeException("native init failed");
}
Everything works fine until the service is stopped (e.g., from a UI activity where the service may be started/stopped). The problem is when the service is stopped the task has not yet been killed by android and if the user restarts the service the native libraries are not reloaded and a call to a native function causes a crash in the native code?
I tried calling the nativeClassInit() method again after a restart but this doesn't help?
Also, I seen in other posts that unloading the native library is not allowed in Android.
I found by making the service run in its own private process and having the service kill itself in its onDestroy() method via android.os.Process.killProcess() solved my problem. Not sure if this is the most correct way but I would be happy to hear any suggestions.
Concerning the above comments...
What is the native code trying to do when it crashes, and what is the error?
The native code crashed as soon as an internal native library function was called just before the crash an __android_log_print was done displaying the correct parameter values passed in. Its hard to say what exactly happened from the dump.
Do you preserve some JNI pointers (JniENV, jobject-s, etc.) on native side between Service restarts?
Yes, I preserve the JVM in the Onload method and also JNI class IDs & method IDs in my static initialization method. I tried recalling the static initialization method but the same crash occurred.