android 监测bug上传到服务器,基于Android 错误信息捕获发送至服务器的详解
程序员最头疼的事情就是bug和debug。这次debug长达20天,搞的我心力交瘁。累,因为Android兼容性,不同手机会有不同的bug出来,而且很难复现,所以就上网找了下类似保存错误log到文件再上传到服务器,现把源码也共享出来。上传至服务器的代码我没加。相信大家都有现成的代码了。
先讲下原理,跟JavaEE的自定义异常捕获一样,将错误一直向上抛,然后在最上层统一处理。这里就可以获得Exception Message,进行保存操作
异常捕获类如下:
/**
* @author Stay
* 在Application中统一捕获异常,保存到文件中下次再打开时上传
*/
public class CrashHandler implements UncaughtExceptionHandler {
/** 是否开启日志输出,在Debug状态下开启,
* 在Release状态下关闭以提示程序性能
* */
public static final boolean DEBUG = true;
/** 系统默认的UncaughtException处理类 */
private Thread.UncaughtExceptionHandler mDefaultHandler;
/** CrashHandler实例 */
private static CrashHandler INSTANCE;
/** 程序的Context对象 */
// private Context mContext;
/** 保证只有一个CrashHandler实例 */
private CrashHandler() {}
/** 获取CrashHandler实例 ,单例模式*/
public static CrashHandler getInstance() {
if (INSTANCE == null) {
INSTANCE = new CrashHandler();
}
return INSTANCE;
}
/**
* 初始化,注册Context对象,
* 获取系统默认的UncaughtException处理器,
* 设置该CrashHandler为程序的默认处理器
*
* @param ctx
*/
public void init(Context ctx) {
// mContext = ctx;
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
}
/**
* 当UncaughtException发生时会转入该函数来处理
*/
@Override
public void uncaughtException(Thread thread, Throwable ex) {
if (!handleException(ex) && mDefaultHandler != null) {
//如果用户没有处理则让系统默认的异常处理器来处理
mDefaultHandler.uncaughtException(thread, ex);
} else { //如果自己处理了异常,则不会弹出错误对话框,则需要手动退出app
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
}
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(10);
}
}
/**
* 自定义错误处理,收集错误信息
* 发送错误报告等操作均在此完成.
* 开发者可以根据自己的情况来自定义异常处理逻辑
* @return
* true代表处理该异常,不再向上抛异常,
* false代表不处理该异常(可以将该log信息存储起来)然后交给上层(这里就到了系统的异常处理)去处理,
* 简单来说就是true不会弹出那个错误提示框,false就会弹出
*/
private boolean handleException(final Throwable ex) {
if (ex == null) {
return false;
}
// final String msg = ex.getLocalizedMessage();
final StackTraceElement[] stack = ex.getStackTrace();
final String message = ex.getMessage();
//使用Toast来显示异常信息
new Thread() {
@Override
public void run() {
Looper.prepare();
// Toast.makeText(mContext, "程序出错啦:" + message, Toast.LENGTH_LONG).show();
// 可以只创建一个文件,以后全部往里面append然后发送,这样就会有重复的信息,个人不推荐
String fileName = "crash-" + System.currentTimeMillis() + ".log";
File file = new File(Environment.getExternalStorageDirectory(), fileName);
try {
FileOutputStream fos = new FileOutputStream(file,true);
fos.write(message.getBytes());
for (int i = 0; i < stack.length; i++) {
fos.write(stack[i].toString().getBytes());
}
fos.flush();
fos.close();
} catch (Exception e) {
}
Looper.loop();
}
}.start();
return false;
}
// TODO 使用HTTP Post 发送错误报告到服务器 这里不再赘述
// private void postReport(File file) {
// 在上传的时候还可以将该app的version,该手机的机型等信息一并发送的服务器,
// Android的兼容性众所周知,所以可能错误不是每个手机都会报错,还是有针对性的去debug比较好
// }
}
在Application onCreate时就注册ExceptionHandler,此后只要程序在抛异常后就能捕获到。
public class App extends Application{
@Override
public void onCreate() {
super.onCreate();
CrashHandler crashHandler = CrashHandler.getInstance();
//注册crashHandler
crashHandler.init(getApplicationContext());
}
}
?public class LogActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {//制造bug
File file = new File(Environment.getExternalStorageState() ,"crash.bin");
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[1024];
fis.read(buffer);
} catch (Exception e) {
//这里不能再向上抛异常,如果想要将log信息保存起来,则抛出runtime异常,
// 让自定义的handler来捕获,统一将文件保存起来上传
throw new RuntimeException(e);
}
}
}
注意,如果catch后不throw就默认是自己处理了,ExceptionHandler不会捕获异常了。再分享一个Log的封装类,只要在这里设置DEBUG的值就能让控制台是否打印出log
public class DebugUtil {
public static final String TAG = "ICON";
public static final boolean DEBUG = true;
public static void toast(Context context,String content){
Toast.makeText(context, content, Toast.LENGTH_SHORT).show();
}
public static void debug(String tag,String msg){
if (DEBUG) {
Log.d(tag, msg);
}
}
public static void debug(String msg){
if (DEBUG) {
Log.d(TAG, msg);
}
}
public static void error(String tag,String error){
Log.e(tag, error);
}
public static void error(String error){
Log.e(TAG, error);
}
}
android 监测bug上传到服务器,基于Android 错误信息捕获发送至服务器的详解相关推荐
- php图片上传腾讯云cos,ThinkPHP集成腾讯云存储(COS)--详解
准备工作: 一. 根据图示进入COS 点击立即使用 进入后根据下面点击新建:Bucket(Bucket就是你往云存储的一个目录) 新建Bucket 二. 下载SDK 下一步: 然后复制把整个cos文件 ...
- FTP编程实验——实现文件上传下载(基于Python3.7和PyQt5)
目录 FTP编程实现文件上传下载(基于Python3.7和PyQt5) 一.实验目的 二.实验内容 三.实验步骤 (一)服务器端 (二)客户端 [1] 界面设计 [2] 生成布局代码 [3] 功能实现 ...
- Android开发文件上传格式,(android开发)使用okhttp上传文件
开发android手机客户端,常常会需要上传文件到服务器,比如:你手机里的照片. 使用okhttp会是一个很好的选择.它使用很简单,而且运行效率也很高. 首先,在 app/build.gradle 的 ...
- lede更改软件源_Linux的上传和下载——Ubuntu中软件的安装和ftp服务器的搭建
[Linux操作系统]Linux的上传和下载--Ubuntu中软件的安装和ftp服务器的搭建 学习完Linux终端命令以后,我们现在要考虑的是怎么实现Linux中文件的上传和下载,这就是我们本篇博客要 ...
- android multipartentity 怎么上传参数,android-通过MultipartEntityBuilder通过HTTP表单上传文件,并显示进度b...
android-通过MultipartEntityBuilder通过HTTP表单上传文件,并显示进度b 短版本-.jar已弃用,其升级版本java.lang.NoClassDefFoundError在 ...
- 九宫格拼图android代码,Android 多图上传后将图片进行九宫格展示的实例代码
不多说上代码 public abstract class NineGridAdapter { protected Context context; protected List list; publi ...
- RxHttp 完美适配Android 10/11 上传/下载/进度监听
1.前言 随着Android 11的正式发布,适配Android 10/11 分区存储就更加的迫切了,因为Android 11开始,将强制开启分区存储,我们就无法再以绝对路径的方式去读写非沙盒目录下的 ...
- 魅族android不兼容Android,魅族17系列彻底跟上时代,搭载基于Android 10的Flyme 8.1系统...
原标题:魅族17系列彻底跟上时代,搭载基于Android 10的Flyme 8.1系统 我们知道,魅族17年匠心工艺大作暨魅族科技第一部5G高端旗舰手机魅族17系列手机将于5月8日正式发布,经过最近这 ...
- android多文件上传错误,微信多图上传解决android多图上传失败问题
微信提供了文件上传的方法wx.uploadFile来上传我们的图片 wx.chooseImage({ success: function(res) { var tempFilePaths = res. ...
最新文章
- 第十九章——使用资源调控器管理资源(2)——使用T-SQL配置资源调控器
- Python Tkinter小试
- Flink从入门到精通100篇(十九)-基于 Flink 的大规模准实时数据分析平台的建设实践
- 在MAC系统的eclipse里打开android sdk manager
- 什么是XSS攻击XSS攻击应用场景
- art-template入门(六)之解析规则
- 为什么要远离对日外包_远离魔法-或:为什么我不想再使用Laravel
- windows下shutdown/up oracle数据库的批处理
- 如何做好一位合格qc_如何做好一个合格的热缩产品
- K8S知道,K9S呢?
- 高中低压电网光伏并网二次设计——分布式光伏电站并网市电通讯组网
- Vue使用iconfont图标
- 2020图灵奖颁给“龙书”两位作者!合作数十年,他们让计算机读懂码农代码
- Vue中使用 Aplayer 和 Metingjs 添加音乐插件
- 2021 TCR Asia收官 壳牌捷凯领克东望洋收获大满贯
- oracle表数据导出成unl文件,oracle的文本导入、导出技巧
- Unity3D新手入门初中高级教程
- java代码自动抠图_Opencv java实现人脸抠图和行为识别
- 雷蛇 笔记本 装linux,顺应民意:雷蛇考虑开发Linux版Blade游戏本
- linux操作系统 第09章 操作系统接口
热门文章
- mysql 线性表_线性表之顺序存储,基本操作
- SparkCore基础
- Java什么是重用_深度解析:java必须掌握的知识点——类的重用
- 如何在计算机课上渗透德育教育初探,在《道德与法治》课中德育渗透的案例初探...
- 论文浅尝 - ACL2020 | 通过集成知识转换进行多语言知识图谱补全
- 关于PaddleNLP如何加载训练好的模型进行NER
- 论文解读:Attention is All you need
- CRISP-DM:数据挖掘标准流程
- 最小生成树——普里姆算法和克鲁斯卡尔算法
- day21 面向对象之继承和组合