Android崩溃日志收集---CrashHandler,给你自残的理由

使用CrashHandler的目的

测试人员过来告诉你,“你写的代码崩溃了!”
“what ? ! 我写的代码怎么可能会崩溃?!你复现一下,污蔑我的话信不信自残给你看”
“哎,这次怎么好了,什么情况?”
虽然说这种几率性bug可以晚点解决,但是终归是要解决的,但是复现又有点困难,那怎么办?那就只能使用CrashHandler了

先看如何实现CrashHandler
public class CrashHandler implements Thread.UncaughtExceptionHandler {

    private static volatile CrashHandler crashHandler;

    private Context context;

    private CrashHandler(){}

    public void init(Context context){
        this.context = context;
        Thread.setDefaultUncaughtExceptionHandler(this);
    }

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

    @Override
    public void uncaughtException(Thread t, final Throwable e) {
        // 提示信息
        new Thread() {
            @Override
            public void run() {
                Looper.prepare();
                Intent intent = new Intent(context , CrashActivity.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.putExtra("exceptionOfCrash" , e.getMessage());
                context.startActivity(intent);
                Looper.loop();
            }
        }.start();
        ActivityCollector.finishAll();
        Process.killProcess(Process.myPid());
        System.exit(1);
    }
}

CrashHandler实现了UncaughtExceptionHandler 接口,通过重写uncaughtException函数来处理代码内部未捕获的异常,也就是运行崩溃异常,通过重写该函数可以使用自己的方式来处理运行时崩溃异常,因为系统的提示确实是有一点小瑕疵,我们自己处理可以先把崩溃日志上传,然后再给用户一个优雅的提示,然后优雅的关闭进程。虽然说所有的崩溃都是不合理的,但是我们可以至少让它友好一点。

剩余步骤
CrashActivity
public class CrashActivity extends BaseActivity {

    private TextView prompt , crashMessage;
    private String exceptionOfCrash;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_crash);
        initIntent();
        initView();
        countDownTimer.start();
    }

    private void initIntent() {
        Intent intent = getIntent();
        if (intent == null)return;
        exceptionOfCrash = intent.getStringExtra("exceptionOfCrash");
    }

    private void initView() {
        prompt = findViewById(R.id.prompt);
        crashMessage = findViewById(R.id.crashMessage);
        crashMessage.setText(exceptionOfCrash);
    }

    private CountDownTimer countDownTimer = new CountDownTimer(10000 , 1000) {
        @Override
        public void onTick(long millisUntilFinished) {
            prompt.setText(String.format(Locale.getDefault() , "Warning!\nnuclear missile will be launched in %1s second" , millisUntilFinished/1000));
        }

        @Override
        public void onFinish() {
            ActivityCollector.finishAll();
            Process.killProcess(Process.myPid());
            System.exit(1);
        }
    };

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK){
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
}

具体的用户友好提示和崩溃日志收集可以在这个界面完成

别忘了注册—Application
public class ProgramApplication extends Application{

    @Override
    public void onCreate() {
        super.onCreate();
        CrashHandler crashHandler = CrashHandler.getCrashHander();
        crashHandler.init(this);
    }
}
<application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:name=".ProgramApplication"
        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>
        <activity android:name=".CrashActivity"
            android:theme="@android:style/Theme.Light.NoTitleBar.Fullscreen"/>
    </application>

代码位置点这里

你可能感兴趣的:(android开发)