RecyclerView 性能优化 | 安卓 offer 收割基

阿里四面有三面都问了这个问题,在此作了整理,但愿能够帮助到你们,欢迎查漏补缺。java

数据处理和视图加载分离

咱们知道,从远端拉取数据确定是要放在异步的,在咱们拉取下来数据以后可能就匆匆把数据丢给了 VH 处理,其实,数据的处理逻辑咱们也应该放在异步处理,这样 Adapter 在 notify change 后,ViewHolder 就能够简单无压力地作数据与视图的绑定逻辑,好比:android

mTextView.setText(Html.fromHtml(data).toString());
复制代码

这里的 Html.fromHtml(data) 方法可能就是比较耗时的,存在多个 TextView 的话耗时会更为严重,这样便会引起掉帧、卡顿,而若是把这一步与网络异步线程放在一块儿,站在用户角度,最多就是网络刷新时间稍长一点。git

数据优化

分页拉取远端数据,对拉取下来的远端数据进行缓存,提高二次加载速度;对于新增或者删除数据经过 DiffUtil 来进行局部刷新数据,而不是一味地全局刷新数据。github

布局优化

减小过渡绘制

减小布局层级,能够考虑使用自定义 View 来减小层级,或者更合理地设置布局来减小层级,不推荐在 RecyclerView 中使用 ConstraintLayout,有不少开发者已经反映了使用它效果更差,相关连接有:Is ConstraintLayout that slow?constraintlayout 1.1.1 not work well in listview面试

减小 xml 文件 inflate 时间

这里的 xml 文件不只包括 layout 的 xml,还包括 drawable 的 xml,xml 文件 inflate 出 ItemView 是经过耗时的 IO 操做,尤为当 Item 的复用概率很低的状况下,随着 Type 的增多,这种 inflate 带来的损耗是至关大的,此时咱们能够用代码去生成布局,即 new View() 的方式,只要搞清楚 xml 中每一个节点的属性对应的 API 便可。缓存

减小 View 对象的建立

一个稍微复杂的 Item 会包含大量的 View,而大量的 View 的建立也会消耗大量时间,因此要尽量简化 ItemView;设计 ItemType 时,对多 ViewType 可以共用的部分尽可能设计成自定义 View,减小 View 的构造和嵌套。bash

其余

其余并不表明不重要,而是我不能把他们进行分类哈,其中可能某些操做会对你的 RecyclerView 有很大的优化。网络

  • 升级 RecycleView 版本到 25.1.0 及以上使用 Prefetch 功能,可参考 RecyclerView 数据预取异步

  • 若是 Item 高度是固定的话,可使用 RecyclerView.setHasFixedSize(true); 来避免 requestLayout 浪费资源;ide

  • 设置 RecyclerView.addOnScrollListener(listener); 来对滑动过程当中中止加载的操做。

  • 若是不要求动画,能够经过 ((SimpleItemAnimator) rv.getItemAnimator()).setSupportsChangeAnimations(false); 把默认动画关闭来提高效率。

  • TextView 使用 String.toUpperCase 来替代 android:textAllCaps="true"

  • TextView 使用 StaticLayout 或者 DynamicLayout 的自定义 View 来代替它。

  • 经过重写 RecyclerView.onViewRecycled(holder) 来回收资源。

  • 经过 RecycleView.setItemViewCacheSize(size); 来加大 RecyclerView 的缓存,用空间换时间来提升滚动的流畅性。

  • 若是多个 RecycledViewAdapter 是同样的,好比嵌套的 RecyclerView 中存在同样的 Adapter,能够经过设置 RecyclerView.setRecycledViewPool(pool); 来共用一个 RecycledViewPool

  • ItemView 设置监听器,不要对每一个 Item 都调用 addXxListener,应该你们公用一个 XxListener,根据 ID 来进行不一样的操做,优化了对象的频繁建立带来的资源消耗。

  • 经过 getExtraLayoutSpace 来增长 RecyclerView 预留的额外空间(显示范围以外,应该额外缓存的空间),以下所示:

    new LinearLayoutManager(this) {
        @Override
        protected int getExtraLayoutSpace(RecyclerView.State state) {
            return size;
        }
    };
    复制代码

结语

我正在打造一个帮助 Android 开发者们拿到更好 offer 的面试库————安卓 offer 收割基,欢迎 star,以为不错的能够持续关注,有兴趣的能够一块儿加入进来和我一同打造。

相关文章
相关标签/搜索