首页 > 编程知识 正文

浅谈有与无,functional morpheme

时间:2023-05-06 11:33:25 阅读:63290 作者:3280

开场在日常开发中,或多或少地涉及到了运行缓慢、ANR等性能问题。 做好工作首先要利其器。 本文介绍了严格模式在安卓开发中的作用。

严格模式定义严格模式(严格模式)是一种开发工具,工程师可以在其中检测意外错误,并注意到UI更改可能会导致错误。 严格模式通常用于捕获APP应用程序主线程中意外的硬盘io或网络io。 将硬盘读写和网络操作与主线程分离后,程序更顺畅,响应速度更快,摆脱了ANR的困扰。

注意: Android设备的硬盘通常是闪存存储,许多设备很少同时在存储顶部运行文件系统。 一般来说,硬盘的IO非常快,大多数情况下,在后台进程中运行IO时会特别慢。 我们一般应该假设很晚。 这更合适。

具体能检测出什么样的严格模式主要是检测出两大问题。 一个是线程策略,即TreadPolicy,另一个是虚拟机策略,即虚拟机策略。

线程策略发现的内容包括

使用detectCustomSlowCalls ()打开自定义需要时间的调用

使用detectDiskReads ()打开磁盘读取操作

使用detectDiskWrites ()打开对磁盘的写入

网络操作在detectNetwork ()中打开

虚拟机策略检查的内容包括

在detectActivityLeaks ()中启用活动泄漏

未关闭的Closable对象泄漏是使用detectLeakedClosableObjects ()打开的

使用detectLeakedSqlLiteObjects ()打开遗漏的Sqlite对象

使用setClassInstanceLimit ()打开检查实例数

工作原理其实严格模式的实现原理也比较简单,以IO操作为例,主要是在打开、读取、写入、关闭时监测。 libcore.io.BlockGuardOs文件是监视的位置。 以open为例,监视如下。

@ overridepublicfiledescriptoropen (字符串路径、int flags、int mode ) throwserrnoexception { block guard.getthreadpolicy }=o _ rd only (block guard.getthreadpolicy ) (.onWriteToDisk ); }returnOS.open(path,flags,mode ); }

其中onReadFromDisk ) )方法的实现,代码位于StrictMode.Java中。

public void onReadFromDisk () if ) ) mpolicymaskdetect_disk_read )==0) { return; (if ) toomanyviolationsthisloop ) ) { return; } block guard.blockguardpolicyexceptione=newstrictmodediskreadviolation (mpolicymask; e.fillin堆栈跟踪(; sarthandlingviolationexception (e; }

使用示例:

public void onCreate () if ) developer_mode ) strict mode.setthreadpolicy (newstrictmode.thread policy.builder ) ) )。 detectnetwork(/or.detectall ) ) foralldetectableproblems.penalty log ).build ); 严格模式. setvmpolicy (newstrictmode.VM policy.builder (.detectleakedsqlliteobjects ).detectLeakedClosableObjects )

tyLog() .penaltyDeath() .build()); } super.onCreate();}

异常捕获、查看结果

严格模式有很多种报告违例的形式,但是想要分析具体违例情况,还是需要查看日志,终端下过滤StrictMode就能得到违例的具体stacktrace信息。

adb logcat | grep StrictMode

日志的时间靠谱么

在下面的过滤日志中,我们看到下面的一个IO操作要消耗31毫秒,这是真的么

D/StrictMode( 2921): StrictMode policy violation; ~duration=31 ms: android.os.StrictMode$StrictModeDiskReadViolation: policy=31 violation=2D/StrictMode( 2921): at android.os.StrictMode$AndroidBlockGuardPolicy.onReadFromDisk(StrictMode.java:1176)D/StrictMode( 2921): at libcore.io.BlockGuardOs.read(BlockGuardOs.java:148)D/StrictMode( 2921): at libcore.io.IoBridge.read(IoBridge.java:422)D/StrictMode( 2921): at java.io.FileInputStream.read(FileInputStream.java:179)D/StrictMode( 2921): at java.io.InputStreamReader.read(InputStreamReader.java:244)D/StrictMode( 2921): at java.io.BufferedReader.fillBuf(BufferedReader.java:130)D/StrictMode( 2921): at java.io.BufferedReader.readLine(BufferedReader.java:354)D/StrictMode( 2921): at com.example.strictmodedemo.MainActivity.testReadContentOfFile(MainActivity.java:65)D/StrictMode( 2921): at com.example.strictmodedemo.MainActivity.onCreate(MainActivity.java:28)D/StrictMode( 2921): at android.app.Activity.performCreate(Activity.java:4543)

从上面的stacktrace可以看出testReadContentOfFile方法中包含了文件读取IO操作,至于是否为31毫秒,我们可以利用秒表的原理计算一下,即在方法调用的地方如下记录

long startTime = System.currentTimeMillis();testReadContentOfFile();long cost = System.currentTimeMillis() - startTime;Log.d(LOGTAG, "cost = " + cost);

得到的日志中上述操作耗时9毫秒,非31毫秒。


D/MainActivity(20996): cost = 9

---注:通常情况下StrictMode给出的耗时相对实际情况偏高,并不是真正的耗时数据---


特别需要注意的理念

ssdkfd发现一个异常的时候. 比如你通过adb logcat看到了penaltvLog()打出来的log.
你可以用: threads, Handler, AsyncTask, IntentService等尝试修复它. 特别注意别惦记着要修复所有StrictMode找到的点. 在正常活动生命周期中,许多情况下磁盘访问通常是必要的.不过利用StrictMode找到的在UI线程上的网络请求几乎都的确是一个问题。
StrictMode是不是一个安全机制并不能保证发现所有的磁盘或网络访问。
在Bindercalls时跨进程通信的状态下,它还是很有效的一种机制。
从磁盘或网络访问调用JNI不会触发。

1. http://droidyue.com/blog/2015/09/26/android-tuning-tool-strictmode/

2. http://www.bubuko.com/infodetail-1819517.html

3. http://tech.it168.com/a2011/0908/1243/000001243936_all.shtml



版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。