Implementing user-unaware background crash handling in Android

Implementing user-unaware background crash handling in Android

As the saying goes, if you want to have no bugs, don't write a single line of code. When an app reaches the hands of users, the fewer crashes the better. Crash handling in Android is different from that in iOS. iOS crashes usually result in a flash back, while Android will display a clumsy dialog box as shown below.

It’s not surprising that when your users see a crash dialog like this, they think “this class of programmers is terrible”.

In Android, our applications have the concept of foreground and background. In this article, it is defined as follows: the current application has an Activity displayed (that is, the user clearly perceives that they are in the current application), which is agreed to be the foreground, otherwise it is the background.

If a crash occurs in the foreground, the user will be able to clearly perceive it, but if it happens in the background, we can do some simple operations to prevent the user from noticing the crash (i.e., no crash dialog box will pop up).

The principle is actually quite simple.

  • Check whether it is background
  • If it is a background process, kill the process, otherwise execute the default crash handling

Check whether it is background. Here we use the number of Activities in the process as the judgment standard

  • When activity onStart, activityCount increases automatically
  • When Activity onStop, activityCount is decremented
  • When activityCount is 0, we consider the application to be in the background state

The specific implementation is as follows:

  1. object ActivityLifecycleCallbackImp: Application.ActivityLifecycleCallbacks {
  2. var activityCount: Int = 0
  3. override fun onActivityPaused(activity: Activity?) {
  4. }
  5.  
  6. override fun onActivityResumed(activity: Activity?) {
  7. }
  8.  
  9. override fun onActivityStarted(activity: Activity?) {
  10. activityCount++
  11. }
  12.  
  13. override fun onActivityDestroyed(activity: Activity?) {
  14. }
  15.  
  16. override fun onActivitySaveInstanceState(activity: Activity?, outState: Bundle?) {
  17. }
  18.  
  19. override fun onActivityStopped(activity: Activity?) {
  20. activityCount --  
  21. }
  22.  
  23. override fun onActivityCreated(activity: Activity?, savedInstanceState: Bundle?) {
  24. }
  25. }

Register in Application:

  1. class MyApplication : Application() {
  2. override fun onCreate() {
  3. super.onCreate()
  4. registerActivityLifecycleCallbacks(ActivityLifecycleCallbackImp)
  5. }
  6. }

All that's left is to set up a custom uncaught exception handler:

  1. val defaultHandler = Thread.getDefaultUncaughtExceptionHandler()
  2. Thread.setDefaultUncaughtExceptionHandler { thread, exception ->
  3. exception.printStackTrace()
  4. val isBackground = ActivityLifecycleCallbackImp.activityCount == 0
  5. if (isBackground) {
  6. Log.d( "MyApplication" , "isBackground just kill the process without annoying users" )
  7. android.os.Process.killProcess(android.os.Process.myPid())
  8. } else {
  9. defaultHandler.uncaughtException(thread, exception)
  10. }
  11. }

This function has been basically realized. Compared with the previous rigid dialog box, it is much more friendly to kill the process silently in the background without interfering with the user.

<<:  Big data "killing familiarity" new gameplay or Apple's deep routine

>>:  iOS+PWA is here, are you here?

Recommend

Do potatoes have “natural enemies”?

Potato (Latin name: Solanum tuberosum, English: P...

Why are some people always reluctant to leave the gambling table?

Author: Wu Quan A coin has only two sides, heads ...

Why do you always want to jump down when you are standing on a high place?

This article was reviewed by Zhao Wei, MD, associ...

Event planning and promotion skills (4000 words of hard-core operation tips)

The eight essential steps for a successful fissio...

Getting Started Guide to Short Video Promotion!

From the traditional "two Weibo" to tod...

Why is Android no longer suitable for the era of smart cars?

As more and more car companies begin to emphasize...

Is it reliable to find a partner through body odor?

Our body odor stores a wealth of biological infor...

“Seedless” grapes are actually produced by drugs? Can we eat them safely?

As a common fruit available in all seasons, grape...