[douban] 02_程序异常的处理

Android 4.0

程序异常的处理
程序异常终止的处理,强行停止, UncaughtExceptionHandler接口 
程序崩溃处理

google默认实现是,弹出一个对话框
如果有try{}catch{},那么执行这里面的,
如果没有,那么执行 uncaughtException ()里面的处理方式

处理方式一:
在可能出现bug的程序中,设置自定义的异常处理方式
Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler());

处理方式二:
①定义一个Application,在onCreate()里面设置默认的异常处理方式
public class MyApp extends Application {
    @Override
    public void onCreate() {
        // super.onCreate();
        Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
    }
}
②自定义的异常处理类
package cn.zengfansheng.exception;
import java.lang.Thread.UncaughtExceptionHandler;
/**
 * 我的UncaughtExceptionHandler处理类
 * @author hacket
 *
 */
public class MyUncaughtExceptionHandler implements UncaughtExceptionHandler {
    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        System.out.println("我捕获到了异常~~~");
    }
}
③然后在uncaughtException()方法,获取应用程序版本,手机硬件信息,错误的堆栈信息,
④提交到服务器上去
⑤自杀
完整代码:

MyUncaughtExceptionHandler类

package cn.zengfansheng.exception;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.reflect.Field;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
/**
 * 我的UncaughtExceptionHandler处理类
 * @author hacket
 *
 */
public class MyUncaughtExceptionHandler implements UncaughtExceptionHandler {
    private Context context;
    // 一、单例
    // 保证MyUncaughtExceptionHandler只有一个实例
    // 1.私有化构造方法
    private MyUncaughtExceptionHandler() {
    }
    // 2.提供一个静态的程序变量
    private static MyUncaughtExceptionHandler myUncaughtExceptionHandler;
    // 3.暴露出来一个静态的方法 获取myCrashHandler
    public static synchronized MyUncaughtExceptionHandler getInstance() {
        if (myUncaughtExceptionHandler == null) {
            myUncaughtExceptionHandler = new MyUncaughtExceptionHandler();
        }
        return myUncaughtExceptionHandler;
    }
    // 二、获取上下文
    public void init(Context context) {
        this.context = context;
    }
    // 三、重写uncaughtException()获取信息
    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        System.out.println("我捕获到了异常~~~");
        StringBuilder sb = new StringBuilder();
        
        PackageManager pm = context.getPackageManager();
        try {
            // 1.获取当前应用程序的版本号.
            PackageInfo packinfo = pm.getPackageInfo(context.getPackageName(),0);
            sb.append("程序的版本号为" + packinfo.versionName);
            sb.append("\n");
            // 2.获取手机的硬件信息.反射获取
            Field[] fields = Build.class.getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                // 暴力反射,获取私有的字段信息
                fields[i].setAccessible(true);
                String name = fields[i].getName();// 字段名
                sb.append(name + " = ");
                String value = fields[i].get(null).toString();// 字段所对应的值
                sb.append(value);
                sb.append("\n");
            }
            // 3.获取程序错误的堆栈信息 .
            StringWriter writer = new StringWriter();
            PrintWriter printWriter = new PrintWriter(writer);
            ex.printStackTrace(printWriter);
            String result = writer.toString();
            sb.append(result);
            System.out.println(sb.toString());
            // 4.把错误信息 提交到服务器
            // TODO 异常信息提交到服务器
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 完成自杀的操作
        android.os.Process.killProcess(android.os.Process.myPid());
    }
}
结果:
02-11 21:03:44.018: I/System.out(26525): 我捕获到了异常~~~
02-11 21:03:44.038: I/System.out(26525): 程序的版本号为1.0
02-11 21:03:44.038: I/System.out(26525): BOARD = MSM8660_SURF
02-11 21:03:44.038: I/System.out(26525): BOOTLOADER = unknown
02-11 21:03:44.038: I/System.out(26525): BRAND = Xiaomi
02-11 21:03:44.038: I/System.out(26525): CPU_ABI = armeabi-v7a
02-11 21:03:44.038: I/System.out(26525): CPU_ABI2 = armeabi
02-11 21:03:44.038: I/System.out(26525): DEVICE = mione_plus
02-11 21:03:44.038: I/System.out(26525): DISPLAY = JZO54K
02-11 21:03:44.038: I/System.out(26525): FINGERPRINT = Xiaomi/mione_plus/mione_plus:4.1.2/JZO54K/4.1.10:user/release-keys
02-11 21:03:44.038: I/System.out(26525): HARDWARE = qcom
02-11 21:03:44.038: I/System.out(26525): HOST = wcc-miui-ota-bd17
02-11 21:03:44.038: I/System.out(26525): ID = JZO54K
02-11 21:03:44.038: I/System.out(26525): IS_DEBUGGABLE = true
02-11 21:03:44.038: I/System.out(26525): MANUFACTURER = Xiaomi
02-11 21:03:44.038: I/System.out(26525): MODEL = MI 1SC
02-11 21:03:44.038: I/System.out(26525): PRODUCT = mione_plus
02-11 21:03:44.038: I/System.out(26525): RADIO = unknown
02-11 21:03:44.038: I/System.out(26525): SERIAL = f0f02fad
02-11 21:03:44.038: I/System.out(26525): TAGS = release-keys
02-11 21:03:44.038: I/System.out(26525): TIME = 1389262724000
02-11 21:03:44.038: I/System.out(26525): TYPE = user
02-11 21:03:44.038: I/System.out(26525): UNKNOWN = unknown
02-11 21:03:44.038: I/System.out(26525): USER = builder
02-11 21:03:44.038: I/System.out(26525): java.lang.RuntimeException: Unable to start activity ComponentInfo{cn.zengfansheng.exception/cn.zengfansheng.exception.MainActivity}: java.lang.NullPointerException
02-11 21:03:44.038: I/System.out(26525):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2080)
02-11 21:03:44.038: I/System.out(26525):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2105)
02-11 21:03:44.038: I/System.out(26525):     at android.app.ActivityThread.access$600(ActivityThread.java:136)
02-11 21:03:44.038: I/System.out(26525):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1201)
02-11 21:03:44.038: I/System.out(26525):     at android.os.Handler.dispatchMessage(Handler.java:99)
02-11 21:03:44.038: I/System.out(26525):     at android.os.Looper.loop(Looper.java:137)
02-11 21:03:44.038: I/System.out(26525):     at android.app.ActivityThread.main(ActivityThread.java:4803)
02-11 21:03:44.048: I/System.out(26525):     at java.lang.reflect.Method.invokeNative(Native Method)
02-11 21:03:44.048: I/System.out(26525):     at java.lang.reflect.Method.invoke(Method.java:511)
02-11 21:03:44.048: I/System.out(26525):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
02-11 21:03:44.048: I/System.out(26525):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)
02-11 21:03:44.048: I/System.out(26525):     at dalvik.system.NativeStart.main(Native Method)
02-11 21:03:44.048: I/System.out(26525): Caused by: java.lang.NullPointerException
02-11 21:03:44.048: I/System.out(26525):     at cn.zengfansheng.exception.MainActivity.onCreate(MainActivity.java:13)
02-11 21:03:44.048: I/System.out(26525):     at android.app.Activity.performCreate(Activity.java:5084)
02-11 21:03:44.048: I/System.out(26525):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
02-11 21:03:44.048: I/System.out(26525):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2044)
02-11 21:03:44.048: I/System.out(26525):     ... 11 more