Android ANR Spy is the most simplest library that helps android developers to detect ANRs.
when a developer do most heavy jobs on UI thread (more than 5 seconds usually) and UI thread still receieve more request/events for doing a task then Android system raises ANR message. This is extremely bad effect on your app and may lead to the failure of your business.
Google recommends/suggests your app on play store. If your app raises too many ANRs then your app will be ranked down
- Normal on UI Thread in any activity = 5 secs
- BroadCast = 10 sec
- Service = 20 sec
Note: Sample app is included in the project. Just clone the repo
implementation("io.github.farimarwat:anrspy:1.3")
(before onCreate() method)
//Anr Callback
private var mCallback = object : ANRSpyListener {
override fun onWait(ms: Long) {
//Total blocking time of main thread.
//Can be used for doing any action e.g. if blocked time is more than 5 seconds then
//restart the app to avoid raising ANR message because it will lead to down rank your app.
}
override fun onAnrStackTrace(stackstrace: Array<StackTraceElement>) {
//To investigate ANR via stackstrace if occured.
//This method is deprecated and will be removed in future
}
override fun onReportAvailable(methodList: List<MethodModel>) {
//Get instant report about annotated methods if touches main thread more than target time
}
override fun onAnrDetected(
details: String,
stackTrace: Array<StackTraceElement>,
packageMethods: List<String>?
) {
//details: Short description about the detected anr
//stacktrace: Stacktrace of the anr
//packageMethod: methods hierarchy(bottom up) that causes anr (only if method is inside current app package name)
}
}
(before onCreate() method)
val anrSpyAgent = ANRSpyAgent.Builder(this)
.setTimeOut(5000)
.setSpyListener(mCallback)
.setThrowException(false)
.enableReportAnnotatedMethods(true)
.setFirebaseInstance(firebaseinstance)
.build()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
.....
......
anrSpyAgent.start()
}
Note:Step 1, 2 and 3 can be done only once on either mainactivity or in appclass.There is not need to create seperate instances for each activity, viewmodel etc. This is thread based process and will be available in whole app.
setTimeOut(5000)
Time limit to detect ANR
setSpyListener()
Sets ANRSpyListener/callback methods
setThrowException(true)
Convert possible ANR to crash to figure out the line where ANR may be possible and close the app if true. Default is false
enableReportAnnotatedMethods(true)
This will generate report for annotated methods that you want to trace any where in the app. If the specified methods touches main thread for more than target time (default 5 secs), it will trigger onReportAvailable method of the callback to get details about the function e.g. Thread Name, Elapsed Time on main thread and function
Note: If the annotated method is not running on main thread then there will be no report generated.
setFirebaseInstance(firebaseinstance)
To get logs similar to the mention above on firebase. Just set the instance for firebase analytics and all events will be collected as usuall to other events. All the events will be prefixed with: ANR_SPY_ to differenciate from other events on firebase
In case if any one want to trace a specific method to trace then there are two types of annotations available:
1. @TraceClass(traceAllMethods = false) This annotatiion is applied to a class and takes one parameter. If the paramater traceAllMethods is set to true then all methods of the class will be traced on main thread. Default is true
Note: If traceAllMethods is set to false and there is no specific annotated method then there will be no report generated. To trace all methods in MainActivity:
Example:
@TraceClass(traceAllMethods = true)
class MainActivity : AppCompatActivity() {
.......
}
2. @TraceMethod To trace a specific method on main thread for ANR
Example:
@TraceMethod
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
}
Note: If the method is not running on main thread then there will be no report generated
version 1.3
- Get details of methods which is related to main app package that causes anrs via "onAnrDetected" extra paramater
- A bug fixed (classnotfoundexception)
version 1.2 (beta)
- Annotation added to trace a specific method for ANR
- Store annotated methods report in firebase analytics
version 1.0 Initial release
If you want to donate then you are welcome to buy me a cup of tea via PATREON because this encourages me to give you more free stuff and continue to maintain this library