Android 对程序异常崩溃的捕捉 转载 + 自己修改+自己写的Demo

来源:互联网 发布:焦作青峰网络 编辑:程序博客网 时间:2024/06/08 02:26

转载:http://blog.csdn.net/i_lovefish/article/details/17719081


我自己写的Demo:http://pan.baidu.com/s/1gfFpq8N

1.以下为异常捕捉处理代码

import java.io.BufferedReader;  import java.io.File;  import java.io.FileInputStream;  import java.io.FileNotFoundException;  import java.io.FileOutputStream;  import java.io.IOException;  import java.io.InputStreamReader;  import java.io.PrintWriter;  import java.io.StringWriter;  import java.io.Writer;  import java.lang.Thread.UncaughtExceptionHandler;  import java.lang.reflect.Field;  import java.text.DateFormat;  import java.text.SimpleDateFormat;  import java.util.Date;  import java.util.HashMap;  import java.util.Map;    import android.content.Context;  import android.content.pm.PackageInfo;  import android.content.pm.PackageManager;  import android.content.pm.PackageManager.NameNotFoundException;  import android.os.Build;  import android.os.Environment;  import android.os.Looper;  import android.util.Log;  import android.widget.Toast;        /**    * UncaughtException处理类,当程序发生Uncaught异常的时候,有该类来接管程序,并记录发送错误报告.   *   *  需要在Application中注册,为了要在程序启动器就监控整个程序。  */      public class CrashHandler implements UncaughtExceptionHandler {                    public static final String TAG = "CrashHandler";              /** 崩溃异常日志保存路径:*/    private String path = "/storage/emulated/0/ZhaiDaiSource/crash/"; //    private String path = "/mnt/sdcard/crash/";     private String preFileName = "ExceptionCatch_Save_Send";               //系统默认的UncaughtException处理类           private Thread.UncaughtExceptionHandler mDefaultHandler;          //CrashHandler实例          private static CrashHandler instance;     //程序的Context对象          private Context mContext;          //用来存储设备信息和异常信息          private Map<String, String> infos = new HashMap<String, String>();                //用于格式化日期,作为日志文件名的一部分          private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");                /** 保证只有一个CrashHandler实例 */          private CrashHandler() {}                /** 获取CrashHandler实例 ,单例模式 */          public static CrashHandler getInstance() {              if(instance == null)              instance = new CrashHandler();             return instance;          }                /**        * 初始化        */          public void init(Context context) {              mContext = context;              //获取系统默认的UncaughtException处理器              mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();              //设置该CrashHandler为程序的默认处理器              Thread.setDefaultUncaughtExceptionHandler(this);          }                /**        * 当UncaughtException发生时会转入该函数来处理        */          @Override          public void uncaughtException(Thread thread, Throwable ex) {            if (!handleException(ex) && mDefaultHandler != null) {                  //如果用户没有处理则让系统默认的异常处理器来处理                  mDefaultHandler.uncaughtException(thread, ex);              } else {                  try {                      Thread.sleep(3000);                  } catch (InterruptedException e) {                      Log.e(TAG, "error : ", e);                  }                  //退出程序                  android.os.Process.killProcess(android.os.Process.myPid());                  System.exit(1);         }          }                    /**        * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.        *         * @param ex        * @return true:如果处理了该异常信息;否则返回false.        */          private boolean handleException(Throwable ex) {              if (ex == null) {                  return false;              }                Log.e(TAG, "error : ", ex);            //收集设备参数信息               collectDeviceInfo(mContext);                        //使用Toast来显示异常信息              new Thread() {                  @Override                  public void run() {                      Looper.prepare();                      Toast.makeText(mContext, "很抱歉,程序出现异常,即将退出.", Toast.LENGTH_SHORT).show();                      Looper.loop();                  }              }.start();              //保存日志文件               saveCatchInfo2File(ex);            return true;          }                    /**        * 收集设备参数信息        * @param ctx        */          public void collectDeviceInfo(Context ctx) {              try {                  PackageManager pm = ctx.getPackageManager();                  PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES);                  if (pi != null) {                String versionName = pi.versionName == null ? "null" : pi.versionName;                      String versionCode = pi.versionCode + "";                      infos.put("versionName", versionName);                      infos.put("versionCode", versionCode);                  }              } catch (NameNotFoundException e) {            Log.e(TAG, "an error occured when collect package info", e);              }              Field[] fields = Build.class.getDeclaredFields();              for (Field field : fields) {                  try {                      field.setAccessible(true);                      infos.put(field.getName(), field.get(null).toString());                      Log.d(TAG, field.getName() + " : " + field.get(null));                  } catch (Exception e) {                      Log.e(TAG, "an error occured when collect crash info", e);                  }              }          }                /**        * 保存错误信息到文件中        *         * @param ex        * @return  返回文件名称,便于将文件传送到服务器        */          private String saveCatchInfo2File(Throwable ex) {                      StringBuffer sb = new StringBuffer();              for (Map.Entry<String, String> entry : infos.entrySet()) {                  String key = entry.getKey();                  String value = entry.getValue();                  sb.append(key + "=" + value + "\n");              }                            Writer writer = new StringWriter();              PrintWriter printWriter = new PrintWriter(writer);              ex.printStackTrace(printWriter);              Throwable cause = ex.getCause();              while (cause != null) {                  cause.printStackTrace(printWriter);                  cause = cause.getCause();              }              printWriter.close();              String result = writer.toString();              sb.append(result);              try {                  long timestamp = System.currentTimeMillis();                  String time = formatter.format(new Date());                  String fileName = preFileName + time + "-" + timestamp + ".log";                          /*使用SDcard_and_InnerStore.java 类获取 路径 就不需要这个判断了*/            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {      //                String path = "/mnt/sdcard/crash/";                   File dir = new File(path);                      if (!dir.exists()) {                          dir.mkdirs();                      }                      FileOutputStream fos = new FileOutputStream(path + fileName);                      fos.write(sb.toString().getBytes());                    //发送给开发人员                  sendCrashLog2PM(path+fileName);                  fos.close();                  }                  return fileName;              } catch (Exception e) {                  Log.e(TAG, "an error occured while writing file...", e);              }              return null;          }                /**      * 将捕获的导致崩溃的错误信息发送给开发人员      *       * 目前只将log日志保存在sdcard 和输出到LogCat中,并未发送给后台。      */      private void sendCrashLog2PM(String fileName){          if(!new File(fileName).exists()){              Toast.makeText(mContext, "日志文件不存在!", Toast.LENGTH_SHORT).show();              return;          }          FileInputStream fis = null;          BufferedReader reader = null;          String s = null;          try {              fis = new FileInputStream(fileName);              reader = new BufferedReader(new InputStreamReader(fis, "GBK"));              while(true){                  s = reader.readLine();                  if(s == null) break;                  //由于目前尚未确定以何种方式发送,所以先打出log日志。                  Log.i("info", s.toString());              }          } catch (FileNotFoundException e) {              e.printStackTrace();          } catch (IOException e) {              e.printStackTrace();          }finally{   // 关闭流              try {                  reader.close();                  fis.close();              } catch (IOException e) {                  e.printStackTrace();              }          }      }  } 

2.BaseApplication

import android.app.Application;import android.content.Context;public class CatchExceptionApplication extends Application {@Overridepublic void onCreate() {super.onCreate();CrashHandler catchHandler = CrashHandler.getInstance();catchHandler.init(getApplicationContext());}}

3. 清单文件添加application和权限

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.exceptioncatch_save_send"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="14"        android:targetSdkVersion="22" />    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>        <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme"         android:name="com.example.exceptioncatch_save_send.base.CatchExceptionApplication">        <activity            android:name=".MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application></manifest>

======================================================

4.代码校验:

import java.io.File;import com.example.exceptioncatch_save_send.utils.SDCard_and_InnerStore;import android.app.Activity;import android.os.Bundle;public class MainActivity extends Activity {  private String s;  @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);String sdorInner=SDCard_and_InnerStore.getSDorInStore(this) + File.separator +"ZhaiDaiSource" + File.separator + "head.jpg";System.out.println("sdorInner = "+sdorInner);System.out.println(s.equals("hello")); }}





0 0
原创粉丝点击