It’s quite common to invite users to rate an app on Google Play at some point, on one hand it’s good to know that your users are happy and on the other it’s a good way to attract new users. It’s definitely not the only variable in the equation, but I can definitely say that user satisfaction is inversely proportional to the amount of crashes. But bugs are unfortunately something we have to expect as developers, even after testing our apps thoroughly. One thing we probably don’t want to do, is to ask a user to rate our app just after a crash since we can be reasonably sure that he’s not going to be too happy about it. How can we make sure that this doesn’t happen? When an uncaught exception is thrown, the uncaughtException method of the default UncaughtExceptionHandler for that Thread is called. Good news is, you can supply your own UncaughtExceptionHandler using the setDefaultUncaughtExceptionHandler setter (this is what ACRA and I suppose other libraries like Crittercism or BugSense do under the hood). Here is a little snippet of what we do in the Qype app:

	public class CustomUncaughtExceptionHandlerProxy implements Thread.UncaughtExceptionHandler {

	    private static CustomUncaughtExceptionHandlerProxy proxy;

	    private final boolean enabled;

	    private Thread.UncaughtExceptionHandler customUncaughtExceptionHandler;

	    private CustomUncaughtExceptionHandlerProxy(CustomApplication application) {
	        enabled = !application.inDevMode();
	        if (enabled) {
	            // Save a reference to the current default handler.
	            customUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
	            // Set our custom handler as the default one, so that it's first notified when something ugly happens.
	            Thread.setDefaultUncaughtExceptionHandler(this);
	        }
	    }

	    public static void initialize(CustomApplication application) {
	        if (proxy == null) {
	            proxy = new CustomUncaughtExceptionHandlerProxy(application);
	        }
	    }

	    public static CustomUncaughtExceptionHandlerProxy getInstance() {
	        return proxy;
	    }

	    @Override
	    public void uncaughtException(Thread thread, Throwable ex) {
	        if (enabled) {
	            if (!preferences.rateAppDialogAlreadyShown()) {
	                // reset count only if the 'rate app' dialog hasn't been already shown.
	                preferences.resetShowRateAppDialogCountdown();
	            }
	            // Let the default uncaught exception handler do its job.
	            customUncaughtExceptionHandler.uncaughtException(thread, ex);
	        } else {
	            Thread.getDefaultUncaughtExceptionHandler().uncaughtException(thread, ex);
	        }
	    }
	}

This is a typical implementation of the Proxy design pattern, it’s pretty straightforward but here’s a little explanation of how it works. Let’s say you want to show a “Rate App” dialog after n times the app is opened by the user, you would use a counter and increment it each time the launcher Activity is created and it will show the dialog when the value of the counter is exactly n. But if the app crashes and the dialog is yet to be shown, you may want to reset the counter.