(十三)Android性能优化StrictMode

(十三)Android性能优化StrictMode

2023年6月27日发(作者:)

(⼗三)Android性能优化StrictMode⼩酌鸡汤富贵必从勤苦得,男⼉须读五车书。本⽂来源《Android 性能优化 全家桶》StrictMode能检测什么呢? StrictMode主要检测两⼤问题:线程策略(TreadPolicy)和VM策略(VmPolicy)。StrictMode的⼯作原理? StrictMode最常⽤于在应⽤程序的主线程上捕获意外的磁盘或⽹络访问,在该线程上接收UI操作并进⾏动画处理。使磁盘和⽹络操作脱离主线程可以使应⽤程序更加流畅,响应更快。通过使应⽤程序的主线程保持响应状态,还可以防⽌向⽤户显⽰ANR对话框。请注意,即使Android设备的磁盘通常位于闪存中,但许多设备在该内存之上运⾏⽂件系统的并发性⾮常有限。通常情况下,⼏乎所有磁盘访问都是快速的,但是在某些情况下,某些进程在后台发⽣某些I / O时,访问速度可能会⼤⼤降低。如果可能的话,最好假设这种情况并不快。ThreadPolicy线程策略检测所有可能的问题,使⽤detectAll()开启;调⽤速度缓慢的检测,使⽤detectCustomSlowCalls()开启;磁盘读取操作,使⽤detectDiskReads()开启;磁盘写⼊操作,使⽤detectDiskWrites()开启;⽹络操作,使⽤detectNetwork()开启;检测已定义资源类型和getter调⽤之间的不匹配的功能,使⽤detectResourceMismatches()开启;检测未缓冲的输⼊/输出操作,使⽤detectUnbufferedIo()开启。VmPolicy虚拟机策略检测所有可能的问题,使⽤detectAll()开启;检测Activity泄漏,使⽤detectActivityLeaks()开启;权限检测,detectContentUriWithoutPermission()开启;未关闭的Closable对象泄漏,使⽤detectLeakedClosableObjects()开启;泄漏的Sqlite对象,使⽤detectLeakedSqlLiteObjects()开启;检测实例数量,使⽤setClassInstanceLimit()开启。等等……StrictMode的使⽤原则和技巧 以名称开头的⽅法detect指定了我们应该寻找的问题。以名称开头的⽅法penalty指定了检测到问题时应采取的措施。 可以根据需要调⽤任意多个detect和penalty⽅法。顺序微不⾜道:所有措施都适⽤于所有检测到的问题。StrictMode如何使⽤? 在Application,Activity或其他应⽤程序组件te() ⽅法执⾏前,添加StrictMode检测。public void onCreate() { if (DEVELOPER_MODE) { eadPolicy(new () .detectDiskReads() .detectDiskWrites() .detectNetwork() // or .detectAll() for all detectable problems .penaltyLog() .build()); olicy(new () .detectLeakedSqlLiteObjects() .detectLeakedClosableObjects() .penaltyLog() .penaltyDeath() .build()); } te(); }如果观测结果呢?AS IDE中的logat中筛选StrictMode信息adb logcat 进⾏筛选StrictMode信息现在,就⼀起实操体验 StrictMode 吧~现在,就⼀起实操体验 StrictMode 吧~(1)StrictMode实操环境(可选项,⽤⾃⼰的环境和代码也⼀样)SamplePop代码下载SamplePop环境如下: Android Studio 4.0 Gradle version 6.1.1 Android API version 30(2)举个栗⼦:主线程中的⽂件写⼊的检查(2.1)代码启⽤全部的ThreadPolicy和VmPolicy违例检测public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { //代码启⽤全部的ThreadPolicy和VmPolicy违例检测 eadPolicy(new r().detectAll().penaltyLog().build()); olicy(new r().detectAll().penaltyLog().build()); te(savedInstanceState); setContentView(ty_main); //执⾏模拟测试 writeToFileInMainThread(); } /** * 主线程写⽂件 */ public void writeToFileInMainThread() { File destFile = new File(ernalStoragePublicDirectory (ORY_DOWNLOADS).getPath(), ""); try { NewFile(); table(true); OutputStream output = new FileOutputStream(destFile, true); ("IO operation".getBytes()); (); (); } catch (Exception e) { tackTrace(); } }}(2.2)运⾏应⽤,观察logcat的输出:StrictMode 主线程写⽂件(2.3)解决StrictMode检查错误 /** * ⼦线程写⽂件 */ public void writeToFileInSubThread() { new Thread(new Runnable() { @Override public void run() { writeToFileInMainThread(); } }).start(); }(3)举个栗⼦:内存泄漏的检查(3.1)让LeakActivity产⽣内存泄漏public class LeakActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { te(savedInstanceState); setContentView(ty_leak); tance().(this); }}(3.2)ActivityManager中关于mActivities的部分实现public class ActivityManager { private static ActivityManager mInstance = new ActivityManager(); public ArrayList mActivities = new ArrayList<>(); private ActivityManager(){ } public static ActivityManager getInstance() { return mInstance; }}(3.3)引发内存泄漏 不断从MainActivity打开LeakActivity,再返回,再打开,如此反复操作,引发内存泄漏。 public void onLeakActivityStart(View view) { Log.d(TAG, "onLeakActivityStart: "); startActivity(new Intent(this, )); }(3.4)运⾏应⽤,观察logcat的输出:StrictMode 内存泄漏(4)举个栗⼦:⾃定义检测类的实例泄漏(4.1)开启实例检测,当LeakActivity类出现多于⼀个实例时,就报告内存泄漏olicy(new r().setClassInstanceLimit(, 1).penaltyLog().build());(4.2)运⾏应⽤,观察logcat的输出:StrictMode 实例检测(5)举个栗⼦:耗时调⽤(noteSlowCall)(5.1)耗时调⽤检测,适⽤于⾃定义的任务执⾏类中,⽐如:public class FastRunTask { private static final int MAX_RUN_VALID_DURATION = 300; public void execute(Runnable task) { long startTime = Millis(); (); long useTime = Millis() - startTime; if (useTime > MAX_RUN_VALID_DURATION) { owCall("FastRunTask note slow call use time : [" + useTime + "]"); } }}(5.2)执⾏耗时任务: public void onFastRunTask(View view) { Log.d(TAG, "onFastRunTask: "); FastRunTask fastRunTask = new FastRunTask(); e(new Runnable() { @Override public void run() { try { (500); } catch (InterruptedException e) { tackTrace(); } } }); }(5.3)运⾏应⽤,观察logcat的输出:StrictMode 耗时调⽤(6)StrictMode⼩结主要作⽤:查找可能会长时间运⾏的操作,例如您可能会⽆意中在主线程中执⾏的⽹络或数据库操作。注意项: StrictMode⽆法监控JNI中的磁盘IO和⽹络请求 应⽤中并⾮需要解决全部的违例情况,⽐如有些IO操作必须在主线程中进⾏。 通常情况下StrictMode给出的耗时相对实际情况偏⾼,并不是真正的耗时数据。如何修复问题:如果你发现你的感觉有问题的违规⾏为,有各种各样的⼯具来帮助解决这些问题:线程,Handler,AsyncTask,IntentService等。注意:StrictMode不是安全机制,不能保证找到所有磁盘或⽹络访问。尽管在执⾏Binder调⽤时确实跨进程边界传播了状态,但它最终仍是尽⼒⽽为的机制。未来的Android版本可能会执⾏更多(或更少)操作,因此您永远不要在发布的应⽤程序中启⽤StrictMode。⼀起来启⽤ StrictModel 查看⾃⼰的项⽬吧~⼩编的扩展链接SamplePop代码下载《Android 性能优化 全家桶》参考链接⾕歌官⽹ -> 这是应该读的第⼀篇⽂章状似明⽉泛云河,体如轻风动流波 举⼿之劳,赞有余⾹! ⽐⼼ ❤  ❤

发布者:admin,转转请注明出处:http://www.yc00.com/web/1687842450a50025.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信