极客时间总结

极客时间总结

学到的知识:

  1. Bitmap都在Java堆内存,经常会oom,8.0以后有个硬件位图 Hardware Bitmap,它可以减少图片内存并提升绘制效率。像素数据放到 Native 内存中的。最大的 Java 堆限制也才到 512MB,可能我的物理内存还有 5GB
  • SharedPreferences跨进程会导致数据丢失
  • 网络数据压缩,有个库压缩比默认gzip算法更厉害,节约大量的带宽成本
  • xml x2c
  • 异步的textview。,把 measure 和 layout 都放到了后台线程,只留下了必须要在主线程完成的 draw,这大大降低了 UI 线程的负载。
  • 谷歌有个 Protocol Buffers,比json数据更小,是二进制格式
  • 一个 100MB 的文件裁剪后一般只剩下 30MB 左右,使用 7zip 压缩最后小于 10MB,增加了文件上传的成功率。

Android开发高手课

内存优化

Android 3.0~Android 7.0 将 Bitmap 对象和像素数据统一放到 Java 堆中,这样就算我们不调用 recycle,Bitmap 内存也会随着对象一起被回收。不过 Bitmap 是内存消耗的大户,把它的内存放到 Java 堆中似乎不是那么美妙。即使是最新的华为 Mate 20,最大的 Java 堆限制也才到 512MB,可能我的物理内存还有 5GB,但是应用还是会因为 Java 堆内存不足导致 OOM。Bitmap 放到 Java 堆的另外一个问题会引起大量的 GC,对系统内存也没有完全利用起来。

将 Bitmap 内存放到 Native 中,也可以做到和对象一起快速释放,同时 GC 的时候也能考虑这些内存防止被滥用。NativeAllocationRegistry 可以一次满足你这三个要求,Android 8.0 正是使用这个辅助回收 Native 内存的机制,来实现像素数据放到 Native 内存中。Android 8.0 还新增了硬件位图 Hardware Bitmap,它可以减少图片内存并提升绘制效率。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 步骤一:申请一张空的 Native Bitmap
Bitmap nativeBitmap = nativeCreateBitmap(dstWidth, dstHeight, nativeConfig, 22);

// 步骤二:申请一张普通的 Java Bitmap
Bitmap srcBitmap = BitmapFactory.decodeResource(res, id);

// 步骤三:使用 Java Bitmap 将内容绘制到 Native Bitmap 中
mNativeCanvas.setBitmap(nativeBitmap);
mNativeCanvas.drawBitmap(srcBitmap, mSrcRect, mDstRect, mPaint);

// 步骤四:释放 Java Bitmap 内存
srcBitmap.recycle();
srcBitmap = null

Protocol Buffers

文件遍历在 API level 26 之后建议使用FileVisitor,替代 ListFiles,整体的性能会好很多。

ec4efbcad6a976425731ebcfdf4917ef
Mars的好处就是跨平台、长链接,看情况

网络数据压缩
QQ截图20190509231931
QQ截图20190509231800

电量

Android 是基于 Linux 内核,而 Linux 大部分使用在服务器中,它对功耗并没有做非常严格苛刻的优化。特别是国内会有各种各样的“保活黑科技”,大量的应用在后台活动简直就是“电量黑洞”。

耗电量这块, 因为要维持推送的实时到达, 只能追求黑科技, 要不然人家就会问,为啥苹果可以收到推送,android就不行~ 但是保活就会加大耗电

耗电优化的第一个方向是优化应用的后台耗电。因为用户最容易感知这个,我明明没有怎么打开,为什么耗这么多?在后台不要做这些:长时间获取 WakeLock(及时释放)、WiFi 和蓝牙的扫描、GPS、video、audio

WakeLock 用来阻止 CPU、屏幕甚至是键盘的休眠。类似 Alarm、JobService 也会申请 WakeLock 来完成后台 CPU 操作.
Alarm 用来做一些定时的重复任务

通过 Hook,我们可以在申请资源的时候将堆栈信息保存起来。当我们触发某个规则上报问题的时候,可以将收集到的堆栈信息、电池是否充电、CPU 信息、应用前后台时间等辅助信息也一起带上。

UI优化

对于硬件绘制,我们通过调用 OpenGL ES 接口利用 GPU 完成绘制。opengl是一个跨平台的图形 API,它为 2D/3D 图形处理硬件指定了标准软件接口。而 OpenGL ES 是 OpenGL 的子集,专为嵌入式设备设计。

使用 XML 进行 UI 编写可以说是十分方便,可以在 Android Studio 中实时预览到界面。如果我们要对一个界面进行极致优化,就可以使用代码进行编写界面。

xml缺点
读取xml很耗时
递归解析xml较耗时
反射生成对象的耗时是new的3倍以上

x2c:在编译的时候,通过注解的方式,将xml转换成Java代码

QQ截图20190511135645

measure/layout 优化

  • 减少布局的嵌套(viewstub、merge、include)
  • 尽量不使用 RelativeLayout 或者基于 weighted LinearLayout,它们 layout 的开销非常巨大。这里我推荐使用 ConstraintLayout (约束布局,只有一个层级)替代 RelativeLayout 或者 weighted LinearLayout。
  • 减少多余的background
  • PrecomputedText(研究下),异步的textview。
    Litho (研究下)如我前面提到的 PrecomputedText 一样,把 measure 和 layout 都放到了后台线程,只留下了必须要在主线程完成的 draw,这大大降低了 UI 线程的负载。
    如果你没有计划完全迁移到 Litho,我建议可以优先使用 Litho 中的 RecyclerCollectionComponent 和 Sections 来优化自己的 RecyelerView 的性能。

h5优化

分为前端优化和本地优化
前端优化:看看ssr
QQ截图20190512234706

本地:

  • webview预创建。提前创建和初始化 WebView,以及实现 WebView 的复用,这块大约可以节省 100~200 毫秒。
  • 缓存。提前把网页需要的资源请求下来。

React Native 和 Weex 性能差。 JS 是解释性的动态语言,它的执行效率相比 AOT 编译后的 Java,性能依然会在几倍以上的差距。


极客时间总结
http://peiniwan.github.io/2024/04/8038d8caeb52.html
作者
六月的雨
发布于
2024年4月6日
许可协议