The app answers: how we reduced the number of ANRs by six times. Part 2, on error correction

, ANR (Application Not Responding), . , , , .





, , ANR-, — . Google Play — . :





Broadcast of Intent { act=com.google.android.c2dm.intent.RECEIVE } …”, , - . - , , , , 60% ANR- Application.onCreate.





, . , - ANR.





Application.onCreate Android. :





  • , ANR- , ;





  • BroadcastReceiver, ANR 10 . , , .





: , ANR-, Android ANR- ( “Enable background ANR dialogs” ). , , , .





, ANR-, , Application.onCreate. Google Play, Firebase Cloud Messaging BroadcastReceiver: 10- , ANR-.





, , Application Application.onCreate ( ). , ContentProvider’ , , onCreate.





: . : , . Android, , Application.onCreate, , , . :





Background cold start application duration
Application cold start duration

, 2,2 , — 5 . 3% 10 . , , ANR-. , .





, . Android Studio .





Android Studio / . , , . . :





  • startMethodTracingSampling





  • startMethodTracing





  • stopMethodTracing





Application ( ), Application.onCreate, onResume Activity. , Application - :





class Application {
    constructor() {
        Debug.startMethodTracingSampling("/sdcard/startup.trace", 64 * 1024 * 1024, 50)
    }

    override fun onCreate() {
        // …
        Debug.stopMethodTracing()
    }
} 
      
      



Android Studio:





.





  • sample-based- method-based-. , . Sample-based- , . , sample-based- .





  • debug- release- . , -. ( Leak Canary) . 





, , . , ( ?), , . . , .









. application scope, , . . application scope , , «» .









- , , . , (Handler.postDelayed). .





ContentProvider’





ContentProvider. , AndroidManifest.xml, Android ContentProvider , .





- ContentProvider, , AndroidManifest.xml :





<provider
    android:name="some.ContentProvider"
    tools:node="remove" /> 
      
      



, . , , , ContentProvider, , . , Application.onCreate.





, 95- 50% ( ~10 ~5 ):





ANR-? Google Play:





Source: TV series "Office"
: «»

, , ANR-. “Bad Behaviour” , .





SharedPreferences apply()

- Google Play :





, , - Android, , SharedPreferences. 





, , ANR-.





commit, . SharedPreferences apply. , API?





Android. SharedPreferences SharedPreferencesImpl.java. SharedPreferences HashMap, commit apply , . , , , , . MemoryCommitResult.





apply(), , enqueueDiskWrite(), , . apply():





@Override
public void apply() {
    final MemoryCommitResult mcr = commitToMemory();
    final Runnable awaitCommit = () -> mcr.writtenToDiskLatch.await();

    QueuedWork.addFinisher(awaitCommit);

    Runnable postWriteRunnable = () -> {
        awaitCommit.run();
        QueuedWork.removeFinisher(awaitCommit);
    }

    SharedPreferencesImpl.this.enqueueDiskWrite(mcr, postWriteRunnable);
} 
      
      



Runnable — , . Runnable QueuedWork. JavaDoc QueueWork , :





Internal utility class to keep track of process-global work that's outstanding and hasn't been finished yet.





This was created for writing SharedPreference edits out asynchronously so we'd have a mechanism to wait for the writes in Activity.onPause and similar places, but we may use this mechanism for other things in the future.





, Activity.onStop, Service.onStartCommand Service.onDestroy.





, Android . apply(), commit().





, , . ? SharedPreferences, . , SharedPreferences , , .





, SharedPreferences ANR- apply, A/B-, . SharedPreferences -:





fun Context.createPreferences(name: String, mode: Int = Context.MODE_PRIVATE): SharedPreferences = getSharedPreferences(name, mode) 
      
      



SharedPreferences . - SharedPreferences, , apply(): commit() . , - SharedPreferences — Binary Preferences, - .





A/B- :





fun Context.createPreferences(name: String, mode: Int = Context.MODE_PRIVATE): SharedPreferences =
    if (isAsyncCommitAbTestEnabled()) {
        getAsyncCommitSharedPrefs(this, name, mode)
    } else {
        getSharedPreferences(name, mode)
    } 
      
      



A/B-, . , .





, ANR- 4% A/B . , .





push-

, ANR rate. 





, ANR rate. , , ANR- BroadcastReceiver, Application.onCreate. , — .





, BroadcastReceiver push-. : , , , ?





Android . , . BroadcastReceiver- , . Android Application.onCreate:





. Application . , Application.onCreate, , push-. BroadcastReceiver ANR-:





, , AndroidManifest.xml. , BroadcastReceiver “receiver” “android:process”. , Firebase Cloud Messaging?





, . FCM BroadcastReceiver tools:node=”replace”. FCM BroadcastReceiver, push- FirebaseMessagingService, . :





<service
android:name="com.google.firebase.messaging.FirebaseMessagingService"
android:exported="false"
android:process=":light"
tools:node="replace">
  <intent-filter android:priority="-500">
  <action android:name="com.google.firebase.MESSAGING_EVENT" />
  </intent-filter>
</service>

<receiver
android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND"
android:process=":light"
tools:node="replace">
  <intent-filter>
  <action android:name="com.google.android.c2dm.intent.RECEIVE" />
  </intent-filter>
</receiver> 
      
      



, Google Play broadcast , Application.onCreate, , :





class Application {
	override fun onCreate() {
		if (isMainProcess) {
			// perform usual initialization
		}
	}
}
      
      



. .





push-, , , . , , , Activity PendingIntent .





, :





, .





— :





  • ANR- Badoo 0,8% 0,41% , *, 0,28%:





* Google Play - .





  • ANR- .





ANR rate, , - :





  • FCM . , , , .





  • FCM- , , XML- .









, . , , ANR rate, .





ANR rate ANR- :





, ANR rate . 





, ANR? .









  1. Snap Engineering





  2. SharedPreferences





  3. SharedPreferences
















All Articles