Android-架构组件,节省你重复造轮子时间大厂面试题汇总

Android-架构组件,节省你重复造轮子时间大厂面试题汇总,第1张

概述前言:与其每天浑水摸鱼、浑浑噩噩,不如多进阶学习,提升自己的竞争力。Android中高级必会知识点:一、性能优化1、APP稳定性优化1.做过哪些稳定性方面的优化?2.性能稳定性是怎么做的?3.业务稳定性如何保障?4.如果出现异常,怎样快速止损?2、APP启动速度优化1.启动优化原理是什 前言:

与其每天浑水摸鱼、浑浑噩噩,不如多进阶学习,提升自己的竞争力。

AndroID中高级必会知识点:一、性能优化1、APP稳定性优化

1.做过哪些稳定性方面的优化?
2.性能稳定性是怎么做的?
3.业务稳定性如何保障?
4.如果出现异常,怎样快速止损?

2、APP启动速度优化

1.启动优化原理是什么?
2.是怎么异步的,异步遇到过什么问题吗?
3.启动优化有哪些容易被忽略的地方?
4.版本迭代导致的启动变慢有好的解决方式吗?

1、出现 ANR 的情况

满足下面的一种情况系统就会d出 ANR 提示

输入事件(按键和触摸事件) 5s 内没被处理;
broadcastReceiver 的事件 ( onRecIEve() 方法) 在规定时间内没处理完 (前台广播为 10s,后台广播为 60s);
Service 前台 20s 后台 200s 未完成启动;
ContentProvIDer 的 publish() 在 10s 内没进行完。
通常情况下就是主线程被阻塞造成的。

2、ANR 的实现原理

以输入无响应的过程为例(基于 9.0 代码):

最终d出 ANR 对话框的位置是与 AMS 同目录的类 AppErrors 的 handleShowAnrUi() 方法。这个类用来处理程序中出现的各种错误,不只 ANR,强行 Crash 也在这个类中处理。

    // base/core/java/com/androID/server/am/AppErrors.java    voID handleShowAnrUi(Message msg) {        Dialog dialogToShow = null;        synchronized (mService) {            AppNotRespondingDialog.Data data = (AppNotRespondingDialog.Data) msg.obj;            // ...            Intent intent = new Intent("androID.intent.action.ANR");            if (!mService.mProcessesReady) {                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY                        | Intent.FLAG_RECEIVER_FOREGROUND);            }            mService.broadcastIntentLocked(null, null, intent,                    null, null, 0, null, null, null, AppOpsManager.OP_NONE,                    null, false, false, MY_PID, Process.SYstem_UID, 0 /* Todo: Verify */);            boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),                    Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;            if (mService.canShowErrorDialogs() || showBackground) {                dialogToShow = new AppNotRespondingDialog(mService, mContext, data);                proc.anrDialog = dialogToShow;            } else {                Metricslogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR,                        AppNotRespondingDialog.CANT_SHOW);                // Just kill the app if there is no dialog to be shown.                mService.killAppAtUsersRequest(proc, null);            }        }        // If we've created a crash dialog, show it without the lock held        if (dialogToShow != null) {            dialogToShow.show();        }    }

不过从发生 ANR 的地方调用到这里要经过很多的类和方法。最初抛出 ANR 是在 inputdispatcher.cpp 中。我们可以通过其中定义的常量来寻找最初触发的位置:

// native/services/inputflinger/inputdispatcher.cppconstexpr nsecs_t DEFAulT_input_disPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec

从这个类触发的位置会经过层层传递达到 inputManagerService 中

// base/services/core/java/com/androID/server/input/inputManagerService.javaprivate long notifyANR(inputApplicationHandle inputApplicationHandle,        InputwindowHandle inputwindowHandle, String reason) {    return mWindowManagerCallbacks.notifyANR(            inputApplicationHandle, inputwindowHandle, reason);}

这里的 mWindowManagerCallbacks 就是 inputMonitor :

// base/services/core/java/com/androID/server/wm/inputMonitor.javapublic long notifyANR(inputApplicationHandle inputApplicationHandle,        InputwindowHandle inputwindowHandle, String reason) {    // ... 略    if (appWindowToken != null && appWindowToken.appToken != null) {        final AppWindowContainerController controller = appWindowToken.getController();        final boolean abort = controller != null                && controller.keydispatchingTimedOut(reason,                        (windowstate != null) ? windowstate.mSession.mPID : -1);        if (!abort) {            return appWindowToken.minputdispatchingTimeoutNanos;        }    } else if (windowstate != null) {        try {            // 使用 AMS 的方法            long timeout = ActivityManager.getService().inputdispatchingTimedOut(                    windowstate.mSession.mPID, aboveSystem, reason);            if (timeout >= 0) {                return timeout * 1000000L; // nanoseconds            }        } catch (remoteexception ex) {        }    }    return 0; // abort dispatching}

