张绍文android开发高手课读书笔记1

本系列博文 基于是前微信高级工程师张绍文专栏 《Android开发高手课》的读书笔记。

文章所写内容是本人读完的感悟,需要原文的朋友请自行购买。

Android的开发前景如何

移动互联网发展不知不觉已经十多年过去了,“风口上的猪”也从Mobile First变成了AI First.

作为从业者的我们能很清楚的感受到移动端的招聘量变少了,但不得不提的是中高端岗位需求却更多了.

这说明移动互联网已经过了高速发展的阶段,逐渐成熟规范了。对从业者的要求也变高了,面对这种情况,

我们能做的就是不断提高自己的技术深度,同时也得扩宽技术广度.

至于一些跨平台技术,如RN,PWA,Week,以及Flutter虽然能代替一部分App开发的需求,但在最终的实现效果

上还是比不上原生开发。所以移动端的从业人员不要急着去改换门庭,应该花更多的时间去修炼内功.

另外移动端开发也不仅限于App开发,还有loT(物联网),音视频,VR/AR 等这些领域也是离不开移动互联网的.

崩溃优化

我们通常所说的崩溃就是指程序出现异常.Android下的崩溃分为java崩溃和Native崩溃。

其中java崩溃还算是比较好找的,网上也有挺多日志上报的方法.

而Native崩溃呢.一般都是因为在 Native 代码中访问非法地址,也可能是地址对齐出现了问题,或者发生了程序主动 abort,这些都会产生相应的 signal 信号,导致程序异常退出。

Android开发高手课中讲的多是Native崩溃的处理,然而我个人对这部分内容了解的也很少,所以下文多是摘取张老师专利中的重点内容。

Native入门可先看这篇博文 Android 平台 Native 代码的崩溃捕获机制及实现

Native 崩溃从捕获到解析一般要经历以下流程

  • 编译端。编译 C/C++ 代码时,需要将带符号信息的文件保留下来。
  • 客户端。捕获到崩溃时候,尽可能地将有用的信息写入日志,然后选择适当的时间传到服务器
  • 服务端 . 读取日志,寻找合适的符号文件,生成可读的C/C++调用栈.

第三方工具中比较成熟的当属Chromium的Breakpad

在异常捕获过程中最重要的是保证在各种极端情况下生成崩溃日志,同时要保证程序不发生二次崩溃。

生成日志时会出现的问题

  1. 文件句柄泄漏,导致创建日志文件失败,怎么办? 我们需要提前申请文件句柄 fd 预留,防止出现这种情况。
  2. 因为栈溢出了,导致日志生成失败,怎么办? 为了防止栈溢出导致进程没有空间创建调用栈执行处理函数,我们通常会使用常见的 signalstack。 在一些特殊情况,我们可能还需要直接替换当前栈,所以这里也需要在堆中预留部分空间。
  3. 整个堆的内存都耗尽了,导致日志生成失败,怎么办? 这个时候我们无法安全地分配内存,也不敢使用 stl 或者 libc 的函数,因为它们内部实现会分配堆内存 这个时候如果继续分配内存,会导致出现堆破坏或者二次崩溃的情况.Breakpad 做的比较彻底,重新封装了Linux Syscall Support,来避免直接调用 libc。
  4. 堆破坏或二次崩溃导致日志生成失败,怎么办? Breakpad 会从原进程 fork 出子进程去收集崩溃现场,此外涉及与 Java 相关的,一般也会用子进程去操作。 这样即使出现二次崩溃,只是这部分的信息丢失,我们的父进程后面还可以继续获取其他的信息。 在一些特殊的情况,我们还可能需要从子进程 fork 出孙进程。

当然对于一般的公司来说,要做这些还是有些强人所难,幸运的是市面上有合适的服务.比如腾讯的Bugly,阿里的啄木鸟平台,网易云捕等.

在热修复流行的当下,就算线上发送了一些崩溃,也可能通过打补丁来达到在线修复。但是如果崩溃发生在启动的时,在热修复代码执行之前,那就糟糕了。所以一些大公司的产品还会有"安全模式"来保障启动流程.

安全模式

在App热修复中有一个特殊情况,就是应用在启动阶段crash,根本启动不了,热修复就难以奏效。这个时候可以采取一种安全模式的启动方式.

简单来说,就是增加一个flag启动标记位,用来标记用户是否连续两次启动失败,这个时候就会进入安全模式进入修改阶段.修复的方式

  • 自修复,清空业务数据,尝试启动
  • 热修复,根据配置文件来判断是否修改
  • 重制为初始安装状态,将Document、Library、Cache三个根目录清空

详细可看 安全模式:天猫App启动保护实践

如何快速定位崩溃

发生崩溃就一定会有崩溃信息,那么我们应该看的是那部分信息?

1.崩溃基本信息

进程名、线程名。崩溃的进程是前台进程还是后台进程,崩溃是不是发生在 UI 线程。

崩溃的堆栈和类型.是java崩溃,Native崩溃,还是ANR.是自己的代码问题,还是系统的代码问题.

2.系统和应用的运行日志.

系统的event logcat会记录App运行的一些基本情况,记录在/system/etc/event-log-tags 中。

system logcat:
10-25 17:13:47.788 21430 21430 D dalvikvm: Trying to load lib ... 
event logcat:
10-25 17:13:47.788 21430 21430 I am_on_resume_called: 生命周期
10-25 17:13:47.788 21430 21430 I am_low_memory: 系统内存不足
10-25 17:13:47.788 21430 21430 I am_destroy_activity: 销毁 Activty
10-25 17:13:47.888 21430 21430 I am_anr: ANR 以及原因
10-25 17:13:47.888 21430 21430 I am_kill: APP 被杀以及原因
复制代码

3.机型、系统、厂商、CPU、ABI、Linux 版本等

上述这些数据可用作横向比较,你经常会发现某个问题只会在特定的情况下出现。

4.设备状态 是否root,是否是模拟器.有些问题是由Xposed 或多开软件造成

5.内存信息,考虑一些内存不足的崩溃是否多发生在低内存的手机上.

6.自定义的应用信息

这部分信息主要用来辅助定位崩溃位置.可以记录崩溃发生的位置,某个activity;还可以记录发生崩溃之前的几个操作步骤,便于复现崩溃场景.

解决崩溃

1.优先级: 优先解决Top 崩溃或者对业务有重大影响;其次简单易排查的java崩溃,疑难杂症放到最后

2.尝试复现:针对疑难杂症,可以通过早先在日志中自定义的应用信息来复现崩溃过程

3.着眼硬件:排查是否是手机系统,内存,机型引起的。

4.系统错误:有些问题是Android系统不同版本之间存在的问题。

最后,给自己公众号打个广告,【码农的唠叨】聊技术,聊热文,聊互联网趣事,也发唠叨

qrcode_for_gh_5febf245550e_258

猜你喜欢

转载自juejin.im/post/5c63f57f6fb9a04a006f82c3