您的位置:首页 > 其它

你的程序会崩溃吗?

2015-09-19 17:40 218 查看
程序崩溃是最让人头疼的事情。当用户使用时,如果是第一次运行就崩溃,那此程序一定没戏了。即使是偶尔崩溃也会让用户心里很不爽。其实这不能全怪我们程序员。有些问题,我们也无法预知啊。但,作为一名优秀的程序员,我们还是拦过责任来,就是我们的问题。我处理就是了。

处理思路:捕捉崩溃异常,重启并报告异常。

那么现在就面临三个问题。一个是怎样捕捉Uncaught Exception,一个是重启并报告异常。



问题一,捕捉Uncaught Exception

对于此问题,其实Java早就为我们做好了。Android系统沿用了Java的处理机制。既然如此,我们拿来用就成了。Java里有一个UncaughtExceptionHandler的接口,接口里有一个uncaughtException()的方法。还有一个类叫ThreadGroup extends UncaughtExceptionHandler。所以我们有两种方法去捕捉Uncaught Exception了。一种是extends ThreadGroup类并Override uncaughtException()方法;一种是implements UncaughtExceptionHandler接口并Override uncaughtException()方法。代码请往下看。



问题二,重启并报告异常

重启程序呢,有很多种方法,但归根结底就是两种,一种是通过Intent直接打开,一种是通过AlarmManager来定时启动。 代码请往下看。

报告异常其实也就是得到String信息进行处理。代码往下看。

不要忘记要退出程序,怎么退出呢:System.exit(0);android.os.Process.killProcess(android.os.Process.myPid());还有通过ActivityManager来实现。其实在高版本android系统中这些方法都没用了,google把这些都给废弃限制了。不过对本文要讲的问题没有什么影响。本文中要加入System.exit(0);或android.os.Process.killProcess(android.os.Process.myPid);。ActivityManager这种是不可行的。已测试。



实例代码

AppContext.java

package com.study.exceptionhandler;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.lang.Thread.UncaughtExceptionHandler;

import android.app.AlarmManager;
import android.app.Application;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;

/**
 * @time 2015-09-19
 * @author Leo
 * @describe 应用管理和异常处理
 * 
 */
public class AppContext extends Application {

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		Thread.setDefaultUncaughtExceptionHandler(mExceptionHandler);// 设置默认异常处理类
	}

	@Override
	public void onLowMemory() {
		// TODO Auto-generated method stub
		super.onLowMemory();
		// insert handle code here
	}

	/**
	 * 自定义崩溃异常处理对象
	 */
	private UncaughtExceptionHandler mExceptionHandler = new UncaughtExceptionHandler() {

		@Override
		public void uncaughtException(Thread arg0, Throwable arg1) {
			// TODO Auto-generated method stub
			restartApplication1();
			System.exit(0);// 退出上次的程序 可以不加
			android.os.Process.killProcess(android.os.Process.myPid());
		}
	};

	/**
	 * 重启程序 程序不退出 但会闪屏
	 */

	private void restartApplication1() {
		Intent intent = getPackageManager().getLaunchIntentForPackage(
				getPackageName());
		intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
		startActivity(intent);
	}

	/**
	 * 重启程序 程序不退出 但会闪屏
	 */
	private void restartApplication2() {
		Intent intent = new Intent(getApplicationContext(), MainActivity.class);
		intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
				| Intent.FLAG_ACTIVITY_NEW_TASK);
		startActivity(intent);
	}

	/**
	 * 通过定时器重启程序 程序会退出再打开
	 */
	private void restartApplication3() {
		Intent intent = getPackageManager().getLaunchIntentForPackage(
				getPackageName());
		intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
				| Intent.FLAG_ACTIVITY_NEW_TASK);
		PendingIntent operation = PendingIntent.getActivity(
				getApplicationContext(), 0, intent,
				Intent.FLAG_ACTIVITY_NEW_TASK);
		AlarmManager mAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
		mAlarmManager.set(AlarmManager.RTC, System.currentTimeMillis(),
				operation);
	}

	/**
	 * 错误信息 你可以保存到文件里 也可上传到服务器 想怎么处理就怎么处理
	 * @param ex
	 * @return
	 */
	private String getErrorInfo(Throwable ex) {
		String info = null;

		ByteArrayOutputStream baos = null;
		PrintStream err = null;
		try {
			baos = new ByteArrayOutputStream();
			err = new PrintStream(baos);
			ex.printStackTrace(err);
			byte[] bytes = baos.toByteArray();
			info = new String(bytes);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (err != null)
				err.close();
			try {
				if (baos != null)
					baos.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		return info;
	}

}


总结

Bug是解决不完的,但还是要解决的。不要问为什么,努力解决就是了。这样技术慢慢就提高了,离大神越来越进了。加油。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: