分享Android开发中常见的代码优化方案

前言

首先要做相关优化,就得先要大致清晰影响性能的相关因素,这样可以做针对性调优会比较有条理。

比较常见的性能调优因素有:

  • 内存:Java 一般通过 JVM 对内存进行分配管理,主要是用 JVM 中堆内存来存储 Java 创建的对象。系统堆内存的读写速度非常快,所以基本不存在读写性能瓶颈。但由于内存成本要比磁盘高,相比磁盘,内存的存储空间又非常有限。所以当内存空间被占满,对象无法回收时,就会导致内存溢出、内存泄露等问题。
  • 异常:抛出异常需要构建异常栈,对异常进行捕获和处理,这个过程非常消耗系统性能。
  • 网络:对于传输数据比较大,或者是并发量比较大的系统,网络就很容易成为性能瓶颈。
  • CPU: 复杂的计算,会长时间,频繁地占用cpu执行资源;例如:代码递归调用,JVM频繁GC以及多线程情况下切换资源都会导致CPU资源繁忙。

对以上这些因素可以在代码中做相关优化处理。

延迟加载(懒加载)优化

了解预加载

  • ViewPager控件有预加载机制,即默认情况下当前页面左右相邻页面会被加载,以便用户滑动切换到相邻界面时,更加顺畅的显示出来
  • 通过ViewPager的setOffscreenPageLimit(int limit)可设置预加载页面数量

介绍延迟加载

等页面UI展示给用户时,再加载该页面数据(从网络、数据库等),而不是依靠ViewPager预加载机制提前加载部分,甚至更多页面数据。可提高所属Activity的初始化速度,另一方面也可以为用户节省流量.而这种延迟加载方案已经被诸多APP所采用。

相关概括

  • 没有打开页面,就不预加载数据,当页面可见时,才加载所需数据。
  • 换句话说延迟加载就是可见时才去请求数据。
  • 实际应用开发中有哪些延迟加载案例:
    • ViewPager+Fragment 搭配使用延迟加载
    • H5网页使用延迟加载

ViewPager与Fragment延迟加载的场景

  • ViewPager中setOffscreenPageLimit(int limit)部分源码
//默认的缓存页面数量(常量)
private static final int DEFAULT_OFFSCREEN_PAGES = 1;

//缓存页面数量(变量)
private int mOffscreenPageLimit = DEFAULT_OFFSCREEN_PAGES;

public void setOffscreenPageLimit(int limit) {
    //当我们手动设置的limit数小于默认值1时,limit值会自动被赋值为默认值1(即DEFAULT_OFFSCREEN_PAGES)
    if (limit < DEFAULT_OFFSCREEN_PAGES) {
        Log.w(TAG, "Requested offscreen page limit " + limit + " too small; defaulting to "+ DEFAULT_OFFSCREEN_PAGES);
        limit = DEFAULT_OFFSCREEN_PAGES;
    }

    if (limit != mOffscreenPageLimit) {
        //经过前面的拦截判断后,将limit的值设置给mOffscreenPageLimit,用于
        mOffscreenPageLimit = limit;
        populate();
    }
}

  • 思路分析:Fragment中setUserVisibleHint(),此方法会在onCreateView()之前执行,当viewPager中fragment改变可见状态时也会调用,当fragment 从可见到不见,或者从不可见切换到可见,都会调用此方法,使用getUserVisibleHint() 可返回fragment是否可见状态。在onActivityCreated()及setUserVisibleHint()方法中都调一次lazyLoad() 方法。
public abstract class BaseMVPLazyFragment<T extends IBasePresenter> extends BaseMVPFragment<T> {
    /**
    * Fragment的View加载完毕的标记
    */
    protected boolean isViewInitiated;
    /**
    * Fragment对用户可见的标记
    */
    protected boolean isVisibleToUser;
    /**
    * 是否懒加载
    */
    protected boolean isDataInitiated;
    
    ...

    /**
    * 第一步,改变isViewInitiated标记
    * 当onViewCreated()方法执行时,表明View已经加载完毕,此时改变isViewInitiated标记为true,并调用lazyLoad()方法
    */
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        isViewInitiated = true;
        //只有Fragment onCreateView好了,
        //另外这里调用一次lazyLoad()
        prepareFetchData();
        //lazyLoad();
    }

    /**
    * 第二步
    * 此方法会在onCreateView()之前执行
    * 当viewPager中fragment改变可见状态时也会调用
    * 当fragment 从可见到不见,或者从不可见切换到可见,都会调用此方法
    */
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        this.isVisibleToUser = isVisibleToUser;
        prepareFetchData();
    }

    /**
    * 第四步:定义抽象方法fetchData(),具体加载数据的工作,交给子类去完成
    */
    public abstract void fetchData();

    /**
    * 第三步:在lazyLoad()方法中进行双重标记判断,通过后即可进行数据加载
    * 第一种方法
    * 调用懒加载,getUserVisibleHint()会返回是否可见状态
    * 这是fragment实现懒加载的关键,只有fragment 可见才会调用onLazyLoad() 加载数据
    */
    private void lazyLoad() {
        if (getUserVisibleHint() && isViewInitiated && !isDataInitiated) {
            fetchData();
            isDataInitiated = true;
        }
    }

    /**
    * 第二种方法
    * 调用懒加载
    */
    public void prepareFetchData() {
        prepareFetchData(false);
    }

    /**
    * 第三步:在lazyLoad()方法中进行双重标记判断,通过后即可进行数据加载
    */
    public void prepareFetchData(boolean forceUpdate) {
        if (isVisibleToUser && isViewInitiated && (!isDataInitiated || forceUpdate)) {
            fetchData();
            isDataInitiated = true;
        }
    }
}

多线程优化: 建议使用线程池

用线程池的好处

可重用线程池中的线程,避免频繁地创建和销毁线程带来的性能消耗;有效控制线程的最大并发数量,防止线程过大导致抢占资源造成阻塞;可对线程进行有效管理

  • RxJava,RxAndroid,底层对线程池的封装管理非常值得参考。

如果你看到了这里,觉得文章写得不错就给个赞呗?
更多Android进阶指南 可以扫码 解锁更多Android进阶资料


在这里插入图片描述
敲代码不易,关注一下吧。ღ( ´・ᴗ・` )

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值