Sometimes my application crashes while trying to open it. As the app hasn't completely started I don't get an error report. I also can't connect my application to the emulator because this behaviour is not reproducable. Sometimes it just crashes once. In other times I can try to open/reopen it as often as I want and it works perfect.
I only use the network-connection (no camera and other stuff). I don't have any services which could crash the application and I tried to reproduce my error by trying to stop the application while it loads something in the background - no success at all.
What do you think could be the reason for crashing? How can I get a log-file, stacktrace something useful for fixing this problem? I simply can't reproduce it so I never see a Logcat-Output when it occurs.
It might be a Fragment-Initializing-Problem but I can't see my mistake. This never occured before and it's just not a common mistake. It might crash only once/twice a week - but it crashes in some point in time...
I've uploaded my project on github but I don't think this is helping somehow.
My main question is: What for opportunities do I have to see what might be the reason behind these random crashes?
Root your phone and install CatLog. When it crashes, open CatLog and save the log so you can view it later.
Or try this if you want to automate it:
Create an exception handler that saves a stack trace to a file.
public class UncaughtExceptionSaver implements UncaughtExceptionHandler{
UncaughtExceptionHandler previousHandler;
Context context;
public UncaughtExceptionSaver (Context context){
this.context = context;
previousHandler= Thread.getUncaughtExceptionHandler();
}
#Override
void uncaughtException(Thread t, Throwable e){
/*Save the stacktrace from the throwable to a
file in your external directory, using context. */
previousHandler.uncaughtException(t,e);
}
}
Then in an Application subclass, call this in the onCreate method:
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionSaver(this));
Related
Currently trying to obtain profile trace logs files for a huge Android app, that we have instrumented on MyApplication class, following the documentation about instrumenting my app to get trace logs.
We are trying to dig into what happens when our app is initialized and Dagger2 creates the object graph when the app is started.
A cold startup can take a few seconds normally, the issue I have is that when I add the Debug traces, it dramatically slows down the initialization of the app, making it crash with an ANR message.
com.github.anrwatchdog.ANRError: Application Not Responding
Caused by: com.github.anrwatchdog.ANRError$$$_Thread: main (state = RUNNABLE)
I would like to know if there is a way to prevent the Android OS from crashing my app when it blocks for a long period of time, or to at least increase the ANR threshold.
Any help or tips are welcome. Thanks!
For further context, this is roughly what I am doing in my MyApplication.class:
public void onCreate() {
super.onCreate();
Debug.startMethodTracing("MyApp_onCreate()");
injectSelf();
AppInit.initApp(this);
Debug.stopMethodTracing();
}
Actually, it turns out we have our own ANRWatchDogManager which I wasn't aware of, where I can extend the limit.
public class ANRWatchDogManager implements ANRWatchDog.ANRListener {
Somewhere in that class:
public void startANRWatchDog() {
final int timeoutInterval = isDebugBuild() && isEmulator()
? ANR_INCREASED_TIMEOUT
: ANR_DEFAULT_TIMEOUT;
new ANRWatchDog(timeoutInterval).setANRListener(this).start();
}
Okay, I'm at a loss with this problem, it doesn't quite make sense to me. In my app, my Application-class looks something like this:
public class MyApplication extends MultiDexApplication {
private static Context sContext;
#Override
public void onCreate() {
super.onCreate();
sContext = getApplicationContext();
SomeClass.someMethod(sContext.getString(R.string.some_string));
[...]
}
[...]
}
The app itself runs a few Services. Now for some reason I get reports of users getting a NullPointerException for sContext.getString(R.string.some_string). Not a lot, to be honest a very small amount of users, mostly on Android 4 and Samsung devices, and about 50% of the errors have the app running in the background, but still enough to get at least two people to complain. And I don't know how this could happen. I have no idea how this could happen for <1% of my users. Has anyone encountered something similiar or has an idea how sContext could be null at that point?
Make sure you have this in your manifest.xml
<application android:name="packagename.MyApplication"/>
The problem is on this lane I guess:
SomeClass.someMethod(sContext.getString(R.string.some_string));
So, you can do it using getResources().getString()... or just getString(R.string.some_string) instead of sContext.getString(...)
Just started using ACRA. When the application crashes it sends a report to my server. All is well.
But there are exceptions which I can catch and let the user keep the problem without error - like using default values. But I'd like to get an error report without bothering the user. But when I do:
ErrorReporter errorReporter = ACRA.getErrorReporter();
errorReporter.putCustomData("test", "value");
errorReporter.handleSilentException(null);
the application shuts down. I first tried throwing some error (testing purposes), I hoped sending null would stop the app from stopping - I was wrong.
Is there a way to use ACRA to send an error report without exiting the app? Just thought I had it, but
ErrorReporter errorReporter = ACRA.getErrorReporter();
errorReporter.putCustomData("test", "value");
errorReporter.handleException(null, false); // false is endApplication param, `null` seems to result in a NullPointerException
This also closes the application (without an additional Exception from ACRA):
ErrorReporter errorReporter = ACRA.getErrorReporter();
errorReporter.putCustomData("test", "value");
errorReporter.handleException(new RuntimeException("message"), false); // tried `true` also, just in case
Also closes the app
Update:
(1) LogCat shows no stack trace.
(2) While reading the error report, my eye fell on
"DUMPSYS_MEMINFO":"Permission Denial: can't dump meminfo from from pid=1416, uid=10048 without permission android.permission.DUMP\n"
Tried to add android.permission.DUMP to androidmanifest.xml, but I get Permission is only granted to system apps. Reason for exiting app? Work around? It gets all information that I need (and more)...
As it turns out, the above code is correct. The problem was in that I have overwritten the ErrorReporter:
new HttpSender(org.acra.sender.HttpSender.Method.PUT, org.acra.sender.HttpSender.Type.JSON, null) {
#Override
public void send(final Context context, final CrashReportData report) throws ReportSenderException {
super.send(context, report);
respondAsIfCrashing(); // not the real method name
}
};
The application wasn't crashing, it just appeared to do that, because of the respondAsIfCrashing method.
The warning DUMPSYS_MEMINFO":"Permission Denial: can't dump meminfo from from pid=1416, uid=10048 without permission android.permission.DUMP is, apparently, not a reason to crash... (perhaps just not writing to device?)
So using
ErrorReporter errorReporter = ACRA.getErrorReporter();
errorReporter.handleException(new RuntimeException("message"), false);
Is sufficient
In Eclipse, I notice that Logcat only retains a few dozen entries and deletes the older ones as soon as a new one come in. Is there a way to prevent this? I need my app to run for a long time and not lose any entries because my app eventually hangs or crashes after a few days, and I want to see if something in Logcat has been recorded.
I am not sure if this is the most elegant solution to the problem, but you can always increase the LogCat message size in Eclipse.
Window -> Preferences -> Android -> LogCat -> Maximum number of LogCat messages to buffer
The default is 5000, I believe. You can set it to be very high if you are planning to run your application for a long time.
i think you need to increase this show image
Here's a better solution:
Set the Default Uncaught Exception Handler. Whenever the app crashes, this will be called with the exception. Simply write a log entry saying it crashed then dump the logcat to a file. Finally, make sure you re-throw the exception to make sure the app crashes and funky things don't happen. Note: This is per thread, keep that in mind.
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread thread, Throwable ex) {
Log.e("TAG", "---My app crashed just now---", ex);
//TODO: Dump logcat to file
throw new RuntimeException(ex);
}
});
if you want to keep your app running for days.. its better you capture your logs from adb shell.
the common shell command would be :
logcat -c \\ to clear previous logs
logcat -v time>yourLogs.txt & \\ to capture fresh logs
I just released a new version of my application to the Android market, and my new version has a GLSurfaceView in the activity. Even though I'm not doing anything fancy, I have a large user base, there's a lot of substandard Android phones out there, and I'm invariably getting exceptions in GLThread.run().
What is the recommended way to catch/handle these exceptions without crashing the entire app? Ideally I'd like to be able to catch the error, remove the surface view from the activity and switch off the component that uses OpenGL. I did a bit of searching but mostly found exception reports for Firefox on Android and stuff like that. :)
I'm thinking of just using an uncaught exception handler, switching a shared preferences flag to false, and letting it crash; the next run I won't try to add that GLSurfaceView.
I ended up working around the problem with the following code:
final UncaughtExceptionHandler defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread thread, Throwable ex) {
if (thread.getName().startsWith("GLThread")) {
disableOpenGLStuff();
}
// You could wrap this in an else, but I'm not sure how good of an idea it is to leave the application running when a thread has crashed.
defaultHandler.uncaughtException(thread, ex);
});