程序启动即崩溃、Android 8.0真机崩溃重启过快,Android Studio无日志如何解决?
我来给你拆解下这两个场景的解决方案,都是我平时排查这类问题常用的办法:
场景1:程序启动阶段崩溃,Android Studio无错误日志输出
启动瞬间就挂掉的情况,往往是Android Studio的Logcat还没来得及和APP建立连接,所以得换个思路绕开AS的限制:
用ADB命令直接捕获系统日志:这是最稳妥的方式。先在终端执行这条命令:
adb logcat -v time *:E它会实时输出系统里所有错误级别的日志,包括APP启动崩溃的细节。执行完命令再启动APP,崩溃日志会直接打印在终端里。如果想保存日志方便后续分析,可以用:
adb logcat -d > crash_log.txt启动前先运行这个命令,APP崩溃后按
Ctrl+C停止,打开生成的crash_log.txt就能找到崩溃堆栈了。添加全局异常捕获逻辑:在你的
Application类里设置一个未捕获异常处理器,把崩溃日志写入手机本地文件,这样不管AS能不能捕获,你都能手动拿到日志。示例代码如下:@Override public void onCreate() { super.onCreate(); Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> { try { // 日志保存到APP的外部存储目录,需提前申请读写权限 File logFile = new File(getExternalFilesDir(null), "startup_crash.log"); PrintWriter writer = new PrintWriter(new FileWriter(logFile)); throwable.printStackTrace(writer); writer.flush(); writer.close(); } catch (IOException e) { e.printStackTrace(); } }); }崩溃后,你可以通过ADB拉取这个文件到电脑:
adb pull /sdcard/Android/data/你的包名/files/startup_crash.log ./调整Logcat过滤规则:有时候AS默认的「Show only selected application」会因为APP启动太快没跟上,你可以切换到「No Filters」,或者先通过
adb shell ps | grep 你的包名获取APP的进程ID(PID),然后在Logcat里用PID过滤,精准定位你的APP日志。
场景2:Android 8.0真机崩溃后重启过快,无法捕获日志
Android 8.0及以上对后台进程管理更严格,加上有些APP自身做了崩溃重启逻辑,导致日志被快速覆盖。试试这些办法:
临时关闭APP的自动重启逻辑:先检查代码里有没有监听崩溃后重启的逻辑,比如自定义
UncaughtExceptionHandler里的重启代码,或者AndroidManifest中Service设置的android:stopWithTask="false"(会导致服务崩溃后重启)。暂时注释掉这些逻辑,先拿到崩溃日志再说。用ADB持续记录日志到文件:在终端执行这条命令,让日志持续输出到文件,即使APP重启,之前的崩溃日志也会被完整保存:
adb logcat -v threadtime > crash_log.txt操作APP触发崩溃,等几秒后按
Ctrl+C停止命令,打开crash_log.txt从后往前找,一般能看到标记着FATAL EXCEPTION的崩溃堆栈。查看Logcat历史记录:很多版本的Android Studio都有Logcat历史功能,在Logcat窗口右上角的菜单里找到「Show Logcat History」,这里会保存之前的日志,包括APP崩溃后重启前的那段记录,说不定能找到你要的信息。
限制后台进程数量:打开手机开发者选项,找到「后台进程限制」,设置为「不得超过1个进程」,或者开启「不保留活动」。这样APP崩溃后系统不会快速重启它,给你足够时间在AS里捕获日志。
内容的提问来源于stack exchange,提问作者Birdie

