当前位置:网站首页>Use strictmode strictmode principle (1)
Use strictmode strictmode principle (1)
2022-07-01 01:28:00 【Strange uncle Lori Kong】
List of articles
1. strictmode Get started with :
strictmode yes android Provides a dynamic detection mechanism for debugging environment , There are two main functions :
1.1 Thread strategy
Detect the main thread reading and writing jam
detectDiskReads(); detectDiskWrites();Detect whether the main thread uses the network
detectNetwork();Detect custom slow detection
detectCustomSlowCalls()Resource mismatch detection
detectResourceMismatches()No, buffer Of IO operation
detectUnbufferedIo()
Specific code location :
StrictMode#ThreadPolicy#Builder.detectAll
public @NonNull Builder detectAll() {
detectDiskReads();
detectDiskWrites();
detectNetwork();
final int targetSdk = VMRuntime.getRuntime().getTargetSdkVersion();
if (targetSdk >= Build.VERSION_CODES.HONEYCOMB) {
detectCustomSlowCalls();
}
if (targetSdk >= Build.VERSION_CODES.M) {
detectResourceMismatches();
}
if (targetSdk >= Build.VERSION_CODES.O) {
detectUnbufferedIo();
}
return this;
}
1.2 virtual machine VM Strategy
testing sqlite leak
detectLeakedSqlLiteObjects();testing activity leak : Note that here is the reference count , The actual leak cannot be detected , More on that later
detectActivityLeaks()Check whether it needs to be closed or not , such as IO flow
detectLeakedClosableObjectsCheck whether any component has forgotten to de register (BroadCastReceiver,Service)
detectLeakedRegistrationObjects()testing File Uri Is it exposed
detectFileUriExposure()Detect whether the network request is clear text
detectCleartextNetwork()Detect incorrect conext Use
detectIncorrectContextUse()Detect unsafe intent launch
detectUnsafeIntentLaunch()Source code :
public @NonNull Builder detectAll() {
detectLeakedSqlLiteObjects();
final int targetSdk = VMRuntime.getRuntime().getTargetSdkVersion();
if (targetSdk >= Build.VERSION_CODES.HONEYCOMB) {
detectActivityLeaks();
detectLeakedClosableObjects();
}
if (targetSdk >= Build.VERSION_CODES.JELLY_BEAN) {
detectLeakedRegistrationObjects();
}
if (targetSdk >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
detectFileUriExposure();
}
if (targetSdk >= Build.VERSION_CODES.M) {
// TODO: always add DETECT_VM_CLEARTEXT_NETWORK once we have
// facility for apps to mark sockets that should be ignored
if (SystemProperties.getBoolean(CLEARTEXT_PROPERTY, false)) {
detectCleartextNetwork();
}
}
if (targetSdk >= Build.VERSION_CODES.O) {
detectContentUriWithoutPermission();
detectUntaggedSockets();
}
if (targetSdk >= Build.VERSION_CODES.Q) {
detectCredentialProtectedWhileLocked();
}
if (targetSdk >= Build.VERSION_CODES.R) {
detectIncorrectContextUse();
}
if (targetSdk >= Build.VERSION_CODES.S) {
detectUnsafeIntentLaunch();
}
// TODO: Decide whether to detect non SDK API usage beyond a certain API level.
// TODO: enable detectImplicitDirectBoot() once system is less noisy
return this;
}
1.3 Get started with
private fun strictModeOnDebug() {
if (BuildConfig.DEBUG && Build.VERSION.SDK_INT >= 28) {
StrictMode.setThreadPolicy(
ThreadPolicy.Builder()
.detectAll() // testing Thread All options
.penaltyLog() // Print log
.build()
)
StrictMode.setVmPolicy(
VmPolicy.Builder()
.detectAll() // testing VM All options
.penaltyLog() // Print log
.build()
)
TrafficStats.setThreadStatsTag(0xF00D)
}
}
1.3.1 Thread Test operation
- Monitor writes
findViewById<Button>(R.id.io_read_btn).setOnClickListener {
val outputStream = FileOutputStream(File(getExternalFilesDir("")?.path + "hello.json"))
outputStream.write("hello world".toByteArray())
outputStream.flush()
outputStream.close()
}
logcat journal :
2022-06-20 07:57:35.043 13012-13012/com.ifreedomer.strictmode D/StrictMode: StrictMode policy violation; ~duration=1 ms: android.os.strictmode.DiskWriteViolation
at android.os.StrictMode$AndroidBlockGuardPolicy.onWriteToDisk(StrictMode.java:1460)
at libcore.io.BlockGuardOs.write(BlockGuardOs.java:347)
at libcore.io.IoBridge.write(IoBridge.java:526)
at java.io.FileOutputStream.write(FileOutputStream.java:381)
at java.io.FileOutputStream.write(FileOutputStream.java:359)
at com.ifreedomer.strictmode.MainActivity.onCreate$lambda-0(MainActivity.kt:26)
at com.ifreedomer.strictmode.MainActivity.$r8$lambda$J_2M7j2bq49wREm_StCdiMLvSuc(Unknown Source:0)
at com.ifreedomer.strictmode.MainActivity$$ExternalSyntheticLambda0.onClick(Unknown Source:2)
at android.view.View.performClick(View.java:6597)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1194)
at android.view.View.performClickInternal(View.java:6574)
at android.view.View.access$3100(View.java:778)
at android.view.View$PerformClick.run(View.java:25885)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
The same goes for reading logs . It should be noted that ,IO We really need to do it regularly in the main thread , To avoid too many logs to interfere with the development , This option can be masked when recommended
1.3.2 VM Test operation
IO Detection is not turned off
Sample code :
findViewById<Button>(R.id.io_not_close_btn).setOnClickListener { var outputStream = FileOutputStream(File(getExternalFilesDir("")?.path + "hello.json")) outputStream.write("hello world".toByteArray()) outputStream = FileOutputStream(File(getExternalFilesDir("")?.path + "hello.json")) Runtime.getRuntime().gc() Runtime.getRuntime().gc() }logcat:
2022-06-20 08:11:36.071 13677-13687/com.ifreedomer.strictmode D/StrictMode: StrictMode policy violation: android.os.strictmode.LeakedClosableViolation: A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks. at android.os.StrictMode$AndroidCloseGuardReporter.report(StrictMode.java:1786) at dalvik.system.CloseGuard.warnIfOpen(CloseGuard.java:264) at java.io.FileOutputStream.finalize(FileOutputStream.java:475) at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:250) at java.lang.Daemons$FinalizerDaemon.runInternal(Daemons.java:237) at java.lang.Daemons$Daemon.run(Daemons.java:103) at java.lang.Thread.run(Thread.java:764) Caused by: java.lang.Throwable: Explicit termination method 'close' not called at dalvik.system.CloseGuard.open(CloseGuard.java:221) at java.io.FileOutputStream.<init>(FileOutputStream.java:241) at java.io.FileOutputStream.<init>(FileOutputStream.java:180) at com.ifreedomer.strictmode.MainActivity.onCreate$lambda-4(MainActivity.kt:57) at com.ifreedomer.strictmode.MainActivity.$r8$lambda$sFdQJzxyBqsXzAQCFxp0PCpUtgg(Unknown Source:0) at com.ifreedomer.strictmode.MainActivity$$ExternalSyntheticLambda3.onClick(Unknown Source:2) at android.view.View.performClick(View.java:6597) at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1194) at android.view.View.performClickInternal(View.java:6574) at android.view.View.access$3100(View.java:778) at android.view.View$PerformClick.run(View.java:25885) at android.os.Handler.handleCallback(Handler.java:873) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:6669) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)Database leak detection
cursor Not closed
findViewById<Button>(R.id.database_open_btn).setOnClickListener {
val readableDatabase =
dbHelper.readableDatabase
var rawQuery = readableDatabase.rawQuery("select * from user", null)
val sqLiteCursor = rawQuery as SQLiteCursor
sqLiteCursor.moveToFirst()
Log.d(TAG,"sql window = ${sqLiteCursor.window}")
rawQuery = null
readableDatabase.close()
Runtime.getRuntime().gc()
}
logcat:
2022-06-20 08:00:19.687 13012-13022/com.ifreedomer.strictmode D/StrictMode: StrictMode policy violation: android.os.strictmode.SqliteObjectLeakedViolation: Finalizing a Cursor that has not been deactivated or closed. database = /data/user/0/com.ifreedomer.strictmode/databases/haha.db, table = null, query = select * from user
at android.os.StrictMode.onSqliteObjectLeaked(StrictMode.java:1956)
at android.database.sqlite.SQLiteCursor.finalize(SQLiteCursor.java:285)
at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:250)
at java.lang.Daemons$FinalizerDaemon.runInternal(Daemons.java:237)
at java.lang.Daemons$Daemon.run(Daemons.java:103)
at java.lang.Thread.run(Thread.java:764)
Caused by: android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
at android.database.sqlite.SQLiteCursor.<init>(SQLiteCursor.java:103)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:52)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1408)
at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1347)
at com.ifreedomer.strictmode.MainActivity.onCreate$lambda-2(MainActivity.kt:43)
at com.ifreedomer.strictmode.MainActivity.$r8$lambda$KlEPG7__y4DedDU3EV-gqJ4mzpo(Unknown Source:0)
at com.ifreedomer.strictmode.MainActivity$$ExternalSyntheticLambda3.onClick(Unknown Source:2)
at android.view.View.performClick(View.java:6597)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1194)
at android.view.View.performClickInternal(View.java:6574)
at android.view.View.access$3100(View.java:778)
at android.view.View$PerformClick.run(View.java:25885)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
1.4 Set listening
If you want to get this leaked information , You can do it yourself StrictMode Of Listener
if (BuildConfig.DEBUG && Build.VERSION.SDK_INT >= 28) {
StrictMode.setThreadPolicy(
ThreadPolicy.Builder()
.detectAll()
.penaltyLog()
.penaltyListener(Executors.newSingleThreadExecutor(),{
})
.build()
)
StrictMode.setVmPolicy(
VmPolicy.Builder()
.detectAll()
.penaltyLog()
.penaltyListener(Executors.newSingleThreadExecutor(),{
})
.build()
)
}
边栏推荐
- Poor students can also play raspberry pie
- Interpreting the scientific and technological literacy contained in maker Education
- [leetcode] sum of two numbers [1]
- Use of typora
- Windows环境下安装MongoDB数据库
- Analyze the maker education path integrating the essence of discipline
- 解读创客教育所蕴含的科技素养
- 流批一体在京东的探索与实践
- Kongyiji's first question: how much do you know about service communication?
- MFC TCP communication server client demo notes vs2019
猜你喜欢
随机推荐
The liquor and tourism sector recovers, and Yaduo continues to dream of listing. How far is it from "the first share of the new accommodation economy"?
ASCII、Unicode、GBK、UTF-8之间的关系
尝试新的可能
孙宇晨接受瑞士媒体Bilan采访:熊市不会持续太久
【go】go 实现行专列 将集合进行转列
DX-11Q信号继电器
Training discipline principle of robot programming
为什么要搭建个人博客
Visual studio 2019 Download
【office办公-pdf篇】pdf合并与拆分让我们摆脱付费软件的功能限制好不好
TypeError: Argument ‘angle‘ can not be treated as a double
基础知识之一——STA基础概述
Technical personnel advanced to draw a big picture of business, hand-in-hand teaching is coming
Windows环境下安装MongoDB数据库
人穷志不短,穷学生也能玩转树莓派
软件开发完整流程
[learning notes] simple DP
[LeetCode] 两数之和【1】
[go] go implements row column conversion of sets
闭锁继电器YDB-100、100V









