您的位置:首页 > 移动开发 > Android开发

Android使用UncaughtExceptionHandler捕获全局异常

2015-03-25 11:40 561 查看
最近使用的异常捕获案例:

package net.zdsoft.eis.android.system.activity;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.Thread.UncaughtExceptionHandler;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

import net.zdsoft.andframe.blue.entity.WebsiteConfig;
import net.zdsoft.andframe.blue.model.WebsiteConfigModel;
import net.zdsoft.andframe.green.db.helper.DBHelper;
import net.zdsoft.andframe.green.util.HttpUtils;
import net.zdsoft.andframe.green.util.ToastUtils;
import net.zdsoft.eis.android.R;
import net.zdsoft.eis.android.system.constants.Constants;
import net.zdsoft.eis.android.system.model.LoginConfig;

import org.apache.commons.io.IOUtils;

import android.app.Application;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Looper;
import android.util.DisplayMetrics;
import android.util.Log;

/**
* 安卓程序的真正入口点,代表整个应用的实例
*/
public class App extends Application {

// 系统默认异常处理handler
private UncaughtExceptionHandler defaultUncaughtExceptionHandler;
private LoginConfig loginConfig;

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

// android2.2不支持IpV6,以防止android2.2下mina报错
System.setProperty("java.net.preferIPv6Addresses", "false");

Resources resources = getResources();// 获得res资源对象
Configuration config = resources.getConfiguration();// 获得设置对象
DisplayMetrics dm = resources.getDisplayMetrics();// 获得屏幕参数:主要是分辨率,像素等。
config.locale = Locale.SIMPLIFIED_CHINESE; // 简体中文
resources.updateConfiguration(config, dm);

// 初始化数据库版本号
DBHelper.init(Integer.valueOf(getString(R.string.database_version)),getString(R.string.database_name));
Log.d(Constants.TAG, "application init");

defaultUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();

UncaughtExceptionHandler handler = new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
if (!handleException(e) && defaultUncaughtExceptionHandler != null) {
// 如果用户没有处理则让系统默认的异常处理器来处理
defaultUncaughtExceptionHandler.uncaughtException(t, e);
}
else {
try {
Thread.sleep(2000);
}
catch (InterruptedException e1) {
}

// 退出程序
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(1);
}
}

/**
* 用户试图自己处理异常
*
* @return 处理true,不处理false
*/
private boolean handleException(final Throwable e) {
if (e == null) {
return false;
}

Log.e(Constants.TAG, "检测到严重错误,程序即将退出", e);

//                final CountDownLatch latch = new CountDownLatch(1);
//                new Thread() {
//                    @Override
//                    public void run() {
//                        WebsiteConfigModel websiteConfigModel = new WebsiteConfigModel(getApplicationContext());
//                        String regionId = loginConfig.getLastLoginRegionId();
//                        WebsiteConfig w = websiteConfigModel.getWebsiteConfig(regionId);
//                        Map<String, String> map = new HashMap<String, String>();
//                        StringWriter str = new StringWriter();
//                        PrintWriter out = new PrintWriter(str);
//                        e.printStackTrace(out);
//                        out.flush();
//                        map.put("username", str.getBuffer().toString());
//                        IOUtils.closeQuietly(out);
//
//						if (w != null) {
//							HttpUtils.requestURLPost(w.getUrl()
//									+ "/android/recordError.action", map, "");
//						}
//
//                        Looper.prepare();
//                        ToastUtils.displayTextLong(getApplicationContext(), "很抱歉,程序出现异常,即将退出并重启.");
//                        latch.countDown();
//                        Looper.loop();
//                    }
//                }.start();
//
//                try {
//                    // 等待,直到记录错误信息的线程完成再执行
//                    latch.await();
//                    Thread.sleep(2000);
//                }
//                catch (InterruptedException e1) {
//                    // Ignore
//                }

return false;
}
};

// 设置线程异常处理
Thread.setDefaultUncaughtExceptionHandler(handler);

loginConfig = new LoginConfig(getApplicationContext());
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}

@Override
public void onTerminate() {
Log.d(Constants.TAG, "application onTerminate");
super.onTerminate();
}

@Override
public void onLowMemory() {
super.onLowMemory();
}

}
资料相关解释:

Android系统的“程序异常退出”,给应用的用户体验造成不良影响。为了捕获应用运行时异常并给出友好提示,便可继承UncaughtExceptionHandler类来处理。通过Thread.setDefaultUncaughtExceptionHandler()方法将异常处理类设置到线程上即可。

1、异常处理类,代码如下:
public class CrashHandler implements UncaughtExceptionHandler {
public static final String TAG = "CrashHandler";
private static CrashHandler INSTANCE = new CrashHandler();
private Context mContext;
private Thread.UncaughtExceptionHandler mDefaultHandler;

private CrashHandler() {
}

public static CrashHandler getInstance() {
return INSTANCE;
}

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

@Override
public void uncaughtException(Thread thread, Throwable ex) {
// if (!handleException(ex) && mDefaultHandler != null) {
// mDefaultHandler.uncaughtException(thread, ex);
// } else {
// android.os.Process.killProcess(android.os.Process.myPid());
// System.exit(10);
// }
System.out.println("uncaughtException");

new Thread() {
@Override
public void run() {
Looper.prepare();
new AlertDialog.Builder(mContext).setTitle("提示").setCancelable(false)
.setMessage("程序崩溃了...").setNeutralButton("我知道了", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
System.exit(0);
}
})
.create().show();
Looper.loop();
}
}.start();
}

/**
* 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成. 开发者可以根据自己的情况来自定义异常处理逻辑
*
* @param ex
* @return true:如果处理了该异常信息;否则返回false
*/
private boolean handleException(Throwable ex) {
if (ex == null) {
return true;
}
// new Handler(Looper.getMainLooper()).post(new Runnable() {
// @Override
// public void run() {
// new AlertDialog.Builder(mContext).setTitle("提示")
// .setMessage("程序崩溃了...").setNeutralButton("我知道了", null)
// .create().show();
// }
// });

return true;
}
}
2、线程绑定异常处理类
public class CrashHandlerActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
CrashHandler crashHandler = CrashHandler.getInstance();
crashHandler.init(this);  //传入参数必须为Activity,否则AlertDialog将不显示。
// 创建错误
throw new NullPointerException();
}
}


参考内容如下:

Demo下载地址:http://code.google.com/p/android-custom-view/downloads/list

地址: http://orgcent.com/android-uncaughtexceptionhandler-exception/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: