捕获异常打印日志

权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
    android:name=".EHApplication"
    。。。。。。。。。。。。。。。。。
</application>

MainActivity

public class MainActivity extends AppCompatActivity {
private List<String> list;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if(ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
            == PackageManager.PERMISSION_GRANTED){
    }else{
        ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},100);

    }
}
}
public void click(View v){
    Log.i("dt",list.size()+"");
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode==100){
        if (grantResults[0]==PackageManager.PERMISSION_GRANTED){
            Log.i("dt",list.size()+"");
        }
    }
}
}

EHApplication

public class EHApplication extends Application {

private static Context context;

@Override
public void onCreate() {
    super.onCreate();
    CrashHandler.getInstance().init(this);
    context = this;
}
public static Context getContext() {
    return context;
}
}

CrashHandler
//作用:
// 1.收集错误信息
// 2.保存错误信息

public class CrashHandler implements Thread.UncaughtExceptionHandler {
private static CrashHandler sInstance = null;
private Thread.UncaughtExceptionHandler mDefaultHandler;
	private Context mContext;
 // 保存手机信息和异常信息
 private Map<String, String> mMessage = new HashMap<>();
	public static CrashHandler getInstance() {
    if (sInstance == null) {
        synchronized (CrashHandler.class) {
            if (sInstance == null) {
                synchronized (CrashHandler.class) {
                    sInstance = new CrashHandler(); }}}
    return sInstance;
}
private CrashHandler() {
}
/**
 * 初始化默认异常捕获
 *
 * @param context context
 */
public void init(Context context) {
    mContext = context;
    // 获取默认异常处理器
    mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
    // 将此类设为默认异常处理器
    Thread.setDefaultUncaughtExceptionHandler(this);
}

@Override
public void uncaughtException(Thread t, Throwable e) {
    if (!handleException(e)) {
        // 未经过人为处理,则调用系统默认处理异常,弹出系统强制关闭的对话框
        if (mDefaultHandler != null) {
            mDefaultHandler.uncaughtException(t, e);
        }
    } else {
        // 已经人为处理,系统自己退出
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
        System.exit(1);
    }
}

/**
 * 是否人为捕获异常
 *
 * @param e Throwable
 * @return true:已处理 false:未处理
 */
private boolean handleException(Throwable e) {
    if (e == null) {// 异常是否为空
        return false;
    }
    new Thread() {// 在主线程中弹出提示
        @Override
        public void run() {
            Looper.prepare();
            Toast.makeText(mContext, "捕获到异常", Toast.LENGTH_SHORT).show();
            Looper.loop();
        }
    }.start();
    collectErrorMessages();
    saveErrorMessages(e);
    return false;
}

/**
 * 1.收集错误信息
 */
private void collectErrorMessages() {
    PackageManager pm = mContext.getPackageManager();
    try {
        PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(), PackageManager.GET_ACTIVITIES);
        if (pi != null) {
            String versionName = TextUtils.isEmpty(pi.versionName) ? "null" : pi.versionName;
            String versionCode = "" + pi.versionCode;
            mMessage.put("versionName", versionName);
            mMessage.put("versionCode", versionCode);
        }
        // 通过反射拿到错误信息
        Field[] fields = Build.class.getFields();
        if (fields != null && fields.length > 0) {
            for (Field field : fields) {
                field.setAccessible(true);
                try {
                    mMessage.put(field.getName(), field.get(null).toString());
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    }
}

/**
 * 2.保存错误信息
 *
 * @param e Throwable
 */
private void saveErrorMessages(Throwable e) {
    StringBuilder sb = new StringBuilder();
    for (Map.Entry<String, String> entry : mMessage.entrySet()) {
        String key = entry.getKey();
        String value = entry.getValue();
        sb.append(key).append("=").append(value).append("\n");
    }
    Writer writer = new StringWriter();
    PrintWriter pw = new PrintWriter(writer);
    e.printStackTrace(pw);
    pw.close();
    String result = writer.toString();
    sb.append(result);
    String fileName = "crash-" + "-" + System.currentTimeMillis() + ".log";
    // 有无SD卡
    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
        String path = Environment.getExternalStorageDirectory().getPath() + "/crash/";
        File dir = new File(path);
        if (!dir.exists()) dir.mkdirs();
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(path + fileName);
            fos.write(sb.toString().getBytes());
        } catch (Exception e1) {
            e1.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }
}
}
本资源为网传资源,为一套比较全的电商项目,系统架构采用SOA dubbo+EasyI实现,资源过大上传乃是下载链接,如有侵权请联系/留言,不多说下面上目录: 1.01 电商系统介绍2 f% Z/ C0 z% {1 l" q+ R 2.02 电商类型介绍6 r6 J' |. a2 F, t6 y; _. v# p2 J# ` 3.03 电商系统演示介绍! D$ C$ a1 K( q, c 4.04 电商数据结构介绍 5.05 电商数据结构设计器8 q9 r1 t3 Q( A# T" ?# P0 w+ n 6.06 电商数据准备 7.07 后台管理框架搭建 8.08 spu管理跳转 9.09 分类下拉列表的加载 10.10 商品发布的业务逻辑 11.1.建表 12.2.导数据 13.3.统一环境 14.4.生成js文件0 ~* z9 y2 K/ u; k+ N8 S# l* H: V! Y 15.01 商品spu参数提交- Q( T& z* U- B, ^: q) _ 16.02 商品spu图片上传服务介绍' ], M1 {0 w- x; Z' L. y 17.03 文件上传 工具 18.04 spu信息发布功能) G' E R g0 B( \* X + N& D7 p 19.05 spu动态图片追加% N0 H) M. o8 ~+ A 20.06 spu动态图片追加 21.07 属性功能管理介绍 22.08 属性功能管理介绍 23.09 属性保存功能跳转 24.10 属性双重集合参数3 Z4 [5 |4 D, k, M- G 25.11 属性保存功能业务层代码3 E: v6 D1 y: N* t5 X& Q, | 26.12 属性能业异步内嵌页8 t- |* |7 r# @ 27.13 属性集合查询) q& ~/ W) _9 c* r+ d: D5 Z% Y 28.01 属性的双重集合查询语句 29.02 sku功能介绍! m- K+ b0 K7 U* B! o* g3 S 30.03 sku功能跳转 31.04 客户端js函数中的el表达式 32.05 异步加载spu列表数据# M& R, \7 \3 y z- w+ a% }( g" ^ 33.06 用复选框操作属性列表显示 D+ k( T; J. J" `2 u 34.07 属性参数的提交) O0 o, s0 X \! P! @0 b& H 35.08 sku的数据结构说明8 m! S+ i9 k) W4 F# ?7 U 36.09 sku添加的业务实现1 |' b G% [! w/ J* C n; N 37.10 easyui的介绍 38.11 easyui的layout初始化介绍- v- C+ z# J) e- O* I! G 39.12 easyui手风琴控件介绍1 X/ X# \' k% x2 N 40.13 tree控件 41.14 tab控件: U, |: a! S7 ?: A$ t1 ?, G 42.1.properties% C2 @ d! }9 Z& ^2 c 43.2.主键9 D3 f9 W4 J* C" B4 M 44.3. 锚点. F( v2 C8 q- I# F+ G 45.01 数据表格的用法: e: S' z. T0 @8 T( `6 L 46.02 combobox的用法; _6 }2 p3 v: O7 l* } 47.03 嵌套布局的用法% L! U! L0 ]% B 48.04 easyui同步提交后跳转问题 49.05 乱码问题! {6 |( X* i) u; w! Y' B 50.06 首页初始化 51.07 用户登录方法 k, `) e/ R( F& m5 X 52.08 通过cookie取得用户的个性化信息, J7 ?0 ]' A) \6 E7 n5 K 53.09 通过客户端cookie取得用户的个性化信息0 i7 ], O/ }# H: t6 @: j) I+ i 54.10 用户个性化信息9 b% h5 O% p; I" P7 z 55.11 任务总结 56.01 商品检索介绍 57.02 商品分类检索介绍7 J% Q6 L& r: T6 N. H8 a- E6 Y% f" d" S4 I 58.03 商品分类检索sql: Z- N/ w: k; }2 b9 E( w8 I 59.04 商品分类检索列表 60.05 商品属性检索介绍 61.06 ajax字符串数组传参 62.07 ajax字符串json传参& i' g9 \7 ^! e7 _ 63.08 表单序列化传参 64.09 动态sql的设计方法" o# D. ?# R% _1 X 65.10 动态sql的实现 66.11 任务 67.1.项目演示 68.2.resu
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值