android cash现象分析,解决方案,异常重启

cash类型

最常见的cash类型应该是前2种(类型分析借鉴了一些网络资源,谢谢相关的作者)

1.ANR(Application Not Responding:无响应):

发生场景:应用发生ANR。

崩溃症状:系统弹出窗口询问用户选择“Force Close”或者“Wait”。

“Force Close”将杀掉发生ANR的应用进程。“Wait”将会等待系统择机恢复此应用进程。

发生原因:(1)应用主线程卡住,对其他请求响应超时。(2)死锁。(3)系统反应迟钝。(4)CPU负载过重。

2.Force Close:

发生场景:应用进程崩溃。

崩溃症状:系统弹出窗口提示用户某进程崩溃。

发生原因:空指向异常或者未捕捉的异常。

3.Tombstones:

发生场景:Native层崩溃

崩溃症状:如果发生崩溃的native层和UI有关联(比如Browser),我们可以在UI上发现这个崩溃。

如果发生崩溃的native层是在后台并且和UI没有直接联系,那么对于用户来说是不可见的,如果是debug版本可能会有Log打印出当时的底层现场。

发生原因:各种各样,需要具体情况具体分析。

4.系统服务崩溃(System Server Crash):

发生场景:系统服务是Android核心进程,此服务进程发生崩溃。

崩溃症状:手机重启到Android启动界面

发生原因:(1)系统服务看门狗发现异常。(2)系统服务发生未捕获异常。(3)OOM。(4)系统服务Native发生Tombstone。

5.Kernel Panics:

发生场景:Linux内核发生严重错误

崩溃症状:手机从bootloader开始完全重启

发生原因:(1)Linux内核内存空间发生内存崩溃。(2)内核看门狗发现异常。(3)空指针操作内核。


解决方案

1.针对主线程卡住,OOM、CPU、GPU负担过重导致的ANR
方案:优化代码结构,不要在主线程中进行耗时的操作,特别是IO相关如网络操作(最好设置超时参数),读写DB等操作。在内存和CPU方面遇到瓶颈的话,可以使用android提供的内存和CPU的调优工具进行定位相关代码和业务模块进行定位优化(稍后会介绍android性能调优相关,敬请期待OYO)。
注:很多新手喜欢用handler.post(Runnable runnable)方法进行异步操作,然而这样做并没有启动新线程,还是在主线程中。(OO||好吧,我承认我这样搞过)

2.针对未捕获到相关的异常,导致的cash
方案:在容易发生异常的地方使用try/catch捕获,并打印相应的异常日志(日志的持久化可以参考我的另一篇: android 使用log4j SLF4J 输出日志到文件中),分析异常发生的原因,并尽量的避免异常的发生。但是在程序设计之初不可能尽善尽美,万一异常没捕获到会导致很差的用户体验,所以可以依据后面的“异常重启”模块,添加相应的代码。

3.针对系统模块,底层代码发生的cash
方案:本人无能为力。。。。。静等google或民间大神。。。。。。

异常重启

在未捕捉到的异常抛出后能立即重新启动应用,并记录异常。
这里主要是用到Thread.setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler uncaughtExceptionHandler)这个方法,当当前线程有未捕获的异常抛出后,程序会执行uncaughtExceptionHandler中的uncaughtException(Thread thread, Throwable ex)方法。在该方法中启动一个定时服务,可以达到重启应用的目地。献上代码一份,在application的oncreate方法中调用,即可达到异常重启的目的:
    /**
     * 异常重启
     */
    PendingIntent restartIntent;
    public void uncaughtExceptionRestart(){
        Intent intent = new Intent();
        //XXX.XXActivity即是你要重新启动应用后显示的当前页面的完整路径
        intent.setClassName(包名, “XXX.XXActivity");
        restartIntent = PendingIntent.getActivity(getApplicationContext(), -1, intent,
                PendingIntent.FLAG_ONE_SHOT);
        Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread thread, Throwable ex) {
                // 0.1秒钟后重启应用
                AlarmManager mgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
                mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, restartIntent);
               // 做一些异常纪录工作
               // TODO
                // 关闭ACTIVITY栈中所有的activity,当然也可以不写,只是重现启动时的展示的页面未必是你定义的那个XXactivity。用的话自己实现finishAllActivity()
                // finishAllActivity();
                // 关闭当前应用
                android.os.Process.killProcess(android.os.Process.myPid());
            }
        });
    }

线网环境发生cash的跟踪与记录

有时候要拿到第一手的有效信息确实不容易,下面介绍2种可以及时跟踪cash的方法:
1.使用第三方平台
腾讯产品:Bugly( http://bugly.qq.com)功能强大自不必说。登陆自己的账号就可以看到自己的应用cash了多少次之类的各种报表统计,代码块定位信息等等。当然还有其他一些平台,自己找

2.推荐一个github的开源项目
支持将cash的信息发回自己的邮箱,貌似挺赞 https://github.com/msdx/android-crash



















你可能感兴趣的:(android)