Hello Readers, CoolMonkTechie heartily welcomes you in this article (An Overview Of Strict Mode).
In this article, we will learn about Strict Mode in Android. Performing any kind of long blocking operations or disk IO operations on the Android Main thread can cause ANR (Application Not Responding) issues. We may not even realise that we have a potential ANR until it is too late and is already in our user’s hands. most of the cases, the library or framework which we are using in our application, will not allow us to perform disk operations on the main thread (Room for instance, makes it explicit when we want to turn it off).
So, how do we know and correct our mistakes done during android application development when the libraries or frameworks don’t explicitly prevent this kind of operation?
Android provides a Strict Mode developer tool for that.
To understand about the Strict Mode, we cover the below topics as below :
- Overview
- Strict Mode Policies
- Different Ways to Notify Strict Mode
- Enabling Strict Mode
- Recommendations
A famous quote about learning is :
“If you live long enough, you’ll make mistakes. But if you learn from them, you’ll be a better person.“
So Let’s begin.
Overview
Strict Mode is a developer tool which detects things we might be doing by accident and brings them to our attention so we can fix them.
Best practice in Android says “keeping the disk and network operations off from the main thread makes applications much smoother and more responsive”. So StrictMode is use to catch the coding issues such as disk I/O or network access on the application’s main thread i.e. UI thread. By keeping our application’s main thread responsive, we also prevent ANR dialogs from being shown to users.
This is a debugging tool introduced in Android 2.3 (API level 9) but more features were added in Android 3.0.
StrictMode Policies
Strict Mode has two types of policies and each policy has various rules. Each policy also has various methods of showing when a rule is violated.
Thread Policy
Thread policies are focused on the things which is not recommended to do in main thread like disk or network operations. The Thread policy can monitor following violations:
- Disk Reads
- Disk Writes
- Network access
- Resource Mismatch
- Custom Slow Code
VM Policy
VM policies are focused on memory leaks because of bad coding practices like forgot to close the SQLite cursor or leaks in Activities. The VM policy can monitor following violation:
- Activity leaks
- SQLite objects leaks
- Closable objects leaks
- Registration objects leaks
- Class instance limit
- File URL exposure
Different Ways to Notify Strict Mode
There are variety of different ways by which user/developer get to know when a rule you set has been violated. In terms of Strict Mode, it is known as Penalty.
Some of methods are listed below:
penaltyDeath()
: Crash the whole process on violation.penaltyDeathOnNetwork()
: Crash the whole process on any network usage.penaltyDialog()
: Show an annoying dialog to the developer on detected violations.penaltyFlashScreen()
: Flash the screen during a violation.penaltyLog()
: Log detected violations to the system log.
Enabling Strict Mode
To enable and configure the Strict Mode in our application, we require to use setThreadPolicy() and setVmPolicy() methods of Strict Mode. It is a good practice to set policies either in Application , Activity or other application component’s Application.onCreate()
method:
override fun onCreate() {
if (BuildConfig.DEBUG){
StrictMode.setThreadPolicy(
StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork()
.penaltyLog()
.build()
)
StrictMode.setVmPolicy(
StrictMode.VmPolicy.Builder()
.detectAll()
.penaltyLog()
.build()
)
}
super.onCreate()
}
Now, we can decide what should happen when a violation is detected like in the above example we have used only penaltyLog() for Thread Policy but in the VM Policy we used penaltyLog() as well as penaltyDeath() to notify. We can watch the output of adb logcat
while we use our application to see the violations as they happen.
Here is the example of penaltyLog() showing the logs which explains Strict Mode is warning us that we are using disk write operation on the main thread.
DEBUG/StrictMode(3134): StrictMode policy violation; ~duration=319 ms: android.os.StrictMode$StrictModeDiskWriteViolation: policy=31 violation=1
DEBUG/StrictMode(3134): at android.os.StrictMode$AndroidBlockGuardPolicy.onWriteToDisk(StrictMode.java:1041)
DEBUG/StrictMode(3134): at android.database.sqlite.SQLiteStatement.acquireAndLock(SQLiteStatement.java:219)
DEBUG/StrictMode(3134): at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java:83)
DEBUG/StrictMode(3134): at android.database.sqlite.SQLiteDatabase.updateWithOnConflict(SQLiteDatabase.java:1829)
DEBUG/StrictMode(3134): at android.database.sqlite.SQLiteDatabase.update(SQLiteDatabase.java:1780)
DEBUG/StrictMode(3134): at com.test.data.MainActivity.update(MainActivity.java:87)
Recommendations
If we find violations that we feel are problematic, there are a variety of tools to help solve them: threads, Handler
, AsyncTask
, IntentService
, etc. But don’t feel compelled to fix everything that Strict Mode finds. In particular, many cases of disk access are often necessary during the normal activity lifecycle. Use Strict Mode to find things we did by accident. Network requests on the UI thread are almost always a problem, though.
It is not a security mechanism and is not guaranteed to find all disk or network accesses. While it does propagate its state across process boundaries when doing Binder
calls, it’s still ultimately a best effort mechanism. Notably, disk or network access from JNI calls won’t necessarily trigger it.
Many of violations are not related to our application. We want to suppress these violations. For example- DiskRead checking (or suppress any other checking of StrictMode that is it violating). Here, we want to do following things in function:
- Turn off the Strict Mode checking
- Running the function or the parameterized block of code
- Turn on the original Strict Mode checking
The function looks like the below:
fun permitDiskReads(func: () -> Any?) : Any? {
if (BuildConfig.DEBUG) {
val oldThreadPolicy = StrictMode.getThreadPolicy()
StrictMode.setThreadPolicy(
StrictMode.ThreadPolicy.Builder(oldThreadPolicy)
.permitDiskReads().build())
val anyValue = func()
StrictMode.setThreadPolicy(oldThreadPolicy)
return anyValue
} else {
return func()
}
}
The above example, we are just suppressing the detectDiskReads(), we could perform other suppression if required. it‘s not only running the function, but returning Any value (i.e. nothing or something if we don’t know what Any means) the function might return.
This is useful when the code that we want to suppress the check might be a function that returns something. For example, we have a SampleManager.getInstance() that also have some disk reads violation we want to suppress. So we could do as below:
val sampleManager =
permitDiskReads { SampleManager.getInstance() } as SampleManager
That’s all about in this article.
Conclusion
In this article, we understood about about Strict Mode in Android. This article explained about Strict Mode which is a very useful tool to find and fix performance issues, object leaks, and other hard-to-find runtime issues for Android developers. We may think that we are doing everything off the main thread, but sometimes small things can creep in and cause these issues. It helps keep our applications in check and should definitely be enabled whilst developing our applications.
Thanks for reading! I hope you enjoyed and learned about Strict Mode concepts in Android. Reading is one thing, but the only way to master it is to do it yourself.
Please follow and subscribe to the blog and support us in any way possible. Also like and share the article with others for spread valuable knowledge.
You can find other articles of CoolMonkTechie as below link :
You can also follow the official website and tutorials of Android as below links :
If you have any comments, questions, or think I missed something, leave them below in the comment box.
Thanks again Reading. HAPPY READING !!???