Android系统获取应用的Crash信息

hiyounger 8年前
   <p>Android应用不可避免的都会发生crash,即程序崩溃</p>    <p>可能是系统或程序有bug等内部原因,或者是网络状况不佳等外部原因</p>    <p>当应用发生crash时,如果只是你一个人使用的应用,那自然容易检测出原因,可是如果应用有广泛的使用者,面对市面上众多的Rom和机型,就需要一个个获取发生crash时的系统情况了,将异常信息记录下来并发送到服务器,供开发者了解情况并调试</p>    <p>Android提供有默认的异常处理方法,也可以自定义异常处理方法</p>    <p>在Thread类下有如下方法用来设置自定义异常处理器</p>    <pre>  <code class="language-java">public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler handler) {      Thread.defaultUncaughtHandler = handler;  }</code></pre>    <p>当crash发生时,系统会回调UncaughtExceptionHandler的如下方法,我们就需要来重写该方法</p>    <pre>  <code class="language-java">public void uncaughtException(Thread thread, Throwable throwable){    }</code></pre>    <p>因此,现在需要进行的步骤是:</p>    <p><strong>1. 实现Thread.UncaughtExceptionHandler接口,自定义异常处理器</strong></p>    <p><strong>2. 重写uncaughtException方法</strong></p>    <p><strong>3. 在uncaughtException方法中将crash信息以及当前手机信息保存到文本中,然后将文本打包发送到服务器</strong></p>    <p>新建CrashHandler类继承于Thread.UncaughtExceptionHandler</p>    <pre>  <code class="language-java">/**   * Crash处理 CZY   * Created by ZY on 2016/8/27.   */  public class CrashHandler implements Thread.UncaughtExceptionHandler {        //定义文件存放路径      private static final String PATH = Environment.getExternalStorageDirectory().getPath() + "/CrashInfo/";        //定义文件后缀      private static final String FILE_NAME_SUFFIX = ".txt";        //系统默认的异常处理器      private Thread.UncaughtExceptionHandler defaultCrashHandler;        private static final String TAG = "CrashHandler";        private static CrashHandler crashHandler = new CrashHandler();        //私有化构造函数      private CrashHandler() {      }        //获取实例      public static CrashHandler getInstance() {          return crashHandler;      }        public void init() {          defaultCrashHandler = Thread.getDefaultUncaughtExceptionHandler();          //设置系统的默认异常处理器          Thread.setDefaultUncaughtExceptionHandler(this);      }        @Override      public void uncaughtException(Thread thread, Throwable throwable) {          //记录异常信息到本地文本中          dumpExceptionToSDCard(throwable);          if (defaultCrashHandler != null) {              //如果在自定义异常处理器之前,系统有自己的默认异常处理器的话,调用它来处理异常信息              defaultCrashHandler.uncaughtException(thread, throwable);          } else {              Process.killProcess(Process.myPid());          }      }        //记录异常信息到本地文本中      private void dumpExceptionToSDCard(Throwable throwable) {          //如果SD卡非正常挂载,则用Log输出异常信息          if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {              Log.e(TAG, "SD卡出错");              return;          }          File dir = new File(PATH);          if (!dir.exists()) {              dir.mkdirs();          }          long currentTime = System.currentTimeMillis();          String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(currentTime));          //建立记录Crash信息的文本          File file = new File(PATH + time + FILE_NAME_SUFFIX);          try {              PrintWriter printWriter = new PrintWriter(new BufferedWriter(new FileWriter(file)));              printWriter.println(time);              dumpPhoneInfo(printWriter);              printWriter.println();              throwable.printStackTrace(printWriter);              printWriter.close();          } catch (Exception e) {              e.printStackTrace();              Log.e(TAG, "记录Crash信息失败");          }      }        //记录手机信息      private void dumpPhoneInfo(PrintWriter printWriter) {          //系统版本号          printWriter.print("OS Version:");          printWriter.print(Build.VERSION.RELEASE);          printWriter.print("_");          printWriter.println(Build.VERSION.SDK_INT);          //硬件制造商          printWriter.print("Vendor:");          printWriter.println(Build.MANUFACTURER);          //系统定制商          printWriter.print("Brand:");          printWriter.println(Build.BRAND);      }    }</code></pre>    <p>采用了单例模式,每个方法的作用也都注释了其作用</p>    <p>然后,选择在Application中初始化CrashHandler</p>    <p>所以需要自定义Application</p>    <pre>  <code class="language-java">/**   * Created by ZY on 2016/8/27.   */  public class MyApplication extends Application {        @Override      public void onCreate() {          super.onCreate();          CrashHandler crashHandler = CrashHandler.getInstance();          crashHandler.init();      }    }</code></pre>    <p>需要在AndroidManifest.xml文件中声明之</p>    <p>即在application标签下添加以下一行语句</p>    <pre>  <code class="language-java">android:name=".MyApplication"</code></pre>    <p>此外,因为还涉及到了内存卡写操作,所以需要声明下权限</p>    <pre>  <code class="language-java"><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /></code></pre>    <p>然后,在主布局文件中声明个按钮,在点击后抛出一个自定义异常</p>    <pre>  <code class="language-java">findViewById(R.id.crashTest).setOnClickListener(new View.OnClickListener() {              @Override              public void onClick(View v) {                  throw new RuntimeException("自定义异常");              }          });</code></pre>    <p>点击后程序异常退出,打开手机的文件内容管理器</p>    <p>可以看到多了一个CrashInfo文件夹</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/30c92e3550cf8b6c70717881a46e6628.png"></p>    <p style="text-align: center;">这里写图片描述</p>    <p>保存异常信息的文件</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/e8cfc3ed0dcc0fa97f0c13012101dbf1.png"></p>    <p style="text-align: center;">这里写图片描述</p>    <p>异常信息</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/9dd66a62e03afe5d15ef13f3800a0189.png"></p>    <p style="text-align: center;">这里写图片描述</p>    <p>这要,就获取到了异常信息,这里只是将信息保存到了SD卡上,在实际开发中再添加上传到服务器的操作即可</p>    <p> </p>    <p>来自:http://www.jianshu.com/p/780b222185ea</p>    <p> </p>