安卓捕获闪退异常

前言:解决用户远在他方但是出现了闪退问题无法调试和复现。
之前尝试使用如Thread.UncaughtExceptionHandler方式发现并不能捕获到异常并执行自己想要的操作,而且进程会阻塞导致ANR

步骤一:在app的入口类application的onCreate中添加如下代码

        new Handler(Looper.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        Looper.loop();
                    } catch (Throwable e) {
                        Log.e("Crash【主线程】", e.getMessage());
                        Intent intent = new Intent(getInstance(), CrashActivity.class);
                        intent.putExtra(INTENT_KEY_IN_THROWABLE, e);
                        getInstance().startActivity(intent);
                        System.out.println("捕获异常");
                    }
                }
            }
        });

步骤二:新建一个异常显示的activity,当出现异常会跳转该activity并展示异常信息

package com.fangtao.activities.other;

import android.os.Bundle;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import android.text.style.UnderlineSpan;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.fangtao.R;
import com.fangtao.activities.ClassificationActivity;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CrashActivity extends AppCompatActivity {

    private static final String INTENT_KEY_IN_THROWABLE = "throwable";

    /** 报错代码行数正则表达式 */
    private static final Pattern CODE_REGEX = Pattern.compile("\\(\\w+\\.\\w+:\\d+\\)");
    /** 系统包前缀列表 */
    private static final String[] SYSTEM_PACKAGE_PREFIX_LIST = new String[]
            {"android", "com.android", "androidx", "com.google.android", "java", "javax", "dalvik", "kotlin"};
    private static CrashActivity activity;

    private String mStackTrace;
    private TextView tvError;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_crash);
        activity = this;
        Bundle bundle = getIntent().getExtras();
        Throwable throwable = (Throwable)bundle.getSerializable(INTENT_KEY_IN_THROWABLE);
        tvError = findViewById(R.id.tv_error);

        StringWriter stringWriter = new StringWriter();
        PrintWriter printWriter = new PrintWriter(stringWriter);
        throwable.printStackTrace(printWriter);
        Throwable cause = throwable.getCause();
        if (cause != null) {
            cause.printStackTrace(printWriter);
        }
        mStackTrace = stringWriter.toString();
        Matcher matcher = CODE_REGEX.matcher(mStackTrace);
        SpannableStringBuilder spannable = new SpannableStringBuilder(mStackTrace);
        if (spannable.length() > 0) {
            while (matcher.find()) {
                // 不包含左括号(
                int start = matcher.start() + "(".length();
                // 不包含右括号 )
                int end = matcher.end() - ")".length();

                // 代码信息颜色
                int codeColor = 0xFF999999;
                int lineIndex = mStackTrace.lastIndexOf("at ", start);
                if (lineIndex != -1) {
                    String lineData = spannable.subSequence(lineIndex, start).toString();
                    if (TextUtils.isEmpty(lineData)) {
                        continue;
                    }
                    // 是否高亮代码行数
                    boolean highlight = true;
                    for (String packagePrefix : SYSTEM_PACKAGE_PREFIX_LIST) {
                        if (lineData.startsWith("at " + packagePrefix)) {
                            highlight = false;
                            break;
                        }
                    }
                    if (highlight) {
                        codeColor = 0xFF287BDE;
                    }
                }

                // 设置前景
                spannable.setSpan(new ForegroundColorSpan(codeColor), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                // 设置下划线
                spannable.setSpan(new UnderlineSpan(), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
            tvError.setText(spannable);
        }
    }

    public static CrashActivity getInstance() {
        return activity;
    }

}

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容