Android使用UncaughtExceptionHandler捕获全局异常

最近使用的异常捕获案例:

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/ 





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值