android 自定义处理全局异常

本文介绍了一种在Android应用中实现全局异常捕获和处理的方法。通过自定义异常处理类CrashHandler并重写uncaughtException方法,可以在应用崩溃前收集设备信息及异常堆栈,并将这些信息保存到本地文件中,最后选择重启应用或优雅地退出。
摘要由CSDN通过智能技术生成

android 自定义处理全局异常


一、创建异常:

public class MainActivity extends AppCompatActivity {

    String nullString;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Log.i("mytool", nullString.equals("")+"");

    }
}

二、自定义全局错误处理类:

/**
 * Created by liyihang on 17-7-14.
 * 用户为处理异常全局处理类
 */

public class CrashHandler implements Thread.UncaughtExceptionHandler {

    private Thread.UncaughtExceptionHandler defaultUncaughtExceptionHandler;
    private Context mContext;
    private HashMap<String, String> infos=new HashMap<>();

    private CrashHandler(){

    }

    public static CrashHandler instance=null;

    public static CrashHandler getInstance(){
        if (instance==null)
        {
            synchronized (CrashHandler.class)
            {
                if (instance==null)
                {
                    instance=new CrashHandler();
                }
            }
        }
        return instance;
    }

    /**
     *
     * 初始化获取默认错误处理机制
     * 使用自定义错误类替换错误处理
     * @param context 上下文
     */
    public void init(Context context){
        mContext = context;
        defaultUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
        Thread.setDefaultUncaughtExceptionHandler(this);
    }


    /**
     *
     * 系统异常处理回调
     * @param thread
     * @param throwable
     */
    @Override
    public void uncaughtException(Thread thread, Throwable throwable) {
        if (! handlerException(throwable) && defaultUncaughtExceptionHandler!=null)
        {
            //使用系统默认错误处理机制
            defaultUncaughtExceptionHandler.uncaughtException(thread, throwable);
        }else {
            //暂停用来程序处理
            try {
                Thread.sleep(2300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            android.os.Process.killProcess(Process.myPid());
            System.exit(1);
        }
    }

    private boolean handlerException(Throwable throwable) {
        if (throwable==null)
        {
            return false;
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                Looper.prepare();
                Toast.makeText(mContext, "application error exit",Toast.LENGTH_LONG).show();
                Looper.loop();
            }
        }).start();
        getDevicesInfo();
        saveCrashInfo(throwable);
        return true;
    }


    /**
     *
     * 保存系统异常信息
     * @param throwable
     */
    private void saveCrashInfo(Throwable throwable) {
        StringBuffer buffer=new StringBuffer();
        Set<String> strings = infos.keySet();
        for (String string : strings) {
            buffer.append(string+"=="+infos.get(string)+"\n");
        }

        StringWriter stringWriter = new StringWriter();
        PrintWriter printWriter = new PrintWriter(stringWriter);
        throwable.printStackTrace(printWriter);
        Throwable cause = throwable.getCause();
        while (cause!=null)
        {
            cause.printStackTrace(printWriter);
            cause = cause.getCause();
        }
        printWriter.close();

        String s = stringWriter.toString();
        Log.i("mytool", ""+s);
        buffer.append(s);

        try {
            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
                File file=new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/error.txt");
                FileOutputStream fileOutputStream=new FileOutputStream(file);
                fileOutputStream.write(buffer.toString().getBytes());
                fileOutputStream.flush();
                fileOutputStream.close();
            }
        }catch (Exception e){
            Log.i("mytool", "error info=="+e.getMessage());
        }

    }

    /**
     *
     * 获取设备异常信息
     */
    private void getDevicesInfo() {

        try {
            PackageManager packageManager = mContext.getPackageManager();
            PackageInfo packageInfo = packageManager.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES);
            if (packageInfo!=null)
            {
                String versionName = packageInfo.versionName+"";
                String versionCode = packageInfo.versionCode+"";
                Log.i("mytool", "version name=="+versionName);
                Log.i("mytool", "version code=="+versionCode);
            }
        }catch (Exception e){
            Log.i("mytool", "error info=="+e.getMessage());
        }
        Field[] declaredFields = Build.class.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            try {
                declaredField.setAccessible(true);
                infos.put(declaredField.getName(), declaredField.get(null).toString());
                Log.i("mytool", declaredField.getName()+"=="+declaredField.get(null).toString());
            }catch (Exception e){
                Log.i("mytool", "error info=="+e.getMessage());
            }
        }

    }
}

三、在application中调用:

/**
 * Created by liyihang on 17-7-14.
 */

public class MyAppliction extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        CrashHandler.getInstance().init(getApplicationContext());
    }

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

    }
}

四、设置主配置文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.javadome.liyihang.javadome">

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <application
        android:name=".MyAppliction"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值