您的位置:首页 > 其它

捕获异常信息本地查看或者上传服务器

2016-03-15 15:03 375 查看
app运行在手机上,如果没有连接开发工具,那么报错的时候是看不到异常信息的,下面的这种方法,是把日志保存在手机文件里面,可以通过文件管理器查看,方便了开发者找异常

同时,这种方式也是多数开发者的选择,打印在本地,等下次开启应用并且有网的情况下,再把文件上传给服务器,这样就可以在服务器端很便捷的捕获不同用户的异常了,很方便维护

先写一个如下的类:

public class CrashHandler implements Thread.UncaughtExceptionHandler {
public static final String TAG = "CrashHandler";
private Context mContext;
private static CrashHandler crashHandler;
private Thread.UncaughtExceptionHandler defaultHandler;
private DateFormat format = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
private Map<String, String> infos = new HashMap<>();

private CrashHandler() {
}

public static CrashHandler newsIntance() {

if (crashHandler == null) {
synchronized (CrashHandler.class) {
if (crashHandler == null) {
crashHandler = new CrashHandler();
}
}
}

return crashHandler;
}

public void init(Context context) {
mContext = context;
defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
}

@Override
public void uncaughtException(Thread thread, Throwable ex) {

if (!handleException(ex) && defaultHandler != null) {
defaultHandler.uncaughtException(thread, ex);
}else {
defaultHandler.uncaughtException(thread, ex);
}
}

private boolean handleException(Throwable ex) {

if (ex == null) {
return false;
}

new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
Toast.makeText(mContext, "很抱歉,程序出现异常", Toast.LENGTH_SHORT).show();
Looper.loop();
}
}).start();

collectPackageeInfo();

saveCrashInfo2File(ex);
return true;
}

private void collectPackageeInfo() {
try {
PackageManager pm = mContext.getPackageManager();
PackageInfo packageInfo = pm.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES);
if (packageInfo != null) {
infos.put("versionName", packageInfo.versionName == null ? "null" : packageInfo.versionName);
infos.put("versionCode", packageInfo.versionCode + "");
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}

}

private void saveCrashInfo2File(Throwable ex) {

StringBuffer sb = new StringBuffer();
for (Map.Entry<String, String> entry : infos.entrySet()) {
sb.append(entry.getKey() + " = " + entry.getValue() + "\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 {
String time = format.format(new Date());
String appName = mContext.getResources().getString(R.string.app_name);
String fileName = "crash-" + time + "-" + appName + ".log";
String path = Environment.getExternalStorageDirectory() + "/crash/";
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
}
FileOutputStream fos = new FileOutputStream(path + fileName);
fos.write(sb.toString().getBytes());
fos.close();
} catch (Exception e) {
Log.e(TAG, "an error occured while writing file...", e);
}

}

}


然后再Application子类里面: CrashHandler.newsIntance().init(this);

public class QuestionApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
CrashHandler.newsIntance().init(this);
}
}


最后在Manifest.xml里面配置自己的Application子类

<application
xxxx
android:name=".QuestionApplication"
xxxx>


之后这个应用是可以在sd卡里面的crash文件夹里面找到打印的异常日志信息。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: