Android应用捕获全局异常自定义处理
[2016-06-30]最新的全局异常处理DRCrashHandler已经集成在DR_support_lib库中
具体请看: https://coding.net/u/wrcold520/p/DR_support_lib/git/tree/master
[2016-06-28] 1 增加log4j的支持
[2016-06-28] 2 增加全局异常处理(可自定义程序崩溃提示消息,自定义发送错误报告到服务器)
[2016-06-28] 3 增加两种应用退出方法:① appExit,结束掉所有Acitivity的生命周期,正常退出;② appKill,结束掉所有Acitivity的生命周期,杀掉程序进程后退出。
[2016-06-29] 4 增加透明状态栏和导航栏(默认开启,蓝色背景)
在Android程序中,我们通常会在可能发生错误的地方加上try {} catch (Exception e) {}语句来捕获异常,但是,我们无法保证程序就一定不会出错,比如,你玩Android游戏的过程中经常会碰到黑屏或者直接退出的情况,那么这些异常就应该是没有被捕获到(一般获取到都会提示用户错误,并提示用户是否将错误上传至服务器),那么现在我们来看下如何捕获全局异常,然后自己处理。
1、新建DRCrashHandler.java(这是一个抽象类,我放在了DR_supprot_lib库中,以便以后再写应用程序的时候直接使用,里面用到了一些变量是DRConstants类中的,这是一个常量类,用来定义常用的常量的)
默认Toast弹窗提示用户(消息可以自定义)
- package cn.dr.lib.app;
- import java.io.File;
- import java.io.PrintWriter;
- import java.io.StringWriter;
- import java.io.Writer;
- import java.lang.Thread.UncaughtExceptionHandler;
- import java.lang.reflect.Field;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.Locale;
- import java.util.Map;
- import org.apache.log4j.Logger;
- 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.Looper;
- import android.widget.Toast;
- import cn.dr.lib.common.DRConstants;
- import cn.dr.lib.utils.DateUtil;
- import cn.dr.lib.utils.FileUtil;
- /**
- * DarkRanger的全局异常处理类
- *
- * @author DarkRanger
- *
- */
- public abstract class DRCrashHandler implements UncaughtExceptionHandler {
- /** log4j **/
- private static final Logger log = Logger.getLogger(DRCrashHandler.class);
- /** 系统默认的UncaughtException处理类 **/
- private Thread.UncaughtExceptionHandler mDefaultHandler;
- /** 程序context **/
- private DRApplication mContext;
- /** 存储设备信息和异常信息 **/
- private Map<String, String> mInfos = new HashMap<String, String>();
- /** 程序出错提示信息 **/
- private String mDRTipMsg = "抱歉,程序异常,3s后退出!";
- /** 设置crash文件位置 **/
- private String mDRCrashFilePath = DRConstants.CRASH_FILE_PATH;
- /** 生成的log文件 **/
- private File logFile;
- /** 生成的crash文件 **/
- private File crashFile;
- /**
- * 初始化
- *
- * @param context
- */
- public void init(DRApplication context) {
- log.info("DRCrashHandler is Ready For Application! ");
- // 1、上下文
- mContext = context;
- // 2、获取系统默认的UncaughtException处理器
- mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
- // 3、初始化参数
- initParams();
- // 4、设置当前CrashHandler为默认处理异常类
- Thread.setDefaultUncaughtExceptionHandler(this);
- }
- /**
- * 3.1 初始化参数 <br/>
- * <br/>
- *
- * {@link #setTipMsg(String)} setTipMsg("this is crash tip msg!!!"); <br/>
- * {@link #setCrashFilePath(String)}
- * setCrashFilePath(Constants.CRASH_FILE_PATH); <br/>
- * <br/>
- *
- * 如果想使用自己的CrashHandler,则复写initParams()方,然后设置参数<br/>
- *
- * <code>
- * public class MyCrashHandler extends DRCrashHandler {<br/>
- * private static final Logger log = Logger.getLogger(MyCrashHandler.class);<br/>
- *
- * @Override<br/>
- * public void initParams() {<br/>
- * log.trace("MyCrashHandler: initParams()");<br/>
- *
- * setDRTipMsg("MyCrashHandler tip msg!!!");<br/>
- * setDRCrashFilePath(Constants.CRASH_FILE_PATH);<br/>
- * }<br/>
- * }<br/>
- * </code>
- */
- public abstract void initParams();
- @Override
- public void uncaughtException(Thread thread, Throwable ex) {
- log.info("DRCrashHandler dispatcher uncaughtException! ");
- if (mDefaultHandler != null && !handlerException(ex)) {
- mDefaultHandler.uncaughtException(thread, ex);
- } else {
- // 程序休眠3s后退出
- try {
- Thread.sleep(3000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- ((DRApplication) mContext.getApplicationContext()).appExit();
- }
- }
- /**
- * 5、处理异常<br>
- * <br>
- *
- * 5.1 收集设备参数信息<br>
- * 5.2 弹出窗口提示信息<br>
- * 5.3 保存log和crash到文件<br>
- * 5.4 发送log和crash到服务器<br>
- *
- * @param ex
- * @return 是否处理了异常
- */
- protected boolean handlerException(Throwable ex) {
- log.info("DRCrashHandler is handling Exception! ");
- if (ex == null) {
- return false;
- } else {
- // 5.1 收集设备参数信息
- collectDeviceInfo(mContext);
- // 5.2 弹出窗口提示信息
- new Thread(new Runnable() {
- public void run() {
- log.info("DRCrashHandler is ready send crash-info to device!");
- Looper.prepare();
- Toast.makeText(mContext, getDRTipMsg(), Toast.LENGTH_SHORT).show();
- Looper.loop();
- }
- }).start();
- // 5.3 保存log和crash到文件
- saveLogAndCrash(ex);
- // 5.4 发送log和crash到服务器
- sendLogAndCrash();
- return true;
- }
- }
- /**
- * 5.1 收集设备信息
- *
- * @param ctx
- */
- protected void collectDeviceInfo(Context ctx) {
- log.info("DRCrashHandler is collecting DeviceInfo! ");
- 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 + "";
- mInfos.put("versionName", versionName);
- mInfos.put("versionCode", versionCode);
- }
- } catch (NameNotFoundException e) {
- log.error("An error occured when collect package info, Error: " + e);
- }
- Field[] fields = Build.class.getDeclaredFields();
- for (Field field : fields) {
- try {
- field.setAccessible(true);
- mInfos.put(field.getName(), field.get(null).toString());
- } catch (Exception e) {
- log.error("An error occured when collect crash info, Error: " + e);
- }
- }
- }
- /**
- * 5.3 保存log和crash到文件
- *
- * @param ex
- */
- protected void saveLogAndCrash(Throwable ex) {
- log.info("DRCrashHandler is saving Log! ");
- StringBuffer sb = new StringBuffer();
- sb.append("[DateTime: " + DateUtil.date2String(new Date()) + "]\n");
- sb.append("[DeviceInfo: ]\n");
- // 遍历infos
- for (Map.Entry<String, String> entry : mInfos.entrySet()) {
- String key = entry.getKey().toLowerCase(Locale.getDefault());
- String value = entry.getValue();
- sb.append(" " + key + ": " + value + "\n");
- }
- // 将错误手机到writer中
- Writer writer = new StringWriter();
- PrintWriter pw = new PrintWriter(writer);
- ex.printStackTrace(pw);
- Throwable cause = ex.getCause();
- while (cause != null) {
- cause.printStackTrace(pw);
- cause = cause.getCause();
- }
- pw.close();
- String result = writer.toString();
- sb.append("[Excetpion: ]\n");
- sb.append(result);
- // 将异常写入日志文件
- log.error(result);
- // 5.3.1 记录异常到特定文件中
- saveToCrashFile(sb.toString());
- }
- /**
- * 5.3.1写入文本
- *
- * @param crashText
- */
- protected void saveToCrashFile(String crashText) {
- log.info("DRCrashHandler is writing crash-info to CrashFile(" + this.mDRCrashFilePath + ")! ");
- crashFile = new File(mDRCrashFilePath);
- // 创建文件(自己写的操作文件相关的工具类)
- FileUtil.createFileAndFolder(crashFile);
- // 追加文本(自己写的操作文件相关的工具类)
- FileUtil.appendToFile(crashFile, crashText);
- }
- /**
- * 5.4 发送log和crash到服务器
- */
- protected void sendLogAndCrash() {
- logFile = new File(mContext.getDrLogHelper().getLog4jFilePath());
- crashFile = new File(getDRCrashFilePath());
- // 5.4.1
- sendToServer(logFile, crashFile);
- }
- /**
- * 5.4.1 将错误报告发送到服务器
- *
- * @param crashFile
- * @param logFile
- */
- protected abstract void sendToServer(File logFile, File crashFile);
- public String getDRTipMsg() {
- return mDRTipMsg;
- }
- /**
- * 设置程序崩溃提示信息
- *
- * @param mDRTipMsg
- */
- public void setDRTipMsg(String mDRTipMsg) {
- this.mDRTipMsg = mDRTipMsg;
- }
- public String getDRCrashFilePath() {
- return mDRCrashFilePath;
- }
- /**
- * 设置记录崩溃信息的文件位置
- *
- * @param mDRCrashFilePath
- */
- public void setDRCrashFilePath(String mDRCrashFilePath) {
- this.mDRCrashFilePath = mDRCrashFilePath;
- }
- }
2、新建DRApplication.java(抽象类,里面用到了Log4j,上一篇有讲到如果在Android中集成Log4j,这里在Application中使用DRLogHelper来初始化log4j)
- package cn.dr.lib.app;
- import java.io.File;
- import java.util.LinkedList;
- import java.util.List;
- import org.apache.log4j.Logger;
- import android.app.Activity;
- import android.app.Application;
- import cn.dr.lib.log.DRLogHelper;
- import cn.dr.lib.ui.DRAcitivity;
- /**
- * DarkRanger的Application
- *
- * @author DarkRanger
- *
- */
- public abstract class DRApplication extends Application {
- // 当前类的log
- private static Logger log;
- // Activity列表
- private List<DRAcitivity> mActivityList = new LinkedList<DRAcitivity>();
- // drLog实例
- public DRLogHelper mDRLogHelper = DRLogHelper.getInstance();
- // 全局异常处理类的实例
- public DRCrashHandler mDRCrashHandler = new DRCrashHandler() {
- @Override
- public void initParams() {
- }
- @Override
- public void sendToServer(File logFile, File crashFile) {
- }
- };
- @Override
- public void onCreate() {
- super.onCreate();
- // 1、初始化DRLog参数
- initDRLogHelperParam();
- // 2、初始化DRLog
- initDRLogHelper();
- // 3、初始化全局异常处理类
- initCrashHandler();
- }
- /**
- * 1、初始化DRLog参数,如: <br/>
- *
- * {@link DRApplication#getDrlog()} DRLog drLog = getDrlog(); <br/>
- * {@link DRLogHelper#setLog4jFilePath(String)}
- * drLog.setLog4jFilePath(Constants.LOG4J_FILE_PATH); <br/>
- * {@link DRLogHelper#setType(cn.dr.lib.log.DRLogHelper.LogType)}
- * drLog.setType(LogType.TYPE_LOG4J); <br/>
- *
- * 只有在子类中完成initDRLogParam参数设置以后才能使用log
- */
- protected abstract void initDRLogHelperParam();
- /**
- * 2、初始化DRLog
- */
- private void initDRLogHelper() {
- getDrLogHelper().init();
- log = Logger.getLogger(DRApplication.class);
- }
- /**
- * 3、初始化CrashHandler
- */
- private void initCrashHandler() {
- log.trace("DRApplication: initCrashHandler()");
- // 3.1
- setHandler();
- // 3.2
- getDRCrashHandler().init(this);
- }
- /**
- *
- * 3.1 调用以下方法为mCrashHandler设置实例<br/>
- * <br/>
- *
- * {@link #setCrashHandler(DRCrashHandler)}
- */
- public abstract void setHandler();
- /**
- * 获取DRLog单例
- *
- * @return
- */
- public DRLogHelper getDrLogHelper() {
- return mDRLogHelper;
- }
- public DRCrashHandler getDRCrashHandler() {
- return mDRCrashHandler;
- }
- public void setDRCrashHandler(DRCrashHandler mCrashHandler) {
- this.mDRCrashHandler = mCrashHandler;
- }
- /**
- * 添加activity到App的mActivityList
- *
- * @param activity
- */
- public void addActivity(DRAcitivity activity) {
- this.mActivityList.add(activity);
- }
- /**
- * 遍历mActivityList,结束每一个activity的声明周期
- */
- private void finishActivityList() {
- for (Activity activity : mActivityList) {
- activity.finish();
- }
- }
- @Override
- public void onTerminate() {
- log.trace("DRApplication: onTerminate()");
- super.onTerminate();
- appExit();
- }
- /**
- * 完全退出程序
- */
- public void appExit() {
- log.trace("DRApplication: appExit()");
- finishActivityList();
- // 正常退出
- System.exit(0);
- }
- /**
- * 出现异常杀掉进程
- */
- public void appKill() {
- log.trace("DRApplication: appKill()");
- finishActivityList();
- android.os.Process.killProcess(android.os.Process.myPid());
- System.exit(1);
- }
- }
3、
首先要说明的是:前面两个类我已经集成在DR_supprot_lib库中,在新的应用程序中只需要继承这两个类,分类初始化一些参数即可。
写个App程序测试:
3.1 新建MyCrashHandler.java继承DRCrashHandler,复写两个抽象方法initParams()和sendToServer()
- package cn.darkranger.test;
- import java.io.File;
- import org.apache.log4j.Logger;
- import android.os.Environment;
- import cn.dr.lib.app.DRCrashHandler;
- public class MyCrashHandler extends DRCrashHandler {
- private static final Logger log = Logger.getLogger(MyCrashHandler.class);
- String crashFilePath = Environment.getExternalStorageDirectory() + File.separator + "MyApp" + File.separator
- + "Crash.txt";
- @Override
- public void initParams() {
- // 设置程序崩溃提示信息
- setDRTipMsg("this is my msg - -");
- // 设置程序崩溃的文件位置
- setDRCrashFilePath(crashFilePath);
- }
- @Override
- protected void sendToServer(File logFile, File crashFile) {
- log.info("logFile: " + logFile + "; crashFile: " + "\naction:sendToServer - -");
- // 这里要写上传错误信息到服务器的代码,暂时不写,看需求,自己实现
- }
- }
3.2 新建MyApplication.java继承DRApplication,复写两个抽象方法initDRLogHelperParam()和setHandler()
- package cn.darkranger.test;
- import java.io.File;
- import org.apache.log4j.Logger;
- import android.os.Environment;
- import cn.dr.lib.app.DRCrashHandler;
- public class MyCrashHandler extends DRCrashHandler {
- private static final Logger log = Logger.getLogger(MyCrashHandler.class);
- String crashFilePath = Environment.getExternalStorageDirectory() + File.separator + "MyApp" + File.separator
- + "Crash.txt";
- @Override
- public void initParams() {
- // 设置程序崩溃提示信息
- setDRTipMsg("this is my msg - -");
- // 设置程序崩溃的文件位置
- setDRCrashFilePath(crashFilePath);
- }
- @Override
- protected void sendToServer(File logFile, File crashFile) {
- log.info("logFile: " + logFile + "; crashFile: " + "\naction:sendToServer - -");
- // 这里要写上传错误信息到服务器的代码,暂时不写,看需求,自己实现
- }
- }
3.3 新建MainActivity,这里暂时不继承DRActivity,继承AppCompatActivity,两个testview,点击第一个,调用DRApplication的退出,点击第二个,抛出异常,我们自己捕获。
- package cn.darkranger.test;
- import android.os.Bundle;
- import android.support.v7.app.AppCompatActivity;
- import android.view.Menu;
- import android.view.MenuItem;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.TextView;public class MainActivity extends AppCompatActivity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- TextView exitTv = (TextView) findViewById(R.id.id_exit);
- exitTv.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- ((MyApplication) getApplication()).appExit();
- }
- });
- TextView testCrashTv = (TextView) findViewById(R.id.id_testCrash);
- testCrashTv.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- throw new IllegalArgumentException("this is an IllegalArgumentException! ");
- }
- });
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.main, menu);
- return true;
- }
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- int id = item.getItemId();
- if (id == R.id.action_settings) {
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
- }
3.4 更改AndroidManifest.xml(添加读写文件的权限,设置application为:cn.darkranger.test.MyApplication)
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="cn.darkranger.test"
- android:versionCode="1"
- android:versionName="1.0" >
- <uses-sdk
- android:minSdkVersion="11"
- android:targetSdkVersion="21" />
- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- <application
- android:name="cn.darkranger.test.MyApplication"
- android:allowBackup="true"
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name"
- android:theme="@style/AppTheme" >
- <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>
测试:
运行,点击第一个按钮,退出程序,查看log文件:
- [2016-06-30 22:19:09][Class: cn.dr.lib.log.DRLogHelper.initLog4j(DRLogHelper.java:89)]
- [Level: INFO ] - Msg: Log4j is Ready For DRApplication!
- [2016-06-30 22:19:09][Class: cn.dr.lib.app.DRApplication.initCrashHandler(DRApplication.java:87)]
- [Level: TRACE] - Msg: DRApplication: initCrashHandler()
- [2016-06-30 22:19:09][Class: cn.dr.lib.app.DRCrashHandler.init(DRCrashHandler.java:65)]
- [Level: INFO ] - Msg: DRCrashHandler is Ready For Application!
- [2016-06-30 22:19:12][Class: cn.dr.lib.app.DRApplication.appExit(DRApplication.java:152)]
- [Level: TRACE] - Msg: DRApplication: appExit()
- [2016-06-30 22:19:58][Class: cn.dr.lib.log.DRLogHelper.initLog4j(DRLogHelper.java:89)]
- [Level: INFO ] - Msg: Log4j is Ready For DRApplication!
- [2016-06-30 22:19:58][Class: cn.dr.lib.app.DRApplication.initCrashHandler(DRApplication.java:87)]
- [Level: TRACE] - Msg: DRApplication: initCrashHandler()
- [2016-06-30 22:19:58][Class: cn.dr.lib.app.DRCrashHandler.init(DRCrashHandler.java:65)]
- [Level: INFO ] - Msg: DRCrashHandler is Ready For Application!
- [2016-06-30 22:20:02][Class: cn.dr.lib.app.DRApplication.appExit(DRApplication.java:152)]
- [Level: TRACE] - Msg: DRApplication: appExit()
运行,点击第二个按钮,抛出异常,查看log文件和crash文件:
Log.txt
- [2016-06-30 22:19:09][Class: cn.dr.lib.log.DRLogHelper.initLog4j(DRLogHelper.java:89)]
- [Level: INFO ] - Msg: Log4j is Ready For DRApplication!
- [2016-06-30 22:19:09][Class: cn.dr.lib.app.DRApplication.initCrashHandler(DRApplication.java:87)]
- [Level: TRACE] - Msg: DRApplication: initCrashHandler()
- [2016-06-30 22:19:09][Class: cn.dr.lib.app.DRCrashHandler.init(DRCrashHandler.java:65)]
- [Level: INFO ] - Msg: DRCrashHandler is Ready For Application!
- [2016-06-30 22:19:12][Class: cn.dr.lib.app.DRApplication.appExit(DRApplication.java:152)]
- [Level: TRACE] - Msg: DRApplication: appExit()
- [2016-06-30 22:19:58][Class: cn.dr.lib.log.DRLogHelper.initLog4j(DRLogHelper.java:89)]
- [Level: INFO ] - Msg: Log4j is Ready For DRApplication!
- [2016-06-30 22:19:58][Class: cn.dr.lib.app.DRApplication.initCrashHandler(DRApplication.java:87)]
- [Level: TRACE] - Msg: DRApplication: initCrashHandler()
- [2016-06-30 22:19:58][Class: cn.dr.lib.app.DRCrashHandler.init(DRCrashHandler.java:65)]
- [Level: INFO ] - Msg: DRCrashHandler is Ready For Application!
- [2016-06-30 22:20:02][Class: cn.dr.lib.app.DRApplication.appExit(DRApplication.java:152)]
- [Level: TRACE] - Msg: DRApplication: appExit()
- [2016-06-30 22:20:48][Class: cn.dr.lib.log.DRLogHelper.initLog4j(DRLogHelper.java:89)]
- [Level: INFO ] - Msg: Log4j is Ready For DRApplication!
- [2016-06-30 22:20:48][Class: cn.dr.lib.app.DRApplication.initCrashHandler(DRApplication.java:87)]
- [Level: TRACE] - Msg: DRApplication: initCrashHandler()
- [2016-06-30 22:20:48][Class: cn.dr.lib.app.DRCrashHandler.init(DRCrashHandler.java:65)]
- [Level: INFO ] - Msg: DRCrashHandler is Ready For Application!
- [2016-06-30 22:20:50][Class: cn.dr.lib.app.DRCrashHandler.uncaughtException(DRCrashHandler.java:109)]
- [Level: INFO ] - Msg: DRCrashHandler dispatcher uncaughtException!
- [2016-06-30 22:20:50][Class: cn.dr.lib.app.DRCrashHandler.handlerException(DRCrashHandler.java:139)]
- [Level: INFO ] - Msg: DRCrashHandler is handling Exception!
- [2016-06-30 22:20:50][Class: cn.dr.lib.app.DRCrashHandler.collectDeviceInfo(DRCrashHandler.java:175)]
- [Level: INFO ] - Msg: DRCrashHandler is collecting DeviceInfo!
- [2016-06-30 22:20:50][Class: cn.dr.lib.app.DRCrashHandler.saveLogAndCrash(DRCrashHandler.java:206)]
- [Level: INFO ] - Msg: DRCrashHandler is saving Log!
- [2016-06-30 22:20:50][Class: cn.dr.lib.app.DRCrashHandler.run(DRCrashHandler.java:151)]
- [Level: INFO ] - Msg: DRCrashHandler is ready send crash-info to device!
- [2016-06-30 22:20:50][Class: cn.dr.lib.app.DRCrashHandler.saveLogAndCrash(DRCrashHandler.java:233)]
- [Level: ERROR] - Msg: java.lang.IllegalArgumentException: this is an IllegalArgumentException!
- at cn.darkranger.test.MainActivity$2.onClick(MainActivity.java:33)
- at android.view.View.performClick(View.java:4792)
- at android.view.View$PerformClick.run(View.java:19936)
- at android.os.Handler.handleCallback(Handler.java:739)
- at android.os.Handler.dispatchMessage(Handler.java:95)
- at android.os.Looper.loop(Looper.java:135)
- at android.app.ActivityThread.main(ActivityThread.java:5595)
- at java.lang.reflect.Method.invoke(Native Method)
- at java.lang.reflect.Method.invoke(Method.java:372)
- at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964)
- at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759)
- [2016-06-30 22:20:50][Class: cn.dr.lib.app.DRCrashHandler.saveToCrashFile(DRCrashHandler.java:246)]
- [Level: INFO ] - Msg: DRCrashHandler is writing crash-info to CrashFile(/storage/emulated/0/MyApp/Crash.txt)!
- [2016-06-30 22:20:50][Class: cn.dr.lib.utils.FileUtil.createFileAndFolder(FileUtil.java:444)]
- [Level: INFO ] - Msg: File[/storage/emulated/0/MyApp/Crash.txt] was created successfully!
- [2016-06-30 22:20:50][Class: cn.darkranger.test.MyCrashHandler.sendToServer(MyCrashHandler.java:26)]
- [Level: INFO ] - Msg: logFile: /storage/emulated/0/MyApp/Log.txt; crashFile:
- action:sendToServer - -
- [2016-06-30 22:20:53][Class: cn.dr.lib.app.DRApplication.appExit(DRApplication.java:152)]
- [Level: TRACE] - Msg: DRApplication: appExit()
Crash.txt
- [DateTime: 2016-06-30 22:20:50]
- [DeviceInfo: ]
- supported_64_bit_abis: [Ljava.lang.String;@16d078ef
- versioncode: 1
- board: mozart
- bootloader: unknown
- type: user
- matchers: [Ljava.lang.String;@3d5b7685
- id: HUAWEIM2-801W
- time: 1437332391000
- brand: HUAWEI
- tag: Build
- serial: TJF4C15804003585
- hardware: hi3635
- supported_abis: [Ljava.lang.String;@33767ffc
- no_hota: false
- cpu_abi: arm64-v8a
- radio: unknown
- is_debuggable: false
- replacements: [Ljava.lang.String;@2dec2cda
- manufacturer: HUAWEI
- supported_32_bit_abis: [Ljava.lang.String;@3271c1ce
- tags: ota-rel-keys,release-keys
- cpu_abi2:
- unknown: unknown
- user: huawei
- fingerprint: HUAWEI/M2/HWMozart:5.1.1/HUAWEIM2-801W/C233B009:user/release-keys
- host: WUH1000005635
- product: M2
- versionname: 1.0
- display: M2-801WV100R001C233B009
- hide_product_info: false
- model: HUAWEI M2-801W
- device: HWMozart
- [Excetpion: ]
- java.lang.IllegalArgumentException: this is an IllegalArgumentException!
- at cn.darkranger.test.MainActivity$2.onClick(MainActivity.java:33)
- at android.view.View.performClick(View.java:4792)
- at android.view.View$PerformClick.run(View.java:19936)
- at android.os.Handler.handleCallback(Handler.java:739)
- at android.os.Handler.dispatchMessage(Handler.java:95)
- at android.os.Looper.loop(Looper.java:135)
- at android.app.ActivityThread.main(ActivityThread.java:5595)
- at java.lang.reflect.Method.invoke(Native Method)
- at java.lang.reflect.Method.invoke(Method.java:372)
- at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:964)
- at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:759)
Android应用捕获全局异常自定义处理的更多相关文章
- Android捕获全局异常
Android捕获全局异常 程序避免不了出现bug,导致程序崩溃,为了尽量不影响用户体验,可以全局捕获异常 效果图 异常捕获处理前 异常捕获处理后(将程序重新启动) 捕获异常的工具类 package ...
- 在C#代码中应用Log4Net(四)在Winform和Web中捕获全局异常
毕竟人不是神,谁写的程序都会有bug,有了bug不可怕,可怕的是出错了,你却不知道错误在哪里.所以我们需要将应用程序中抛出的所有异常都记录起来,不然出了错,找问题就能要了你的命.下面我们主要讨论的是如 ...
- C# 捕获全局异常
一.在Winform程序中捕获全局异常 在winfrom中我们需要了解Application对象中的两个事件 ①Application.ThreadException 事件--当UI线程中某个异常未被 ...
- SpringBoot捕获全局异常
1.创建GloableExceptionAop类捕获全局异常 package com.cppdy.exception; import org.springframework.web.bind.anno ...
- WebForm 在 Global.asax 中捕获全局异常
/// <summary> /// 捕获全局异常 /// </summary> /// <param name="sender">sender& ...
- SpringBoot学习笔记(二):SpringBoot访问静态文件、捕获全局异常、集成Thymeleaf、集成JSP
SpringBoot访问静态文件 什么是静态文件? 不需要通过web容器去得到的文件,直接通过路径就能得到的文件,比如项目的css,js,img等文件. 所有的资源文件都应该在src/main/res ...
- Android使用UncaughtExceptionHandler捕获全局异常
Android系统的“程序异常退出”,给应用的用户体验造成不良影响.为了捕获应用运行时异常并给出友好提示,便可继承UncaughtExceptionHandler类来处理.通过Thread.setDe ...
- 在Global.asax中 注册Application_Error事件 捕获全局异常
参考于:https://shiyousan.com/post/635813858052755170 在ASP.NET MVC中,通过应用程序生命周期中的Application_Error事件可以捕获到 ...
- C# WinForm捕获全局异常
网上找的C# WinForm全局异常捕获方法,代码如下: static class Program { /// <summary> /// 应用程序的主入口点. /// </summ ...
随机推荐
- 跨域问题hbuilder
1.借助jquery-jsonp插件 $.jsonp({ url: url, data: { 'name': usd, 'passwd': pass }, callbackParameter: &qu ...
- App测试从入门到精通之兼容性和回归测试
兼容性测试需要考虑的APP测试点 1.不同网络环境下的兼容性测试 2.不同手机操作系统兼容性测试 3.不同应用软件的兼容性测试 4.不同的容量大小的SIM卡之间的互相兼容测试 5.当安装杀毒软件时,应 ...
- C++ 中 dynamic_cast 浅析
简述:dynamic_cast 操作符,将基类的指针或引用安全的转换为派生类的指针或引用.主要讲解,dynamic_cast操作符的原理.使用方式.编译器设置.返回值等相关知识. dynamic_ca ...
- 【Linux-学习笔记-不定期更新】
command--help ./当前的路径 目录操作命令: mkdir 创建目录: 创建多级目录 : mkdir -p 查看目录:ls ls -a:显示所有文件,包括隐藏文件 隐藏文件以.开头 ls ...
- C#多线程编程实战1.4终止线程
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...
- SOA IN Real World
微软发布了一个名为“真实世界里的面向服务架构(SOA)”的电子书.这本书表达了微软对面向服务架构的观点,并包括了数个展示如何用微软产品和技术实现SOA的真实案例.书中解释到,SOA的功能型架构本身是松 ...
- react-native自定义原生组件
此文已由作者王翔授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 使用react-native的时候能够看到不少函数调用式的组件,像LinkIOS用来呼起url请求 Link ...
- 主流C语言编译器介绍
- ubuntu 16.4安装toolsbelt heroku
https://devcenter.heroku.com/articles/getting-started-with-python#set-up # Run this from your termin ...
- SpringMVC中视图解析器
视图解析器:固定写法直接coppy就行 1.dispatcherServlet-servlet.xml中添加 <!-- 视图解析器InternalResourceViewResolver --& ...