ANR 弹窗的显示原理(2),2024年最新腾讯android面试题社招

思考一个面试题,一个 Service 运行在独立的进程里,在这个 Service 的 onCreate 方法里执行耗时操作会造成 ANR 吗?

直接说结论:会,但是不会有 ANR 的弹窗。

基础知识:

=====

ANR 的四种场景:

  1. Service TimeOut:  service 未在规定时间执行完成:前台服务 20s,后台 200s

  2. BroadCastQueue TimeOut: 未在规定时间内未处理完广播:前台广播 10s 内, 后台 60s 内

  3. ContentProvider TimeOut:  publish 在 10s 内没有完成

  4. Input Dispatching timeout:  5s 内未响应键盘输入、触摸屏幕等事件

ANR 的根本原因是:应用未在规定的时间内处理 AMS 指定的任务才会 ANR。

所以 Service 未在指定时间内执行完成而且非主进程的 Service 仍然需要通过 AMS 进行通信。这也能说明一定会产生 ANR 的。

实验:

===

理论上是会,那我们就写个小 demo 来试一下。

写一个 Service:

class NoZuoNoDieService: Service() {

override fun onBind(intent: Intent?): IBinder? {

return null

}

override fun onCreate() {

super.onCreate()

// 小睡会模拟耗时

Thread.sleep(21_000)

}

}

然后在 AndroidManifest 里声明在独立进程

<service

android:name=“.service.NoZuoNoDieService”

android:process=“:whatever”

/>

最后我们把这个 Service 调起来作死

startService(Intent(this, NoZuoNoDieService::class.java))

应用并没有 ANR 弹窗,不过 logcat 有 ANR 相关信息,看一下 trace 文件:

----- pid 14608 at 2021-03-23 19:56:20 -----

Cmd line: demo.com.sam.demofactory:whatever

… 省略无关信息

“main” prio=5 tid=1 Sleeping

| group=“main” sCount=1 dsCount=0 flags=1 obj=0x73f13a80 self=0x78e7cc2a00

| sysTid=14608 nice=0 cgrp=default sched=0/0 handle=0x796c96d9a8

| state=S schedstat=( 57816925 3067496 80 ) utm=2 stm=3 core=4 HZ=100

| stack=0x7fe1d03000-0x7fe1d05000 stackSize=8MB

| held mutexes=

at java.lang.Thread.sleep(Native method)

  • sleeping on <0x0a71f3e8> (a java.lang.Object)

at java.lang.Thread.sleep(Thread.java:373)

  • locked <0x0a71f3e8> (a java.lang.Object)

at java.lang.Thread.sleep(Thread.java:314)

at demo.com.sam.demofactory.service.NoZuoNoDieService.onCreate(NoZuoNoDieService.kt:15)

at android.app.ActivityThread.handleCreateService(ActivityThread.java:3426)

at android.app.ActivityThread.-wrap4(ActivityThread.java:-1)

at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1744)

at android.os.Handler.dispatchMessage(Handler.java:106)

at android.os.Looper.loop(Looper.java:171)

at android.app.ActivityThread.main(ActivityThread.java:6611)

at java.lang.reflect.Method.invoke(Native method)

at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)

at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

ANR 弹窗的显示原理

===========

我们来看一下这个没有弹窗的 ANR 是怎么发生的

首先来复习一下 说一说 Service 的启动流程

AMS 真正去启动 Service 调用的是 ActiveServices.realStartServiceLocked 方法:

// API 29 com.android.server.am.ActiveServices

private final void realStartServiceLocked(ServiceRecord r,

ProcessRecord app, boolean execInFg) throws RemoteException {

bumpServiceExecutingLocked(r, execInFg, “create”);

}

private final void bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why) {

scheduleServiceTimeoutLocked(r.app);

}

// 通过 Handler 延时发一条消息,延时时间则为 Service 触发的 ANR 时长

// SERVICE_TIMEOUT = 20*1000

// SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10;

void scheduleServiceTimeoutLocked(ProcessRecord proc) {

if (proc.executingServices.size() == 0 || proc.thread == null) {

return;

}

Message msg = mAm.mHandler.obtainMessage(

ActivityManagerService.SERVICE_TIMEOUT_MSG);

msg.obj = proc;

mAm.mHandler.sendMessageDelayed(msg,

proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);

}

如果 Service 在规定时间内启动完成,则这个消息会被 remove 掉,我们今天要看一下超时之后,收到这个消息是怎么处理的。

// com.android.server.am.ActivityManagerService.MainHandler

final class MainHandler extends Handler {

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case SERVICE_TIMEOUT_MSG: {

mServices.serviceTimeout((ProcessRecord)msg.obj);

} break;

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

分享读者

作者2013年java转到Android开发,在小厂待过,也去过华为,OPPO等大厂待过,18年四月份进了阿里一直到现在。

被人面试过,也面试过很多人。深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长,而且极易碰到天花板技术停滞不前!

我们整理了一份阿里P7级别的Android架构师全套学习资料,特别适合有3-5年以上经验的小伙伴深入学习提升。

主要包括阿里,以及字节跳动,腾讯,华为,小米,等一线互联网公司主流架构技术。如果你有需要,尽管拿走好了。

35岁中年危机大多是因为被短期的利益牵着走,过早压榨掉了价值,如果能一开始就树立一个正确的长远的职业规划。35岁后的你只会比周围的人更值钱。

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img
及字节跳动,腾讯,华为,小米,等一线互联网公司主流架构技术。如果你有需要,尽管拿走好了。

[外链图片转存中…(img-kl7exxq7-1712781243804)]

35岁中年危机大多是因为被短期的利益牵着走,过早压榨掉了价值,如果能一开始就树立一个正确的长远的职业规划。35岁后的你只会比周围的人更值钱。

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-kBlr2ba9-1712781243804)]

  • 12
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值