温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Android 之 LogDog

发布时间:2020-08-08 23:33:58 阅读:385 作者:panaimin 栏目:移动开发
Android开发者专用服务器限时活动,0元免费领,库存有限,领完即止! 点击查看>>

在写Android程序时,经常碰到在模拟器和调试器中无法捕捉的exception。有时自己运行好好的程序到了其他机器上就出现了问题。虽然Google Play有错误堆栈上传功能,但是没有办法把整个运行的过程记录下来。为此我写了一个LogDog类来试图解决这个问题。

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.Thread.UncaughtExceptionHandler;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.HashSet;

import android.content.Context;
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.util.Log;

public class LogDog implements UncaughtExceptionHandler {
	
	public static String 			TAG = "LogDog";
	
	private static HashSet	_tags = new HashSet();
	private static boolean			_debug = false;
	
	static {
		// add tags to be captured
		_tags.add(PDFMaster.TAG);
		_tags.add(RecentlyUsedActivity.TAG);
		_tags.add(DB.TAG);
	}

	public static LogDog instance() {
		return _instance;
	}
	
	public static void i(String tag, String message) {
		if(_debug) {
			Log.i(tag, message);
			return;
		}
		PrintWriter writer = _instance.getWriter();
		if(writer != null && _tags.contains(tag)) {
			_instance._writer.println("i:" + tag + ":" + message);
		}
	}

	public static void e(String tag, String message) {
		if(_debug) {
			Log.i(tag, message);
			return;
		}
		PrintWriter writer = _instance.getWriter();
		if(writer != null && _tags.contains(tag)) {
			_instance._writer.println("e" + tag + ":" + message);
		}
	}

	public static void w(String tag, String message) {
		if(_debug) {
			Log.i(tag, message);
			return;
		}
		PrintWriter writer = _instance.getWriter();
		if(writer != null && _tags.contains(tag)) {
			_instance._writer.println("w" + tag + ":" + message);
		}
	}

	public void init(Context context) {
		_context = context;
		_fileName = _context.getString(R.string.app_name) + ".log";
		_defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
		Thread.setDefaultUncaughtExceptionHandler(this);
	}
	
	public void close() {
		if(_writer != null) {
			_writer.close();
			_writer = null;
		}
	}
	
	// private
	
	private static LogDog					_instance = new LogDog();
	private static final String 			PATH =
		Environment.getExternalStorageDirectory().getPath() + "/log";
	private Context							_context;
	private String							_fileName;
	private Thread.UncaughtExceptionHandler	_defaultHandler;
	private PrintWriter						_writer = null;
	
	private LogDog() {
	}
	
	private PrintWriter getWriter() {
		if(_writer != null)
			return _writer;
		// check if we have SD card
		if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
			//Log.w(TAG, "sdcard unmounted,skip dump exception");
			return null;
		}
		File dir = new File(PATH);
		if (!dir.exists()) {
			dir.mkdirs();
		}
		File file = new File(PATH + "/" + _fileName);
		try {
			_writer = new PrintWriter(new BufferedWriter(new FileWriter(file)));
		} catch (IOException e) {
			//Log.e(TAG, "Failed to open " + PATH + "/" + FILE_NAME);
			_writer = null;
		}
		return _writer;
	}

	@Override
	public void uncaughtException(Thread thread, Throwable ex) {
		// first display a toast message
		new Thread() {
			@Override
			public void run() {
				Looper.prepare();
				PDFMarkerApp.instance().showToast("Sorry for the trouble, dumping uncaught exeption to SD card");
			}
		}.start();
		try {
			dump(ex);
		} catch (Exception e) {
			//Log.e(TAG, "Failed to dump because " + e.getMessage());
			e.printStackTrace();
		}
		if (_defaultHandler != null) {  
			_defaultHandler.uncaughtException(thread, ex);  
		} else {
			// sleep so the toast can have time to display
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
			}
			android.os.Process.killProcess(android.os.Process.myPid());  
		}
	}
	
	private void dump(Throwable ex) throws IOException, NameNotFoundException {
		PrintWriter writer = _instance.getWriter();
		if(writer == null)
			return;
		long current = System.currentTimeMillis();
		String time = new SimpleDateFormat("yyyyMMdd.HHmmss").format(new Date(current));
		_writer.println(time);
		PackageManager pm = _context.getPackageManager();
		PackageInfo pi = pm.getPackageInfo(_context.getPackageName(), PackageManager.GET_ACTIVITIES);
		_writer.print("App Version: ");
		_writer.print(pi.versionName);
		_writer.print('_');
		_writer.println(pi.versionCode);  
		_writer.print("OS Version: ");
		_writer.print(Build.VERSION.RELEASE);
		_writer.print("_");
		_writer.println(Build.VERSION.SDK_INT);
		_writer.print("Vendor: ");
		_writer.println(Build.MANUFACTURER);
		_writer.print("Model: ");
		_writer.println(Build.MODEL);
		_writer.print("CPU ABI: ");
		_writer.println(Build.CPU_ABI);
		_writer.println();
		ex.printStackTrace(_writer);
		close();
		File file = new File(PATH + "/" + _fileName);
		File file2 = new File(PATH + "/" + _fileName + "." + time + ".txt");
		file.renameTo(file2);
	}
	
}

在使用时所有的日志就全记录在一个文件中,直到最后的异常。每次异常都会单独被记录在一个文件中,连带所有需要知道的信息。要是正常运行,这个文件下次就被覆盖,不会造成空间问题。要是调试,只要把_debug改一下,所有日志就在LogCat中显示出来,非常方便。

亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI

开发者交流群×