android抓取错误日志并上报到服务器
来源:互联网 发布:linux pkg config 编辑:程序博客网 时间:2024/04/28 04:50
开发中,app线上版本经常会出现这样那样的问题,那我们如何知道出现了什么问题呢?并且能快速定位到错误并有效解决呢?这里就涉及到错误日志或叫崩溃日志了。一般情况下,我们都会继承友盟等第三方的错误日志,来抓到错误。但是抓错误原理是什么呢?接下来介绍一下,如何抓错误日志,并上报到服务器。
Android中提供了一个全局异常的捕获,方式如下:
1.定义一个类实现UncaughtExceptionHandler
2.在Application中初始化,Thread.setDefaultUncaughtExceptionHandler(handler);
3.将抓取到的错误保存到本地txt文件
4.上传到服务器
具体代码如下:
(1) 定义一个CrashHandler
public class CrashHandler implements UncaughtExceptionHandler {
private static CrashHandler myCrashHandler;
private CrashHandler() {
};
private Context context;
public final static String LOGPATH =Environment.getExternalStorageDirectory() + “/usershopping/crash.txt” ;
private UncaughtExceptionHandler defaultExceptionHandler;
public synchronized static CrashHandler getInstance() {
if (myCrashHandler == null) {
myCrashHandler = new CrashHandler();
}
return myCrashHandler;
}
public void init(Context context) {
this.context = context;
defaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
}
public void uncaughtException(Thread thread, Throwable ex) {
if(!sdCardIsAvailable()){
ex.printStackTrace();
new Thread() {
@Override
public void run() {
Looper.prepare();
Toast.makeText(context, “异常退出”, Toast.LENGTH_LONG).show();
Looper.loop();
}
}.start();
new Thread() {
@Override
public void run() {
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
android.os.Process.killProcess(android.os.Process.myPid());
}
}.start();
return;
}
//(3)将错误日志保存到本地txt文件
try {
// 在throwable的参数里面保存的有程序的异常信息
StringBuffer sb = new StringBuffer();
// 1.得到手机的版本信息 硬件信息
Field[] fields = Build.class.getDeclaredFields();
for (Field filed : fields) {
filed.setAccessible(true); // 暴力反射
String name = filed.getName();
String value = filed.get(null).toString();
sb.append(name);
sb.append(“=”);
sb.append(value);
sb.append(“\n”);
}
// 2.得到当前程序的版本号 PackageInfo info = context.getPackageManager().getPackageInfo( context.getPackageName(), 0); sb.append(info.versionName); sb.append("\n"); // 3.得到当前程序的异常信息 Writer writer = new StringWriter(); PrintWriter printwriter = new PrintWriter(writer); ex.printStackTrace(printwriter); printwriter.flush(); printwriter.close(); sb.append(writer.toString()); File ff = new File(LOGPATH); ff.createNewFile(); FileWriter fw = new FileWriter(new File(LOGPATH)); fw.write(sb.toString());
// System.out.println(sb);
fw.close();
} catch (Exception e1) { e1.printStackTrace(); } new Thread() { @Override public void run() { Looper.prepare(); Toast.makeText(context, "异常退出", Toast.LENGTH_LONG).show(); Looper.loop(); } }.start(); //出现异常后,退出app new Thread() { @Override public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } android.os.Process.killProcess(android.os.Process.myPid()); } }.start();}/** * 检测sdcard是否可用 * * @return true为可用,否则为不可用 */public static boolean sdCardIsAvailable() { String status = Environment.getExternalStorageState(); if (!status.equals(Environment.MEDIA_MOUNTED)) return false; return true;}
}
(2)在Application中开一个子线程,初始化
//抓错误日志
new Thread(){
@Override
public void run() {
//把异常处理的handler设置到主线程里面
CrashHandler ch = CrashHandler.getInstance();
ch.init(getApplicationContext());
}
}.start();
(4)上传到服务器
前几步,是只要发生崩溃,我们就会将崩溃日志保存到本地,然后强制退出app,接下来我们就可以在启动app的首个activity中,即闪屏页里,判断本地是否有错误日志txt,有就开启服务上传,上传成功后就要删除。这样做可以避免多个错误日志覆盖的问题。
//检查cash.txt是否存在 存在就开启服务 上传到服务器 String path= Environment.getExternalStorageDirectory() + "/usershopping/crash.txt"; final File cashFile=new File(path); if (cashFile.exists()){ startService(new Intent(context, UploadCashService.class)); } //这个服务是intentService 自动开启异步,执行结束后自动销毁 public class UploadCashService extends IntentService { public UploadCashService(String name) { super(name); } public UploadCashService() { super("UploadCashService"); } @Override public IBinder onBind(Intent intent) { return null; } @Override protected void onHandleIntent(@Nullable Intent intent) { } @SuppressWarnings("deprecation") @Override public int onStartCommand(Intent intent, int flags, int startId) { //开启上传 upLoadCash(getApplicationContext()); return super.onStartCommand(intent, flags, startId); } private void upLoadCash(final Context context) { String path= Environment.getExternalStorageDirectory() + "/usershopping/crash.txt"; final File file=new File(path); final Map<String, String> headers = new HashMap<String, String>(); final Map<String, String> params = new HashMap<String, String>(); params.put("v1", "true"); headers.put(App.TOKEN_NAME, SharedPreferencesUtils.getString(context, "TOKEN")); headers.put("ContentType", "multipart/form-data"); headers.put("dcode",CommonUtil.getDeviceInfo(context));//手机唯一标识 headers.put("brand", android.os.Build.BRAND); //手机品牌 headers.put("model", Build.MODEL);//手机型号 headers.put("ver",android.os.Build.VERSION.RELEASE);//系统版本号 headers.put("appver", String.valueOf(CommonUtil.getVersion(context)));//app版本号 headers.put("verName", String.valueOf(CommonUtil.getVersionName(context)));//app版本名 headers.put("appname","CLIENT"); PostFormBuilder post = OkHttpUtils.post() .url(new Constant(context).CASHUPLOAD) .params(params) .headers(headers); post.addFile("mFile" , System.currentTimeMillis() + Math.random() * 10 + ".txt", file); post.build().execute(new Callback<Object>() { @Override public Object parseNetworkResponse( Response response) throws Exception { // TODO Auto-generated method stub if (file.exists()){ file.delete(); } return null; } @Override public void onError(Call call, Exception e) { // TODO Auto-generated method stub MyToast.showToast(context, "错误日志上传失败"); } @Override public void inProgress(float progress) { super.inProgress(progress); } @Override public void onResponse(Object response) { // TODO Auto-generated method stub } });}
}
- android抓取错误日志并上报到服务器
- android acra错误日志上报
- android crash日志上报
- flume上报日志到kafka
- 崩溃捕获并上报服务器
- 将android客户端的错误日志压缩上传到服务器
- android-crash-log-上报服务器
- 水晶报表发布到服务器上报错。
- android自己获取并保存错误日志(可以通过邮件发送到自己邮箱)
- android 收集错误log日志,并保存到sd卡上的实用类
- Maven -- clean deploy发布jar或war包到远程服务器上报“非法字符: \65279 ”错误的解决方法
- Android 日志文件抓取
- Android抓取崩溃日志
- Android抓取崩溃日志
- Android 抓取崩溃日志
- android 收集错误日志 上传服务器
- Android抓取系统日志,并从中得到其他应用的日志信息
- android 错误日志打印到本地
- 计算机网络 —— URI和URL
- vivo和OPPO手机刷机
- Android自定义View,实现全屏滑动的DrawerLayout
- CSS3中-moz、-ms、-webkit和-o分别代表什么意思
- stm32 spi的测试例程
- android抓取错误日志并上报到服务器
- elasticsearch java实现类似sql group by
- JVM知识总结
- Qt图形视图框架(六) 为Item应用属性动画
- java基础1
- 将linux下的rm命令改造成移动文件至回收站
- Android BroadcastReceiver(广播)
- Codeforces 820A Mister B and Book Reading
- AJax+Servlet 跨域问题 Access-Control-Allow-Origin