欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android編程實(shí)現(xiàn)捕獲程序異常退出時(shí)的錯誤log信息功能詳解

 更新時(shí)間:2017年08月31日 11:10:37   作者:QQxiaoqiang1573  
這篇文章主要介紹了Android編程實(shí)現(xiàn)捕獲程序異常退出時(shí)的錯誤log信息功能,結(jié)合實(shí)例形式分析了Android異常信息捕獲與日志操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下

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

很多時(shí)候我們程序無緣無故的就掛掉了,讓我們一頭霧水,如果剛好我們在調(diào)試,那我們可以通過錯誤log來查看是什么原因引起的程序崩潰。但是當(dāng)我們把程序發(fā)別人使用時(shí),就沒那么好運(yùn)了,那我們要怎么樣才能捕獲到那個錯誤異常呢?還好Android給我們提供了UncaughtExceptionHandler 這個類,我們可以通過實(shí)現(xiàn)這個類的接口,來全局捕獲那個讓程序崩掉的錯誤log信息。可以將錯誤的log保存在本地,也可以發(fā)送給服務(wù)器后臺。下面來看下UncaughtExceptionHandler 的實(shí)現(xiàn)類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實(shí)例,單例模式。
  *
  * @return 返回CrashHandler實(shí)例
  */
 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;
  // 獲取系統(tǒng)默認(rèn)的uncaughtException處理類實(shí)例
  mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
  // 設(shè)置成我們處理uncaughtException的類
  Thread.setDefaultUncaughtExceptionHandler(this);
 }
 @Override
 public void uncaughtException(Thread thread, Throwable ex) {
  Log.d(TAG, "uncaughtException:" + ex);
  if (!handleException(ex) && mDefaultHandler != null) {
   // 如果用戶沒有處理異常就由系統(tǒng)默認(rèn)的異常處理器來處理
   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, "很抱歉,程序出現(xiàn)異常,即將退出.", Toast.LENGTH_SHORT)
      .show();
    Looper.loop();
   }
  }).start();
  // 收集設(shè)備參數(shù)信息
  collectDeviceInfo(mContext);
  // 收集錯誤日志
  collectCrashInfo(ex);
  // 保存錯誤日志
  saveErrorLog();
  //TODO: 這里可以加一個網(wǎng)絡(luò)的請求,發(fā)送錯誤log給后臺
//  sendErrorLog();
  return true;
 }
 //保存日志到/mnt/sdcard/AppLog/目錄下,文件名已時(shí)間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());
 }
 //收集應(yīng)用和設(shè)備信息
 private void collectDeviceInfo(Context context) {
  //每次使用前,清掉mErrorLogBuffer里的內(nèi)容
  mErrorLogBuffer.setLength(0);
  mErrorLogBuffer.append(SINGLE_RETURN + SINGLE_LINE + SINGLE_RETURN);
  //獲取應(yīng)用的信息
  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);
  //獲取設(shè)備的信息
  Field[] fields = Build.class.getDeclaredFields();
  getDeviceInfoByReflection(fields);
  fields = Build.VERSION.class.getDeclaredFields();
  getDeviceInfoByReflection(fields);
  mErrorLogBuffer.append(SINGLE_LINE + SINGLE_RETURN);
 }
 //獲取設(shè)備的信息通過反射方式
 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就好了,之后我們就只要等異常出現(xiàn)吧。

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>

更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Android開發(fā)入門與進(jìn)階教程》、《Android調(diào)試技巧與常見問題解決方法匯總》、《Android編程之a(chǎn)ctivity操作技巧總結(jié)》、《Android操作json格式數(shù)據(jù)技巧總結(jié)》、《Android數(shù)據(jù)庫操作技巧總結(jié)》、《Android文件操作技巧匯總》、《Android資源操作技巧匯總》及《Android控件用法總結(jié)

希望本文所述對大家Android程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • Android 8.1隱藏狀態(tài)欄圖標(biāo)的實(shí)例代碼

    Android 8.1隱藏狀態(tài)欄圖標(biāo)的實(shí)例代碼

    這篇文章主要介紹了Android 8.1隱藏狀態(tài)欄圖標(biāo),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-04-04
  • 如何在Android中實(shí)現(xiàn)左右滑動的指引效果

    如何在Android中實(shí)現(xiàn)左右滑動的指引效果

    本篇文章是對在Android中實(shí)現(xiàn)左右滑動指引效果的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • Android使用WebView實(shí)現(xiàn)全屏切換播放網(wǎng)頁視頻功能

    Android使用WebView實(shí)現(xiàn)全屏切換播放網(wǎng)頁視頻功能

    這篇文章主要介紹了Android使用WebView實(shí)現(xiàn)全屏切換播放網(wǎng)頁視頻功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2019-07-07
  • Android網(wǎng)絡(luò)判斷知識小結(jié)

    Android網(wǎng)絡(luò)判斷知識小結(jié)

    本文通過兩段實(shí)例代碼分別給大家介紹Android中判斷當(dāng)前網(wǎng)絡(luò)是否可用和Android 關(guān)于判斷應(yīng)用是否有網(wǎng)絡(luò)的相關(guān)知識,對android網(wǎng)絡(luò)判斷相關(guān)知識感興趣的朋友一起學(xué)習(xí)吧
    2015-12-12
  • Android貝塞爾曲線實(shí)現(xiàn)加入購物車拋物線動畫

    Android貝塞爾曲線實(shí)現(xiàn)加入購物車拋物線動畫

    這篇文章主要為大家詳細(xì)介紹了Android貝塞爾曲線實(shí)現(xiàn)加入購物車拋物線動畫,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • Android自定義標(biāo)尺滑動選擇值效果

    Android自定義標(biāo)尺滑動選擇值效果

    這篇文章主要為大家詳細(xì)介紹了Android自定義標(biāo)尺滑動選擇值效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-09-09
  • android監(jiān)聽安裝和卸載示例

    android監(jiān)聽安裝和卸載示例

    Android應(yīng)用程序的安裝和卸載事件,是由系統(tǒng)進(jìn)行監(jiān)聽并全局廣播的,支持1.5(android 3)以上,因此,如果想要監(jiān)聽獲取應(yīng)用的安裝和卸載事件,只需要自定義一個BroadcastReceiver,來對系統(tǒng)廣播進(jìn)行監(jiān)聽和處理
    2014-02-02
  • Android開源庫自定義相機(jī)模塊

    Android開源庫自定義相機(jī)模塊

    這篇文章主要為大家詳細(xì)介紹了Android開源庫自定義相機(jī)模塊,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • Android實(shí)現(xiàn)圖片疊加功能

    Android實(shí)現(xiàn)圖片疊加功能

    本篇文章主要介紹了Android實(shí)現(xiàn)圖片疊加功能的代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-04-04
  • AndroidStudio修改Code Style來格式化自定義標(biāo)簽的xml文件方式

    AndroidStudio修改Code Style來格式化自定義標(biāo)簽的xml文件方式

    這篇文章主要介紹了AndroidStudio修改Code Style來格式化自定義標(biāo)簽的xml文件方式,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-03-03

最新評論