面试官经验分享,你知道App为什么会Crash吗,2024年安卓社招面试题精选
private static class LoggingHandler implements Thread.UncaughtExceptionHandler {
public volatile boolean mTriggered = false;
@Override
public void uncaughtException(Thread t, Throwable e) {
mTriggered = true;
if (mCrashing) return;
//打印异常日志
if (mApplicationObject == null && (Process.SYSTEM_UID == Process.myUid())) {
Clog_e(TAG, "*** FATAL EXCEPTION IN SYSTEM PROCESS: " + t.getName(), e);
} else {
StringBuilder message = new StringBuilder();
message.append(“FATAL EXCEPTION: “).append(t.getName()).append(”\n”);
final String processName = ActivityThread.currentProcessName();
if (processName != null) {
message.append("Process: “).append(processName).append(”, ");
}
message.append("PID: ").append(Process.myPid());
Clog_e(TAG, message.toString(), e);
}
}
}
private static class KillApplicationHandler implements Thread.UncaughtExceptionHandler {
private final LoggingHandler mLoggingHandler;
public KillApplicationHandler(LoggingHandler loggingHandler) {
this.mLoggingHandler = Objects.requireNonNull(loggingHandler);
}
@Override
public void uncaughtException(Thread t, Throwable e) {
try {
ensureLogging(t, e);
if (mCrashing) return;
mCrashing = true;
if (ActivityThread.currentActivityThread() != null) {
ActivityThread.currentActivityThread().stopProfiling();
}
ActivityManager.getService().handleApplicationCrash(
mApplicationObject, new ApplicationErrorReport.ParcelableCrashInfo(e));
} catch (Throwable t2) {
if (t2 instanceof DeadObjectException) {
} else {
try {
Clog_e(TAG, “Error reporting crash”, t2);
} catch (Throwable t3) {
}
}
} finally {
//杀死进程
Process.killProcess(Process.myPid());
System.exit(10);
}
}
private void ensureLogging(Thread t, Throwable e) {
if (!mLoggingHandler.mTriggered) {
try {
mLoggingHandler.uncaughtException(t, e);
} catch (Throwable loggingThrowable) {
}
}
}
…
}
protected static final void commonInit() {
//设置异常处理回调
LoggingHandler loggingHandler = new LoggingHandler();
Thread.setUncaughtExceptionPreHandler(loggingHandler);
Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler(loggingHandler));
…
}
RuntimeInit有两个的内部类,LoggingHandler和KillApplicationHandler。
很显然,LoggingHandler的作用是打印异常日志,而KillApplicationHandler就是App发生Crash的真正原因,其内部调用了Process.killProcess(Process.myPid())来杀死发生Uncaught异常的进程。
我们还发现,这两个内部类都实现了Thread.UncaughtExceptionHandler接口。
分别通过Thread.setUncaughtExceptionPreHandler和Thread.setDefaultUncaughtExceptionHandler方法进行注册。
-
Thread.setUncaughtExceptionPreHandler,覆盖所有线程,会在回调DefaultUncaughtExceptionHandler之前调用,只能在Android Framework内部调用该方法
-
Thread.setDefaultUncaughtExceptionHandler,如果在任意线程中调用即可覆盖所有线程的异常,可以在应用层调用,每次调用传入的Thread.UncaughtExceptionHandler都会覆盖上一次的,即我们可以手动覆盖系统实现的KillApplicationHandler
-
new Thread().setUncaughtExceptionHandler(),只可以覆盖当前线程的异常,如果某个Thread有定义UncaughtExceptionHandler,则忽略全局DefaultUncaughtExceptionHandler
小结:Uncaught异常发生时会终止线程,此时,系统便会通知UncaughtExceptionHandler,告诉它被终止的线程以及对应的异常, 然后便会调用uncaughtException函数。
如果该handler没有被显式设置,则会调用对应线程组的默认handler。如果我们要捕获该异常,必须实现我们自己的handler。
上面说到了我们可以在应用层调用Thread.setDefaultUncaughtExceptionHandler来实现所有线程的Uncaught异常的监听,并且会覆盖系统的默认实现的KillApplicationHandler,这样我们就可以做到让线程发生Uncaught异常的时候只是当前杀死线程,而不会杀死整个进程。
这适用于我们的子线程发生Uncaught异常,如果我们的主线程发生Uncaught异常呢?
主线程都被销毁了,这和Crash似乎就没什么区别的。
那么我们有办法让主线程发生Uncaught异常也不会发生Crash吗?
答案是有的,但在讲如何实现之前我们先来介绍一些知识点。
我们知道Java程序开始于一个Main函数,如果只是顺序执行有限任务很快这个Main函数所在的线程就结束了。
如何来保持Main函数一直存活并不断的处理已知或未知的任务呢?
-
采用死循环。但是死循环的一次循环需要处理什么任务。如果任务暂时没有,也要程序保持活跃的等待状态怎么办?
-
如果有两个线程或者多个线程如何来协作以完成一个微型系统任务?
如果熟悉Android Handler机制的话,我们会了解到整个Android系统其实是消息驱动的。
Looper内部是一个死循环,不断地MessageQueue内部取出消息,由消息来通知做什么任务。
比如收到msg=H.LAUNCH_ACTIVITY,则调用ActivityThread.handleLaunchActivity()方法,最终会通过反射机制,创建Activity实例,然后再执行Activity.onCreate()等方法;
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
总结
作为一名从事Android的开发者,很多人最近都在和我吐槽Android是不是快要凉了?而在我看来这正是市场成熟的表现,所有的市场都是温水煮青蛙,永远会淘汰掉不愿意学习改变,安于现状的那批人,希望所有的人能在大浪淘沙中留下来,因为对于市场的逐渐成熟,平凡并不是我们唯一的答案!
一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算
作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!**](https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0)
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算
更多推荐
所有评论(0)