Android面试(3)

  1. App启动流程

    1. 点击桌面App图标,Launcher进程采用Binder IPC向system_server进程发起startActivity请求;

    2. system_server进程接收到请求后,向zygote(zaigeut)进程发送创建进程的请求;

    3. Zygote进程fork出新的子进程,即App进程;

    4. App进程,通过Binder IPC向sytem_server进程发起attachApplication请求;

    5. system_server进程在收到请求后,进行一系列准备工作后,再通过binder IPC向App进程发送scheduleLaunchActivity请求;

    6. App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息;

    7. 主线程(ActivityThread)在收到Message后,通过发射机制创建目标Activity,并回调Activity.onCreate()等方法。

    8. 到此,App便正式启动,开始进入Activity生命周期,执行完onCreate/onStart/onResume方法,UI渲染结束后便可以看到App的主界面。

    img
  2. Android Crash之Java Crash分析

    参考资料:https://www.jianshu.com/p/1d3e8f251c9c

    https://juejin.cn/post/6844903620920492046

    基于第三方平台 bugly 采集crash信息(企鹅的)

    Crash就是由于代码异常而导致App非正常退出现象,也就是我们常说的崩溃

    • Java Crash

    • Native Crash

    1. Java Crash

      Java Crash在Android上的特点

      • 这类错误一般是由Java层代码触发的

      • 一般情况下程序出错时会弹出提示框,JVM虚拟机退出

      • 一般的Crash工具都能够捕获,系统也提供了API

      常见的Crash类型包括:空节点、角标越界、类型转换异常、实体对象没有序列化、数字转换异常、Activity或Service找不到等。

      NullPointException:

      NullPointerException是我们遇到最频繁的,造成这种Crash一般有两种情况:

      • 对象本身没有进行初始化就进行操作。

      • 对象已经初始化过,但是被回收或者手动置为null,然后对其进行操作。

      针对第一种情况导致的原因有很多,可能是开发人员的失误、API返回数据解析异常、进程被杀死后静态变量没初始化导致,我们可以做的有:

      • 对可能为空的对象做判空处理。

      • 养成使用@NonNull和@Nullable注解的习惯。

      • 尽量不使用静态变量,万不得已使用SharedPreferences来存储。

      • 考虑使用Kotlin语言。

      针对第二种情况大部分是由于Activity/Fragment销毁或被移除后,在Message、Runnable、网络等回调中执行了一些代码导致的,我们可以做的有:

      • Message、Runnable回调时,判断Activity/Fragment是否销毁或被移除;加try-catch保护;Activity/Fragment销毁时移除所有已发送的Runnable。

      • 封装LifecycleMessage/Runnable基础组件,并自定义Lint检查,提示使用封装好的基础组件。

      • 在BaseActivity、BaseFragment的onDestory()里把当前Activity所发的所有请求取消掉。

      IndexOutOfBoundsException:

      这类Crash常见于对ListView的操作和多线程下对容器的操作。

      针对ListView中造成的IndexOutOfBoundsException,经常是因为外部也持有了Adapter里数据的引用(如在Adapter的构造函数里直接赋值),这时如果外部引用对数据更改了,但没有及时调用notifyDataSetChanged(),则有可能造成Crash,对此我们封装了一个BaseAdapter,数据统一由Adapter自己维护通知, 同时也极大的避免了The content of the adapter has changed but ListView did not receive a notification,这两类Crash目前得到了统一的解决。

      另外,很多容器是线程不安全的,所以如果在多线程下对其操作就容易引发IndexOutOfBoundsException。常用的如JDK里的ArrayList和Android里的SparseArray、ArrayMap,同时也要注意有一些类的内部实现也是用的线程不安全的容器,如Bundle里用的就是ArrayMap。

    2. Native Crash

      Native Crash在Android上的特点

      • 出错时界面不会弹出提示框提醒程序崩溃(Android 5.0以下)

      • 出错时会弹出提示框提醒程序崩溃(Android 5.0以上)

      • 程序会直接闪退到系统桌面

      • 这类错误一般是由C++层代码错误引起的

      • 绝大部分Crash工具不能够捕获

      实际Android开发的时候,可能会引入第三方的一些so库或者自己开发相应的so库供程序使用,然而so库一般是通过c或者c++开发的。Android开发者通过java层的JNI机制调用Native语言写的函数,然而Natice语言也可以调用java层的函数。

      例子:

      我们可以Java层定义Native方法(本地方法跟普通的Java方法的区别在于方法声明多了native关键字。)

      img

      JNI层实现Native方法(这里我们制造一个Native Crash,空指针异常。)

      img

      通过Java调用Native方法(要调用Native方法需要先加载我们开发好的so库,通过System.loadLibrary("so名字");来调用,然后在通过java调用声明的native方法。)

      img

      我们在分析Java层Crash的时候是通过logcat日志找到对应的出错代码,然而Native层Crash也是可以logcat日志来进行分析的。在logcat添加完 "DEBUG" 的过滤项之后,我们就能得到具体log。

  3. ANR是什么?什么情况下会引起ANR,ANR设计原理?

    参考:https://cloud.tencent.com/developer/article/1190952

    ANR 全名 Application Not Responding,也就是"应用无响应"。当操作在一段时间内系统无法处理时,系统层面会弹出上图那样的 ANR 对话框。

    ANR分类:

    • KeyDispatchTimeout

      按键或触摸事件在特定时间内无响应:输入事件分发超时5s未响应完毕

    • BroadcastTimeout

      BroadcastReceiver在特定时间内无法处理完成:前台广播在10s内、后台广播在60秒内未执行完成

    • ServiceTimeout

      Service在特定的时间内无法处理完成:前台服务在20s内、后台服务在200秒内未执行完成

    • ContentProviderTimeout

      内容提供者,在publish过超时10s

    一般来说,界面相对越不“流畅”的App(说明UI线程耗时操作多)越容易发生ANR(一个输入事件在某个设备A上4秒有了反馈,并不意味着它在其他设备B上是安全的)。ANR其实就是界面卡顿的极端情况。

    容易发生ANR的场景:

    • 最常见的错误,UI线程等待其它线程释放某个锁,导致UI线程无法处理用户输入;

    • 游戏中每帧动画都进行了比较耗时的大量计算,导致CPU忙不过来;

    • Web应用中,网络状态不稳定,而界面在等待网络数据;

    • UI线程中进行了一些磁盘IO(包括数据库)、SD卡等等)的操作,在个别设备上因为硬件损坏等原因阻塞住了;

    • 手机被其他App占用着CPU,自己获取不到足够的CPU 时间片,纯属误伤。

    原理流程:

    拿Service来说,主要用于在后台处理一些耗时的逻辑,或者去执行某些需要长期运行的任务。但很多同志认为Service就可以执行耗时任务,这是一种误解,Service本身也运行于主线程,执行耗时任务同样会发生ANR。

    1. Service创建之前会延迟发送一个消息,而这个消息就是ANR的起源;

    2. Service创建完毕,在规定的时间之内执行完毕onCreate()方法就移除这个消息,就不会产生ANR了;

    3. 在规定的时间之内没有完成onCreate()的调用,消息被执行,ANR发生。

    ps:ContentProvider若发生超时,这里没有调用appNotResponding()(不像前3种),这里会杀掉进程并清理了相关信息。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,230评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,261评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,089评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,542评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,542评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,544评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,922评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,578评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,816评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,576评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,658评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,359评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,920评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,859评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,381评论 2 342

推荐阅读更多精彩内容