全局异常捕捉并上传log到服务器
来源:互联网 发布:淘宝为啥不能买彩票了 编辑:程序博客网 时间:2024/06/02 08:56
一个项目的完工后,我们也应给APP加上全局的异常捕捉,并将异常log上传到服务器。有些朋友可能会遇到这样的问题,异常是捕捉到了,但是还没等到上传到服务器上APP就挂了。下面我们一起来看一下我在应用中的使用。
import java.io.File;import java.io.FileOutputStream;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.DateFormat;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Date;import java.util.HashMap;import java.util.List;import java.util.Map;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.client.HttpClient;import org.apache.http.client.methods.HttpPost;import org.apache.http.entity.mime.HttpMultipartMode;import org.apache.http.entity.mime.MultipartEntityBuilder;import org.apache.http.entity.mime.content.FileBody;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.params.BasicHttpParams;import org.apache.http.params.HttpConnectionParams;import org.apache.http.params.HttpParams;import org.apache.http.util.EntityUtils;import org.json.JSONObject;import android.app.AlarmManager;import android.app.PendingIntent;import android.content.Context;import android.content.Intent;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;import com.wish.becomeeasy.activity.MainActivity;import com.wish.becomeeasy.constant.Constant;import com.wish.becomeeasy.utils.MyUtils;/** * * @类名称: CrashHandler.java * @创建人:Mr.ladeng (zbl704@yeah.net) * @创建时间: 2015-8-14下午1:22:15 * @修改备注: * @version 1.0 * @类描述:捕捉全局异常类 * * 在application类中onCreate下调用 * * CrashHandler crashHandler = CrashHandler.getInstance(); * crashHandler.init(getApplicationContext()); * */public class CrashHandler implements UncaughtExceptionHandler {public static final String TAG = "CrashHandler"; /***系统默认的UncaughtException处理类 ***/ private Thread.UncaughtExceptionHandler mDefaultHandler; /***CrashHandler实例 ***/ private static CrashHandler INSTANCE = new CrashHandler(); /***程序的Context对象 ***/ private Context mContext; /***用来存储设备信息和异常信息 ***/ private Map<String, String> infos = new HashMap<String, String>(); /***用于格式化日期,作为日志文件名的一部分***/ private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");private String path; /** 证只有一个CrashHandler实例 */ private CrashHandler() { } /** 获取CrashHandler实例 ,单例模式 */ public static CrashHandler getInstance() { return INSTANCE; } /** * 初始化 * * @param context */ public void init(Context context) { mContext = context; //获取系统默认的UncaughtException处理器 mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler(); //设置该CrashHandler为程序的默认处理器 Thread.setDefaultUncaughtExceptionHandler(this); } /** * 当UncaughtException发生时会转入该函数来处理 */ @Override public void uncaughtException(Thread thread, Throwable ex) { if (!handleException(ex) && mDefaultHandler != null) { //如果用户没有处理则让系统默认的异常处理器来处理 mDefaultHandler.uncaughtException(thread, ex); } else { try { Thread.sleep(3000); } catch (InterruptedException e) { Log.e(TAG, "error : ", e); } //退出程序 android.os.Process.killProcess(android.os.Process.myPid()); System.exit(1); } } /** * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成. * * @param ex * @return true:如果处理了该异常信息;否则返回false. */ private boolean handleException(Throwable ex) { if (ex == null) { return false; } //收集设备参数信息 collectDeviceInfo(mContext); //保存日志文件 String crashInfoFile = saveCrashInfo2File(ex); // String substring = crashInfoFile.substring(0, crashInfoFile.indexOf("."));//去后缀 final List<File> crashFile = new ArrayList<File>(); File file = new File(path+crashInfoFile); crashFile.add(file); Log.e(TAG, path+crashInfoFile); //使用Toast来显示异常信息 new Thread() { @Override public void run() { Looper.prepare(); MyUtils.showToast(mContext, "亲!让我休息一下吧!"); String uploadMessage = UploadMessage(CrashHandler.this, "crashExp" , crashFile ); if (uploadMessage.equals("success")) { Log.e(TAG, "上传日志成功!");}else {Log.e(TAG, "上传日志失败!");} Looper.loop(); } }.start(); Intent intent = new Intent(mContext , MainActivity.class); PendingIntent restartIntent = PendingIntent.getActivity(mContext.getApplicationContext(), 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK); //退出程序 AlarmManager mgr = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE); mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, restartIntent); // 1秒钟后重启应用 // mContext.finishActivity(); return true; } /** * 收集设备参数信息 * @param ctx */ public void collectDeviceInfo(Context ctx) { 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 + ""; infos.put("versionName", versionName); infos.put("versionCode", versionCode); } } catch (NameNotFoundException e) { Log.e(TAG, "an error occured when collect package info", e); } Field[] fields = Build.class.getDeclaredFields(); for (Field field : fields) { try { field.setAccessible(true); infos.put(field.getName(), field.get(null).toString()); Log.d(TAG, field.getName() + " : " + field.get(null)); } catch (Exception e) { Log.e(TAG, "an error occured when collect crash info", e); } } } /** * 保存错误信息到文件中 * * @param ex * @return 返回文件名称,便于将文件传送到服务器 */ private String saveCrashInfo2File(Throwable ex) { StringBuffer sb = new StringBuffer(); for (Map.Entry<String, String> entry : infos.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); sb.append(key + "=" + value + "\n"); } Writer writer = new StringWriter(); PrintWriter printWriter = new PrintWriter(writer); ex.printStackTrace(printWriter); Throwable cause = ex.getCause(); while (cause != null) { cause.printStackTrace(printWriter); cause = cause.getCause(); } printWriter.close(); String result = writer.toString(); sb.append(result); try { long timestamp = System.currentTimeMillis(); String time = formatter.format(new Date()); String fileName = "crash-" + time + "-" + timestamp + ".log"; if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { path = "/sdcard/crash/"; File dir = new File(path); if (!dir.exists()) { dir.mkdirs(); } FileOutputStream fos = new FileOutputStream(path + fileName); fos.write(sb.toString().getBytes()); fos.close(); } return fileName ; } catch (Exception e) { Log.e(TAG, "an error occured while writing file...", e); } return null; } /***************** 把捕捉的异常发送给服务器 *********************/public String UploadMessage(CrashHandler crashHandler, String crashExp , List<File> files) {HttpParams connParams = new BasicHttpParams();HttpConnectionParams.setConnectionTimeout(connParams, 5 * 1000);HttpConnectionParams.setSoTimeout(connParams, 5 * 1000);HttpClient client = new DefaultHttpClient(connParams);/*** HttpClient client=new DefaultHttpClient();// 开启一个客户端 HTTP 请求**//** 创建 HTTP POST请求*//** 请求地址***/HttpPost post = new HttpPost("异常接口");MultipartEntityBuilder builder = MultipartEntityBuilder.create();/** 设置浏览器兼容模式**/builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);/** 添加文件,添加的是实体内容 */for (File file : files) {/*** 把文件转换成流对象FileBody***/FileBody fileBody = new FileBody(file);builder.addPart("errorLog" , fileBody);}/*** 添加文本内容,后面要添加格式 ***///try {//builder.addPart("crashExp",new StringBody(crashExp, Charset.forName("UTF-8")));//} catch (UnsupportedEncodingException e1) {//e1.printStackTrace();//}/** 生成 HTTP POST 实体**/HttpEntity entity = builder.build();/** 设置请求参数***/post.setEntity(entity);try {/***client.execute(post);//发起请求 并返回请求的响应**/HttpResponse response = client.execute(post);if (response.getStatusLine().getStatusCode() == 200) {HttpEntity json = response.getEntity();if (json != null) {String data = EntityUtils.toString(json, "utf-8").trim();JSONObject jsonObject = new JSONObject(data);String flag = jsonObject.getString("flag");if (flag.equals("1")) {return "success";}}}} catch (Exception e) {Log.e(TAG, e.getMessage());}return "";}}
1 0
- 全局异常捕捉并上传log到服务器
- Android全局捕获异常信息,并上传到服务器。
- Android程序异常捕捉并上传服务器
- 捕获全局异常,上传到服务器
- 捕获异常信息并上传到服务器
- 全局异常捕获,上传服务器
- 关于捕捉全局异常
- springboot全局异常捕捉
- Android全局异常捕捉
- 捕捉全局异常
- SpringBoot全局异常捕捉
- 捕捉全局异常
- springboot 全局异常捕捉
- Android全局异常捕捉器
- spring boot全局异常捕捉
- spring boot 全局异常捕捉
- Springboot全局异常的捕捉
- 捕捉全局异常简单篇
- 为什么使用Python, Python应用场景 特点
- centos 7 安装配置ELK
- 页面中设置IE浏览器的文档模式
- 深入理解javascript严格模式(Strict Mode)
- 大大
- 全局异常捕捉并上传log到服务器
- ORA-1555,oracle读一致性
- c++中两个类互相引用的问题
- listviewitem中的属性android:descendantFocusability用法
- 下拉刷新图片 缓存等待
- 线段树求解有序(可在过程中删除元素)第K大
- Android 沉浸式状态栏的实现
- Java四种线程池的使用
- org.apache.jasper.JasperException: The absolute uri: http://java.sun.com/jsp/jstl/core cannot be res