国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android編程實現捕獲程序異常退出時的錯誤log信息功能詳解

2019-10-22 18:28:50
字體:
來源:轉載
供稿:網友

本文實例講述了Android編程實現捕獲程序異常退出時的錯誤log信息功能。分享給大家供大家參考,具體如下:

很多時候我們程序無緣無故的就掛掉了,讓我們一頭霧水,如果剛好我們在調試,那我們可以通過錯誤log來查看是什么原因引起的程序崩潰。但是當我們把程序發別人使用時,就沒那么好運了,那我們要怎么樣才能捕獲到那個錯誤異常呢?還好Android給我們提供了UncaughtExceptionHandler 這個類,我們可以通過實現這個類的接口,來全局捕獲那個讓程序崩掉的錯誤log信息。可以將錯誤的log保存在本地,也可以發送給服務器后臺。下面來看下UncaughtExceptionHandler 的實現類CrashHandler吧。

CrashHandler.Java

import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;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.SimpleDateFormat;import java.util.Date;import java.util.Locale;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;public class CrashHandler implements UncaughtExceptionHandler { private static final String TAG = CrashHandler.class.getSimpleName(); private static final String SINGLE_RETURN = "/n"; private static final String SINGLE_LINE = "--------------------------------"; private static CrashHandler mCrashHandler; private Context mContext; private UncaughtExceptionHandler mDefaultHandler; private StringBuffer mErrorLogBuffer = new StringBuffer(); /**  * 獲取CrashHandler實例,單例模式。  *  * @return 返回CrashHandler實例  */ public static CrashHandler getInstance() {  if (mCrashHandler == null) {   synchronized (CrashHandler.class) {    if (mCrashHandler == null) {     mCrashHandler = new CrashHandler();    }   }  }  return mCrashHandler; } public void init(Context context) {  mContext = context;  // 獲取系統默認的uncaughtException處理類實例  mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();  // 設置成我們處理uncaughtException的類  Thread.setDefaultUncaughtExceptionHandler(this); } @Override public void uncaughtException(Thread thread, Throwable ex) {  Log.d(TAG, "uncaughtException:" + ex);  if (!handleException(ex) && mDefaultHandler != null) {   // 如果用戶沒有處理異常就由系統默認的異常處理器來處理   mDefaultHandler.uncaughtException(thread, ex);  } else {   try {    Thread.sleep(3000);   } catch (InterruptedException e) {    e.printStackTrace();   }   android.os.Process.killProcess(android.os.Process.myPid());  } } //處理異常事件 private boolean handleException(Throwable ex) {  if (ex == null) {   return false;  }  new Thread(new Runnable() {   @Override   public void run() {    Looper.prepare();    Toast.makeText(mContext, "很抱歉,程序出現異常,即將退出.", Toast.LENGTH_SHORT)      .show();    Looper.loop();   }  }).start();  // 收集設備參數信息  collectDeviceInfo(mContext);  // 收集錯誤日志  collectCrashInfo(ex);  // 保存錯誤日志  saveErrorLog();  //TODO: 這里可以加一個網絡的請求,發送錯誤log給后臺//  sendErrorLog();  return true; } //保存日志到/mnt/sdcard/AppLog/目錄下,文件名已時間yyyy-MM-dd_hh-mm-ss.log的形式保存 private void saveErrorLog() {  if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {   SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh-mm-ss", Locale.getDefault());   String format = sdf.format(new Date());   format += ".log";   String path = Environment.getExternalStorageDirectory().getPath()+"/AppLog/";   File file = new File(path);   if (!file.exists()){    file.mkdirs();   }   FileOutputStream fos = null;   try {    fos = new FileOutputStream(path+format);    fos.write(mErrorLogBuffer.toString().getBytes());    fos.flush();   } catch (FileNotFoundException e) {    e.printStackTrace();   } catch (IOException e) {    e.printStackTrace();   } finally {    if (fos != null) {     try {      fos.close();      fos = null;     } catch (IOException e) {      e.printStackTrace();     }    }   }  } } //收集錯誤信息 private void collectCrashInfo(Throwable ex) {  Writer info = new StringWriter();  PrintWriter printWriter = new PrintWriter(info);  ex.printStackTrace(printWriter);  Throwable cause = ex.getCause();  while (cause != null) {   cause.printStackTrace(printWriter);   cause = cause.getCause();  }  String result = info.toString();  printWriter.close();  //將錯誤信息加入mErrorLogBuffer中  append("", result);  mErrorLogBuffer.append(SINGLE_LINE + SINGLE_RETURN);  Log.d(TAG, "saveCrashInfo2File:" + mErrorLogBuffer.toString()); } //收集應用和設備信息 private void collectDeviceInfo(Context context) {  //每次使用前,清掉mErrorLogBuffer里的內容  mErrorLogBuffer.setLength(0);  mErrorLogBuffer.append(SINGLE_RETURN + SINGLE_LINE + SINGLE_RETURN);  //獲取應用的信息  PackageManager pm = context.getPackageManager();  try {   PackageInfo pi = pm.getPackageInfo(context.getPackageName(),     PackageManager.GET_ACTIVITIES);   if (pi != null) {    append("versionCode", pi.versionCode);    append("versionName", pi.versionName);    append("packageName", pi.packageName);   }  } catch (NameNotFoundException e) {   e.printStackTrace();  }  mErrorLogBuffer.append(SINGLE_LINE + SINGLE_RETURN);  //獲取設備的信息  Field[] fields = Build.class.getDeclaredFields();  getDeviceInfoByReflection(fields);  fields = Build.VERSION.class.getDeclaredFields();  getDeviceInfoByReflection(fields);  mErrorLogBuffer.append(SINGLE_LINE + SINGLE_RETURN); } //獲取設備的信息通過反射方式 private void getDeviceInfoByReflection(Field[] fields) {  for (Field field : fields) {   try {    field.setAccessible(true);    append(field.getName(), field.get(null));   } catch (IllegalArgumentException e) {    e.printStackTrace();   } catch (IllegalAccessException e) {    e.printStackTrace();   }  } } //mErrorLogBuffer添加友好的log信息 private void append(String key, Object value) {  mErrorLogBuffer.append("" + key + ":" + value + SINGLE_RETURN); }}

在application中的使用非常簡單,只要init就好了,之后我們就只要等異常出現吧。

CrashApplication.java

import android.app.Application;public class CrashApplication extends Application{ @Override public void onCreate() {  super.onCreate();  CrashHandler.getInstance().init(this); }}

不要忘記在AndroidManifest.xml聲明我們的CrashApplication 。

AndroidManifest.xml

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><application  android:allowBackup="true"  android:name=".CrashApplication"  android:icon="@drawable/ic_launcher"  android:label="@string/app_name"  android:theme="@style/AppTheme" >  <activity   android:name="com.example.crashtestdemo.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>

希望本文所述對大家Android程序設計有所幫助。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 泰州市| 绥阳县| 上林县| 乐安县| 临沂市| 海口市| 吉木萨尔县| 梁山县| 天气| 邹平县| 吴桥县| 恩施市| 南雄市| 黄骅市| 弥渡县| 陈巴尔虎旗| 沂水县| 永泰县| 龙州县| 平塘县| 卢龙县| 凌源市| 商洛市| 措勤县| 陇川县| 新泰市| 漾濞| 昌宁县| 梨树县| 绿春县| 鹤岗市| 天等县| 托里县| 呼玛县| 巩留县| 鹤岗市| 鞍山市| 介休市| 郁南县| 新田县| 淮滨县|