StrictMode 严格模式

StrictMode 严格模式

开发者经常会无意地犯些错误:在主线程读写磁盘、访问网络,严格模式能够把帮助开发者监控这些错误。

注意:严格模式是一种保护机制但是并不保证找出所有的磁盘和网络访问。因为严格模式经常在发生Binder Call的时候报告自己的状态,所以它是一种尽力而为的机制。一般地,网络和磁盘访问一般走JNI调用,所以不一定会触发它。还有一点,线上的应用不应该开启严格模式。

代码示例:
 public void onCreate() {
     if (DEVELOPER_MODE) {
         StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                 .detectDiskReads()
                 .detectDiskWrites()
                 .detectNetwork()   // or .detectAll() for all detectable problems
                 .penaltyLog()
                 .build());
         StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                 .detectLeakedSqlLiteObjects()
                 .detectLeakedClosableObjects()
                 .penaltyLog()
                 .penaltyDeath()
                 .build());
     }
     super.onCreate();
 }

严格模式下的两种策略

StrictMode.ThreadPolicy(作用于特定线程)
主要监控以下内容:
  Disk Reads 磁盘读
  Disk Writes 磁盘写
  Network access 网络访问
  Custom Slow Code 自定义的运行速度慢的代码分析

StrictMode.VmPolicy(作用于整个虚拟机进程的所有线程)
主要监控以下内容:
  内存泄露的Activity对象
  内存泄露的SQLite对象
  内存泄露的释放的对象
  内存泄漏的BroadcastReceiver or ServiceConnection

严格模式监控到异常信息触发的提示

Log 日志
  Death 应用退出
  DropBox 持久化的、系统级别的Logcat

测试

代码

package com.jinglong.strickmodetest;

    import android.os.Bundle;
    import android.os.Environment;
    import android.os.StrictMode;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;

    import java.io.File;
    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.IOException;

    public class MainActivity extends AppCompatActivity {

        public static final String STRICK_MODE_TEST = "StrickModeTest";
        public static final String TAG = STRICK_MODE_TEST + ":" +MainActivity.class.getName();
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build());
            StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().penaltyLog().build());
            File externalStorageDirectory = Environment.getExternalStorageDirectory();
            if (externalStorageDirectory==null||!externalStorageDirectory.exists()){
                Log.d(TAG,"SDCard is not exist");
            }else{
                //获取SD卡下的文件或目录
                String[] childrenFiles = externalStorageDirectory.list();
                for (int i = 0;i < childrenFiles.length;i++){
                    File childFile = new File(externalStorageDirectory.getPath(),childrenFiles[i]);
                    if (childFile.exists()&&childFile.isFile()){
                        //找到第一个File
                        try {
                            FileReader fr = new FileReader(childFile);
                            char ch[] = new char[1024] ;
                            while (fr.read(ch)!=-1){
                                Log.e(TAG,new String(ch));
                            }
                            //为了测试效果,此处不关fr

                            FileWriter fw = new FileWriter(childFile);
                            fw.write("Hello 璟龙");
                            fw.flush();
                            //为了测试效果,此处不关fw
                            
                            break;
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

日志

  • 第一条日志表示资源没有关闭,即IO流未关闭
  • 第二条日志表示在主线程中发生了磁盘访问的读操作
07-18 15:05:26.930 10735-10748/com.jinglong.strickmodetest E/StrictMode: A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks.
07-18 15:05:26.949 10735-10735/com.jinglong.strickmodetest D/StrictMode: StrictMode policy violation; ~duration=44 ms: android.os.StrictMode$StrictModeDiskReadViolation: policy=31 violation=2

你可能感兴趣的:(StrictMode 严格模式)