`
zheyiw
  • 浏览: 1017338 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

系统未知异常捕获和错误日志保存及上传 (崩溃异常)

阅读更多

//1,自定义Application捕获未知异常
public class HKBaseApplication extends Application {
	// activity对象列表,用于activity统一管理
	private List<Activity> activityList;
	// 异常捕获
	protected boolean isNeedCaughtExeption = true;// 是否捕获未知异常
	private PendingIntent restartIntent;
	private MyUncaughtExceptionHandler uncaughtExceptionHandler;
	public String packgeName;
	public String crashFilePath;

	@Override
	public void onCreate() {
		super.onCreate();

		activityList = new ArrayList<Activity>();
		packgeName = getPackageName();
		crashFilePath = Environment.getExternalStorageDirectory() + "/HKDownload/" + packgeName + "/crash/";

		if (isNeedCaughtExeption) {
			cauchException();
		}
	}

	// -------------------异常捕获-----捕获异常后重启系统-----------------//

	private void cauchException() {
		Intent intent = new Intent();
		// 参数1:包名,参数2:程序入口的activity
		intent.setClassName(packgeName, packgeName + ".LoginActivity");
		restartIntent = PendingIntent.getActivity(getApplicationContext(), -1, intent,
				Intent.FLAG_ACTIVITY_NEW_TASK);

		// 程序崩溃时触发线程
		uncaughtExceptionHandler = new MyUncaughtExceptionHandler();
		Thread.setDefaultUncaughtExceptionHandler(uncaughtExceptionHandler);
	}

	// 创建服务用于捕获崩溃异常
	private class MyUncaughtExceptionHandler implements UncaughtExceptionHandler {
		@Override
		public void uncaughtException(Thread thread, Throwable ex) {
			// 保存错误日志
			saveCatchInfo2File(ex);

			// 1秒钟后重启应用
			AlarmManager mgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
			mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, restartIntent);

			// 关闭当前应用
			finishAllActivity();
			finishProgram();
		}
	};

	/**
	 * 保存错误信息到文件中
	 * 
	 * @return 返回文件名称
	 */
	private String saveCatchInfo2File(Throwable ex) {
		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 sb = writer.toString();
		try {
			DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
			String time = formatter.format(new Date());
			String fileName = time + ".txt";
			System.out.println("fileName:" + fileName);
			if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
				File dir = new File(crashFilePath);
				if (!dir.exists()) {
					if (!dir.mkdirs()) {
						// 创建目录失败: 一般是因为SD卡被拔出了
						return "";
					}
				}
				System.out.println("filePath + fileName:" + crashFilePath + fileName);
				FileOutputStream fos = new FileOutputStream(crashFilePath + fileName);
				fos.write(sb.getBytes());
				fos.close();
				// 文件保存完了之后,在应用下次启动的时候去检查错误日志,发现新的错误日志,就发送给开发者
			}
			return fileName;
		} catch (Exception e) {
			System.out.println("an error occured while writing file..." + e.getMessage());
		}
		return null;
	}

	// ------------------------------activity管理-----------------------//

	// activity管理:从列表中移除activity
	public void removeActivity(Activity activity) {
		activityList.remove(activity);
	}

	// activity管理:添加activity到列表
	public void addActivity(Activity activity) {
		activityList.add(activity);
	}

	// activity管理:结束所有activity
	public void finishAllActivity() {
		for (Activity activity : activityList) {
			if (null != activity) {
				activity.finish();
			}
		}
	}

	// 结束线程,一般与finishAllActivity()一起使用
	// 例如: finishAllActivity;finishProgram();
	public void finishProgram() {
		android.os.Process.killProcess(android.os.Process.myPid());
	}
}


//2,在loginActivity中添加下面的代码发送异常日志给开发者
// 发送错误日志
private void sendCrashLog() {
	String lastCrashFileName = UtilPre.getString(this, UtilPre.Str.newCrashFileName, "");
	final String newCrashFileName = getNewCrashFile(app.crashFilePath, lastCrashFileName);
	if (lastCrashFileName.compareTo(newCrashFileName) < 0) {
		System.out.println("newCrashFileName:" + newCrashFileName);
		String ErrorMsg = UtilFile.readFromFile(app.crashFilePath, lastCrashFileName, true);
		// IMEI, ServiceIP, ClientType, ClientVersion, ErrorMsg
		TaskGetWhenNotLoginedIn task = new TaskGetWhenNotLoginedIn(this, "SDI_ClientError", new String[] {
				imei, Config.URLServer, "FAI_Android", currentVersionNo, ErrorMsg }) {
			public void onTaskSuccess(DataTable[] ds, boolean isAsk, String msg, ArrayList<String> msgList) {
				UtilPre.save(activity, UtilPre.Str.newCrashFileName, newCrashFileName);
			}

			@Override
			public void onTaskFailed(JSONObject result, String message) {
				// 忽略错误
			}
		};
		task.executeInBackground();
	}
}

// 获取新的错误日志文件名
private String getNewCrashFile(String filePath, String lastCrashFileName) {
	File root = new File(filePath);
	File[] files = root.listFiles();
	for (File file : files) {
		String fileName = file.getName();
		// System.out.println("遍历错误日志:" + fileName);
		if (lastCrashFileName.compareTo(fileName) < 0) {
			lastCrashFileName = fileName;
		}
	}
	return lastCrashFileName;
}
分享到:
评论

相关推荐

    捕获数学函数异常

    print(f"未知错误:{str(e)}") # 捕获所有其他未明确处理的异常 ``` 在这个例子中,我们首先尝试执行可能引发异常的数学操作。如果出现`ZeroDivisionError`,程序会打印出“错误:除以零”;如果`math.sqrt()`函数...

    Android application捕获崩溃异常怎么办

    1. 保存错误日志:在崩溃异常出现时,需要保存错误日志,以便于后续的错误分析和 debug。 2. 重启应用程序:在崩溃异常出现时,需要重启应用程序,以便于恢复应用程序的正常运行。 3. 关闭当前应用程序:在崩溃异常...

    捕获不可达的异常

    "捕获不可达的异常"这个话题涉及到的是如何在Java或其他支持异常处理的编程语言中,有效地管理和应对那些可能导致程序崩溃的错误。当一个异常发生,如果不进行处理,可能会导致"force closed"(强制关闭)的情况,...

    Android实现捕获未知异常并提交给服务器的方法

    此外,为了提供更全面的异常信息,还可以结合`Log`记录日志,使用`Android`的`Crashlytics`、`Fabric`或`Firebase Crash Reporting`等第三方服务,它们可以自动收集崩溃信息并上传,便于开发者分析。 总的来说,...

    C_Exception_Catch.rar_vc 异常_异常处理

    在VC++编程环境中,异常处理是一项至关重要的技能,特别是在处理可能导致程序崩溃的错误时。"C_Exception_Catch.rar_vc 异常_异常处理"这个压缩包文件似乎包含了关于如何在Visual C++(简称VC)中有效地捕获和处理...

    C#异常处理小例子

    总之,C#的异常处理机制通过`try-catch-finally`和`using`等语法糖,为开发者提供了强大且灵活的方式来处理程序中的错误和异常,确保了代码的稳定性和可靠性。在实际编程中,我们应该充分利用这些工具,编写出更加...

    Java中常见的异常分析

    在Java编程中,异常处理是一项至关重要的技能,它能够帮助开发者识别并处理程序运行时可能出现的问题,确保程序的健壮性和稳定性。...同时,良好的异常日志记录和监控也是确保系统稳定运行的重要手段。

    Java学习笔记之异常

    - **未知问题处理**:对于那些未预见的错误,合理的异常处理机制可以避免程序崩溃,并给出相应的错误提示。 #### 三、异常的关键字——try..catch..finally 在Java中,`try..catch..finally` 是异常处理的核心...

    C#097异常类型及版本 源代码

    在C#编程语言中,异常处理是程序设计中不可或缺的一部分,它确保了程序在遇到错误或意外情况时能够优雅地处理问题,而不是突然崩溃。"C#097异常类型及版本 源代码"这个主题主要关注的是C#中的异常处理机制、常见的...

    jstorm源码解析之bolt异常处理方法.docx

    对于可预见的异常,建议使用`FailedException`进行处理,而对于不可预见的异常,可以考虑增加日志记录和监控,以便在出现问题时能够及时发现和解决。在实际应用中,理解并灵活运用这些原则,可以帮助我们构建更加...

    总结了java容易出错的信息 以及错误信息类型

    Java编程语言中,错误和异常处理是程序健壮性的重要组成部分。这些异常和错误可以分为不同的类别,帮助开发者识别和修复程序中的问题。以下是对Java中常见错误和异常类型的详细解释: 1. **算术异常类:Arithmetic...

    MyException (2).zip_C#

    - 避免过度使用自定义异常,只在系统内建异常无法准确表达错误类型时使用。 - 在抛出自定义异常时,提供有意义的错误消息,帮助调试。 - 不要忽视捕获的异常,总是进行适当的处理,比如记录日志、通知用户或恢复...

    深度挖掘.NET Framework 2.0(9):.NET 2.0对未处理异常的处理以及跟踪技巧.rar

    通过合理使用try-catch-finally结构、未处理异常事件和跟踪设施,开发者可以提高代码的稳定性和可诊断性,减少因未知错误导致的问题。同时,对性能计数器的运用也能帮助我们持续监控和提升应用的性能。因此,深入...

    C# 中的异常处理

    - **记录异常**:使用日志记录工具记录异常信息,便于后续分析和调试。 - **清理资源**:使用`using`语句自动管理资源,或者结合`finally`块确保资源被正确关闭。 通过以上知识点的学习,我们可以更深入地理解如何...

    ActionScript3.0错误总集

    2. **使用try-catch语句**:通过在可能出现错误的代码段前后使用try-catch块,可以捕获并处理异常,防止程序崩溃。catch块内可以编写代码来处理异常,或者记录错误日志以供后续分析。 3. **调试工具**:Flash ...

    常见的HTTP错误消息类型

    - **未捕获的异常**:如果没有合适的错误处理机制(如`catch`或事件处理函数),异常未被处理,可能会导致程序崩溃。 正确处理错误是保证软件稳定性和用户体验的关键。对于同步错误,应使用`try-catch`结构捕获并...

    防止应用程序奔溃

    通过在代码中使用try-catch-finally结构,可以捕获可能出现的异常,并进行适当的处理,比如记录日志、提示用户或优雅地关闭程序,而不是让程序直接崩溃。 2. 日志记录:详尽的错误日志对于追踪和解决导致程序崩溃的...

    iOS实现保护APP不闪退

    2. **错误日志记录**:在捕获异常后,库会记录详细的错误信息,包括堆栈跟踪,这有助于开发者在后期分析和修复问题。这种日志记录功能对于定位线上问题非常有帮助。 3. **异常恢复**:在某些情况下,'JJException'...

Global site tag (gtag.js) - Google Analytics