然后回在上述方法调用 AMS 的 inputdispatchingTimedOut() 方法继续处理,并最终在 inputdispatchingTimedOut() 方法中将事件传递给 AppErrors

// base/services/core/java/com/androID/server/am/ActivityManagerService.javapublic boolean inputdispatchingTimedOut(final ProcessRecord proc,        final ActivityRecord activity, final ActivityRecord parent,        final boolean aboveSystem, String reason) {    // ...    if (proc != null) {        synchronized (this) {            if (proc.deBUGging) {                return false;            }            if (proc.instr != null) {                Bundle info = new Bundle();                info.putString("shortMsg", "keydispatchingTimedOut");                info.putString("longMsg", annotation);                finishInstrumentationLocked(proc, Activity.RESulT_CANCELED, info);                return true;            }        }        mHandler.post(new Runnable() {            @OverrIDe            public voID run() {                // 使用 AppErrors 继续处理                mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);            }        });    }    return true;}

当事件传递到了 AppErrors 之后,它会借助 Handler 处理消息也就调用了最初的那个方法并d出对话框。

参考:《Android ANR原理分析》

3、ANR 的解决办法

上面分析了 ANR 的成因和原理,下面我们分析下如何解决 ANR.

1. 使用 adb 导出 ANR 日志并进行分析

发生 ANR的时候系统会记录 ANR 的信息并将其存储到 /data/anr/traces.txt 文件中(在比较新的系统中会被存储都 /data/anr/anr_* 文件中)。我们可以使用下面的方式来将其导出到电脑中以便对 ANR 产生的原因进行分析:

adb rootadb shell ls /data/anradb pull /data/anr/<filename>

在笔者分析 ANR 的时候使用上述指令尝试导出 ANR 日志的时候都出现了 Permission DenIEd。此时,你可以将手机 Root 之后导出,或者尝试修改文件的读写权限,或者在开发者模式中选择将日志导出到 sdcard 之后再从 sdcard 将日志发送到电脑端进行查看

2. 使用 DDMS 的 tracevIEw 进行分析

在 AS 中打开 DDMS,或者到 SDK 安装目录的 tools 目录下面使用 monitor.bat 打开 DDMS。

TraceVIEw 工具的使用可以参考这篇文章:《Android 性能分析之TraceView使用(应用耗时分析)》

这种定位 ANR 的思路是:使用 TraceVIEw 来通过耗时方法调用的信息定位耗时 *** 作的位置。

资料:

《ANR 官方文档》《Android 性能分析之TraceView使用(应用耗时分析)》3. 使用开源项目 ANR-WatchDog 来检測 ANR

项目地址是 Github-ANR-WatchDog

该项目的实现原理:创建一个检测线程,该线程不断往 UI 线程 post 一个任务,然后睡眠固定时间,等该线程又一次起来后检測之前 post 的任务是否运行了,假设任务未被运行,则生成 ANRError,并终止进程。

4. 常见的 ANR 场景

I/O 阻塞
网络阻塞
多线程死锁
由于响应式编程等导致的方法死循环
由于某个业务逻辑执行的时间太长
5. 避免 ANR 的方法
UI 线程尽量只做跟 UI 相关的工作;
耗时的工作 (比如数据库 *** 作,I/O,网络 *** 作等),采用单独的工作线程处理;
用 Handler 来处理 UI 线程和工作线程的交互;
使用 RxJava 等来处理异步消息。

最后

其实AndroID开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

上面分享的百度、腾讯、网易、字节跳动、阿里等公司2021年的高频面试题,博主还把这些技术点整理成了视频和pdf(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,上面只是以图片的形式给大家展示一部分。

Android学习PDF+学习视频+面试文档+知识点笔记

【AndroID思维脑图(技能树)】

知识不体系?这里还有整理出来的AndroID进阶学习的思维脑图,给大家参考一个方向。

【AndroID高级架构视频学习资源】

F+学习视频+面试文档+知识点笔记](https://docs.qq.com/doc/DSkNLaERkbnFoS0ZF)

【AndroID思维脑图(技能树)】

知识不体系?这里还有整理出来的AndroID进阶学习的思维脑图,给大家参考一个方向。

[外链图片转存中…(img-Tcy2Rd93-1623417596908)]

【AndroID高级架构视频学习资源】

**AndroID部分精讲视频领取学习后更加是如虎添翼!**进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对AndroID开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶AndroID中高级、架构师对你更是如鱼得水,赶快领取吧!

总结

以上是内存溢出为你收集整理的Android-架构组件,节省你重复轮子时间大厂面试题汇总全部内容,希望文章能够帮你解决Android-架构组件,节省你重复造轮子时间大厂面试题汇总所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1086274.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-27
下一篇 2022-05-27

发表评论

登录后才能评论

评论列表(0条)

保存