主页

2020.05.02 - 2020.05.04 深圳旅行日志

前言

很久之前便承诺了深圳的朋友要前去相见,奈何 19 年俗事烦身,这里先说一声抱歉。

这次趁着五一的假期落实心中所愿,记录一下旅程过程所见所思所想,方便日后翻阅回忆。

日程规划

  • 05.02 Day1
    • 华强北
    • 朋友相会
  • 05.03 Day2
    • 梅沙
  • 05.04 Day3
    • 南山建筑群
    • 归程

阅读更多

Android 源码 —— Bitmap 位图内存的演进流程

前言

Android 中的 Bitmap 像素内存演进流程如下, 摘录自 Google 文档 - 管理位图内存

版本 内存分布
~ Android 2.3.3(API 10) 1. 位图的后备像素数据存储在 Native 堆中。Native 内存中的像素数据并不以可预测的方式释放,可能会导致应用短暂超出其内存限制并崩溃。
2. Android 2.2(API 8) 无并发垃圾回收功能, 当发生垃圾回收时,应用的线程会停止。这会导致延迟,从而降低性能。
3. Android 2.3 添加了并发垃圾回收功能,这意味着系统不再引用位图后,很快就会回收内存
3.0(API 11)~ 7.1(API 25) 像素数据会与关联的位图一起存储在 Dalvik/ART 堆上。
8.0(API 26)~ 位图像素数据存储在 Native 堆中。配合 NativeAllocationRegistry 进行垃圾回收

这里有一个疑问, 为什么 Android 2.3.3 中 Native 的内存释放不可预测, 在 Java 对象的 finalize 被调用时直接释放的方案有何不妥? Android 8.0 的 NativeAllocationRegistry 的引入是为了解决什么问题?

这里就系统的学习一下 NativeAllocationRegistry 的技术, 然后看看他解决了 Android2.3.3 的哪些问题

阅读更多

Facebook —— Fresco 一次加载流程

前言

之前一直使用的是 Glide 图片加载框架, 最近接触了 Fresco 这款出自 Facebook 的图片加载框架, 为了方便后期对其进行封装与拓展, 这里分析记录一下它的一次简单的加载流程

关于 Fresco 的简单使用可以参考 Fresco 使用文档, 与 Glide 不同, 它主要是通过 DraweeView 对上层提供便捷性的服务, 文章主体分为如下几个部分

  • Fresco 初始化
  • SimpleDraweeView 的创建
  • 数据的加载

阅读更多

Jetpack —— Navigation 导航组件

前言

最早接触这个组件是在 18 年 Google IO 大会上, 当时看到他们展示了可视化的导航图, 感觉挺有意思, 不过并没有弄明白它到底有何作用

直到最近接触到的新项目中使用了这个组件之后才明白它的妙用, 为了更好的使用和拓展 Navigation 的功能, 这里笔者分析一下它的实现原理

关于 Navigation 的用法说明, 可以参考 Android Developer 文档, Google 还提供一个学习的 sample

阅读更多

《人类简史》笔录

前言

春节假期漫长, 而且肺炎当头无法外出, 武汉加油, 中国加油, 希望快些好起来

这段时间在享受天伦之乐的同时花了些时间将号称 互联网圣经的«人类简史» 通读了一遍, 这里做一下笔录方便日后的回顾

阅读更多

Android NDK —— GIFLIB 优化 Glide GIF 的加载

前言

我们知道 Glide 的图片框架是可以直接加载 GIF 图的, 笔者在监控项目内存使用的过程中, 发现 Gif 图过大时其内存消耗比较严重, 动画播放时伴随着稍许卡顿

这里我们系统的探究一下 Glide 的 GIF 加载原理和优化措施, 主要内容如下

  • Glide 的 Gif 播放原理
  • Glide 加载 GIF 卡顿探究
  • Gif 加载的优化

阅读更多

Android 系统架构 —— Choreographer 的工作机制

前言

在 ViewRootImpl 的创建过程中, 我们看到了它会通过 Choreographer.getInstance 获取到 Choreographer 对象

public final class ViewRootImpl implements ViewParent,
        View.AttachInfo.Callbacks, ThreadedRenderer.DrawCallbacks {
    ......
    
    Choreographer mChoreographer;
     
    public ViewRootImpl(Context context, Display display) {
        ......
        mContext = context;
        ......
        // 获取渲染编舞者实例对象
        mChoreographer = Choreographer.getInstance();
    }

}

这里我们就深入的了解一下 Choreographer 的工作机制, 主要内容如下

  • Choreographer 的创建
  • VSYNC 信号的分发

接下来先看看它的创建流程

阅读更多