当前位置:网站首页>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()
)
}
边栏推荐
猜你喜欢
![分割链表[先取next再斩断链表防止断链]](/img/eb/708ab20c13df75f4dbd2d6461d3602.png)
分割链表[先取next再斩断链表防止断链]

gin_gorm

One of the basics - overview of sta Basics

【网络丢包,网络延迟?这款神器帮你搞定所有!】

技术人进阶画业务大图,手把手教学来了

Unhandled Exception: MissingPluginException(No implementation found for method launch on channel)

数字IC设计流程总结

"Open math input panel" in MathType editing in win11 is gray and cannot be edited

机器人编程的培训学科类原理

K210 site helmet
随机推荐
06. on several ways of redis persistence
visual studio 2019 快捷键备忘
Technical personnel advanced to draw a big picture of business, hand-in-hand teaching is coming
About the general input operation mode of unity
Training discipline principle of robot programming
二季度最后一天
Visual studio 2019 shortcut notes
(learning power + thinking power) x action power, summary of flywheel effect on the growth of technicians
系统设置大页
C# 自定义并动态切换光标
mustache语法
软硬件基础知识学习--小日记(1)
【go】go 实现行专列 将集合进行转列
[Deepin] 常用集合
孙宇晨接受瑞士媒体Bilan采访:熊市不会持续太久
Docker 部署 MySQL 8
图灵奖得主LeCun指明AI未来的出路在于自主学习,这家公司已踏上征途
機器人編程的培訓學科類原理
Pre training / transfer learning of models
Document service design