androidapp记录运行日志捕获奔溃异常,存储日志到文件

androidapp记录运⾏⽇志捕获奔溃异常,存储⽇志到⽂件app在运⾏过程中,为了后期的维护升级,记录⽇志是⼀个⾮常好的⽅法。
为了读取到app运⾏时的⽇志,⼀般的作法是单独开⼀个线程,在app运⾏的启动线程,然后app退出时停掉线程。
然⽽我们更好的⽅法是开启⼀个service,然后在⾥⾯做⽇志记录,代码如下:
打猎机
package com.hai.logcat;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.Service;
t.Intent;
import android.os.Environment;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;
public class MyLogcat extends Service {
Thread thread;
boolean readlog = true;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
Log.d("hhp", "onCreate");
thread = new Thread(new Runnable() {
@Override
public void run() {
log2();//个⼈觉得这个⽅法更实⽤
}
});
}
@Override
public void onStart(Intent intent, int startId) {
thread.start();
Log.d("hhp", "onStart");
}
/**
* ⽅法1
*/
private void log2() {
Log.d("hhp", "log2 start");
String[] cmds = { "logcat", "-c" };
String shellCmd = "logcat -v time -s *:W "; // adb logcat -v time *:W
Process process = null;
Runtime runtime = Runtime();
BufferedReader reader = null;
try {
<(cmds).waitFor();
process = (shellCmd);
reader = new BufferedReader(new InputStream()));            String line = null;
while ((line = adLine()) != null) {冷气机组
if (ains(String.valueOf(android.Pid()))) {
// line = new Bytes("iso-8859-1"), "utf-8");
writeTofile(line);
}
}
} catch (Exception e) {
e.printStackTrace();
}
Log.d("hhp", "log2 finished");
}
/**
* ⽅法2
*/
private void log() {
Log.d("hhp", "log start");
String[] cmds = { "logcat", "-c" };
String shellCmd = "logcat -v time -s *:W ";// //adb logcat -v time *:W
Process process = null;
InputStream is = null;
DataInputStream dis = null;
String line = "";
Runtime runtime = Runtime();
try {
<(cmds);
process = (shellCmd);
is = InputStream();
dis = new DataInputStream(is);
// String filter = GetPid();
String filter = android.Pid() + "";
while ((line = adLine()) != null) { //这⾥如果输⼊流没断,会⼀直循环下去。
line = new Bytes("iso-8859-1"), "utf-8");
if (ains(filter)) {
int pos = line.indexOf(":");
Log.d("hhp2", line + "");
writeTofile(line);
}
}
} catch (Exception e) {
}
Log.d("hhp", "log finished");
}
private void writeTofile(String line) {
String content = line + "\r\n";
File file = new ExternalStorageDirectory().getAbsolutePath()
+ "/");
if (!ists()) {立磨衬板
try {
} catch (Exception e) {
e.printStackTrace();
}
}
FileOutputStream fos;
try {
try {
fos = new FileOutputStream(file, true);
fos.Bytes());
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onDestroy() {
stopSelf();
}
}
代码⽐较简单,所以没怎么注视了。说下⼤概思路:在service开启的时候,就开启线程不停地从logcat中读取输⼊流,
把读到的信息存⼊⽂件中,service停⽌的时候线程stop,就这么简单。
当然要读⼊系统⽇志还需要添加权限:
上⾯的代码基本可以记录本app运⾏中的⽇志,但如果中途有未捕获的异常导致app奔溃,那么这个未捕获的异常导致的奔溃上⾯代码就记录不到了。
因为这个异常导致app奔溃,虚拟机挂掉,那当然记录⽇志的线程也停了。那怎么捕获这类我们未捕获的异常(运⾏时异常)呢,幸好android这样
⼀个接⼝UncaughtExceptionHandler,当app奔溃前,它会先通知这个接⼝,这样我们就可以在app奔溃前做点⾃⼰想做的事了。
package com.hai.logcat;
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 flect.Field;
import flect.Field;
DateFormat;
SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
t.Context;
t.pm.PackageInfo;
t.pm.PackageManager;
t.pm.PackageManager.NameNotFoundException;
import android.os.Build;
import android.os.Environment;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;
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  ");
/** 保证只有⼀个CrashHandler实例 */
private CrashHandler() {
}
广告伞制作/** 获取CrashHandler实例 ,单例模式 */
public static CrashHandler getInstance() {
return INSTANCE;
}
/**
* 初始化
*
* @param context
*/
public void init(Context context) {
mContext = context;
// 获取系统默认的UncaughtException处理器
mDefaultHandler = DefaultUncaughtExceptionHandler();
// 设置该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);
Thread.sleep(3000);
} catch (InterruptedException e) {
Log.e(TAG, "error : ", e);
}
// 退出程序
android.os.Process.killProcess(android.Pid());
光子重构
}
}
/
**
* ⾃定义错误处理,收集错误信息发送错误报告等操作均在此完成.
*
* @param ex
* @return true:如果处理了该异常信息;否则返回false.
*/
private boolean handleException(final Throwable ex) {
if (ex == null) {
return false;
}
// 使⽤Toast来显⽰异常信息
new Thread() {
@Override
public void run() {
Looper.prepare();
ex.printStackTrace();
Toast.makeText(mContext, "很抱歉,程序出现异常,即将退出.", Toast.LENGTH_LONG).show();
Looper.loop();
}
}.start();
// 收集设备参数信息
collectDeviceInfo(mContext);
/
/ 保存⽇志⽂件
saveCrashInfo2File(ex);
return true;
}
/**
* 收集设备参数信息
*
* @param ctx
*/
public void collectDeviceInfo(Context ctx) {
try {
PackageManager pm = PackageManager();
PackageInfo pi = pm.PackageName(), 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 = DeclaredFields();
for (Field field : fields) {
try {
field.setAccessible(true);
infos.Name(), (null).toString());
Log.d(TAG, Name() + " : " + (null));
} catch (Exception e) {
Log.e(TAG, "an error occured when collect crash info", e);
}
}
焙烧回转窑
}

本文发布于:2024-09-23 02:22:48,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/3/277434.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:系统   默认   线程   信息   程序   收集   记录   处理
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议