How does ACRA catch all of an app's exceptions? - android

Do you know how ACRA - the Android Crash reporting framework - works under the hood?
How does it hook-in to catch exceptions and errors? Is it using some global try/catch block to detect errors?
And does it affect performance and battery life by doing this?

ACRA works by setting up a default exception handler on the main thread. You can see that in the source code here:
mDfltExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
It sets itself as the default uncaught exception handler at this point. Java will call this handler if there are any Exceptions that are thrown that are never caught by any try/catch block.
Since it's not really an active daemon or process, but rather part of your code (assuming you call ACRA.init()), it doesn't actually impact performance or battery life at all.

Related

Report all Android crashes to own API

I am in a situation where I cannot use third party Crash reporting platform (Crashalytics ...etc)
So, I started to use self developed Rest API to receive crash reports from mobile app.
However, I can only send handled crashes so far by using try-catch
How can I handle all crashes thrown by my mobile app even those which are not in my try-catch clauses
Just like Crashlytics which can catch all crashes and sends them to Firebase without placing try-catch
Have a look at Thread.UncaughtExceptionHandler
from the docs :
When a thread is about to terminate due to an uncaught exception the
Java Virtual Machine will query the thread for its
UncaughtExceptionHandler using Thread.getUncaughtExceptionHandler()
and will invoke the handler's uncaughtException method, passing the
thread and the exception as arguments. If a thread has not had its
UncaughtExceptionHandler explicitly set, then its ThreadGroup object
acts as its UncaughtExceptionHandler. If the ThreadGroup object has no
special requirements for dealing with the exception, it can forward
the invocation to the default uncaught exception handler.
using this, you can get all threads and all exceptions, which you can then report to any API you'd like
you can find examples of how it was implemented
here and here
There is a library which you can use called ACRA , its an open source library you can check its code , or you can directly use their library and configure it to hit your api
#AcraHttpSender(uri = "http://yourserver.com/yourscript",
basicAuthLogin = "yourlogin", // optional
basicAuthPassword = "y0uRpa$$w0rd", // optional
httpMethod = HttpSender.Method.POST)
public class MyApplication extends Application {

Multiple process to catch uncaught exception?

I am developing a module that will be installed on multiple app. On of our client expressed concern about the potential of our module crashing making his app crash. I want to find a way to catch all uncaught exceptions that my module can throw. The module is composed of a service and 2-3 activities who have very little communication with the main app.
To catch those exceptions thrown by a handful of classes, and only those classes, what whould be the best option ? I have considered using Thread.UncaughtExceptionHandler which catch all exception thrown by a thread and putting all thoses classes in a separate process (with the android:process attribute), but I was told that using multiple processes can impact performance and battery usage. Is it possible to start a service and multiple activities in a separate thread without having to rewrite them all ?
You can implement an uncaught exception handler from your library. It will handle the uncaught exceptions that got triggered from threads started from your library.
Don't forget to pass it to the DefaultUncaughtExceptionHandler.
If the app implemented its own UncaughtExceptionHandler it will handle it as well.

Log.wtf vs. Unhandled Exception

I just learned about Log.wtf ("What a Terrible Failure" lol) and I'm wondering when I should use it.
What is the difference between calling Log.wtf with an exception and letting an exception go unhandled (crash)?
How does it affect crash reports in the Google Play Developer Console?
I usually throw an IllegalStateException for unexpected conditions. Should I consider calling Log.wtf instead?
Edit:
See also: Under what circumstances will Android's Log.wtf terminate my app?
What Log.wtf does is write the exception and its stack trace in the log, and only that. It neither catches nor throws exceptions. So
The difference is the exception is logged or not. The exception remains unhandled.
It doesn't affect crash reports.
If you wish to log it, go ahead. But you'll want to keep throwing IllegalStateException.
EDIT
I tried debugging and stepping into Log.wtf but no luck.
What I've found is pretty much what is answered in the linked question. It seems that in the "default terrible failure handling" Log.wtf creates an internal exception (TerribleFailure) which wraps any given exception. Then it calls RuntimeInit.wtf(). Its javadoc says:
Report a serious error in the current process. May or may not cause
the process to terminate (depends on system settings).
I guess the behavior of Log.wtf is up to the device manufacturer. My Sony C6503 doesn't seem to raise any exception or kill the process.
Some open source reference:
https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/util/Log.java
https://android.googlesource.com/platform/frameworks/base/+/master/core/java/com/android/internal/os/RuntimeInit.java
Unhandled exceptions are not logged by default. Log.wtf may or may not crash the application. If you pass an exception to Log.wtf and it crashes, then you should get a stack trace similar to what you would get if the exception were not handled. After calling Log.wtf, you should (re)throw an exception if you want to ensure a crash (without catching it of course).
There may be specific use cases for Log.wtf, but if you are unsure, it's probably better to use Log.e instead.

Unhandled exception not caught by global exceptionhandler

I got an android app where I set a global exception handler as described here:
Using Global Exception Handling on android
When I'm forcing an exception then I see that it is catched by the handler.
But from time to time I'm still experiencing device freezes when running the app.
The app uses a lot of different threads. But as far as I understand, this should have no influence.
Are there some known limitations on android regarding global exception handling, where exception are not handled by the global handler?
Thanks

ACRA make it boring if there are many exceptions thrown

I use ACRA in my android application. It's very useful but sometimes boring.
Sometimes, there are several asynchronous tasks running in the background. And for season, all of them failed(e.g. can't connect to internet). ACRA will show the toast message again and again, and refused to exit.
Is it able to let ACRA just catch the first exception? Or just show the toast message once?
Update
add a demo: https://github.com/freewind/android-acra-multi-reports
There are 4 activities in this project. The last one will throw exception and each previous activity will throw exception in onActivityResult. You can see ACRA will report many times before exiting.
That sounds to me like you should actually catch some exceptions and don't let all of them bubble up.
ACRA registers a Thread.UncaughtExceptionHandler on the main thread. Here all uncaught exceptions (as the handler's name suggests) get processed. Usually that means that the application is about to crash and ACRA will do its reporting magic. ACRA uses several Threads itself to do its work and will wait until everything is finished before it actually kills the application's process. So I'd guess that if there are coming a lot of exceptions, ACRA is just so busy to process them that it won't come to the point were it would kill the process.
You could register your own implementation of UncaughtExceptionHandler to catch exceptions and decide when to hand them through to ACRA and when to do something else. If I'm not mistaken, ACRA will call through to the UncaughtExceptionHandler that has been registered before the ACRA init. So you could also try to chain those handlers.

Categories

Resources