Android开发:深入源码剖析图片加载过程,面试官再也不能为难我了!

作者:彭丑丑

前言

本文将从源码深入剖析 「图片加载」 的过程。

为方便大家理解,源码已作简化处理。


图片资源加载过程

首先我们看下加载图片资源的入口方法:BitmapFactory.decodeResource()

// BitmapFactory.decodeResource()

public static Bitmap decodeResource(Resources res, int id) {
    return decodeResource(res, id, null);
}

public static Bitmap decodeResource(Resources res, int id, Options opts) {
    // 步骤1:匹配资源 id,打开InputStream
    final TypedValue value = new TypedValue();
    InputStream is = res.openRawResource(id, value);

    // 步骤2:解码资源,返回 Bitmap
    return decodeResourceStream(res, value, is, null, opts);
}

所以,图片资源加载主要分为两步,具体如下图:

image


步骤1:匹配资源 ID

作用

从资源 id(一个 int 值)定位到具体某一个文件夹下的资源,即**「获得 InputStream和TypedValue(即带有文件夹对应的 densityDpi)」**。

源码解析

// 步骤说明
public static Bitmap decodeResource(Resources res, int id, Options opts) {
    // 步骤1:匹配资源 id,打开InputStream -> 关注1
    final TypedValue value = new TypedValue();
    InputStream is = res.openRawResource(id, value); 

    // 步骤2:解码资源,返回 Bitmap
    return decodeResourceStream(res, value, is, null, opts);
}

/**
  * 关注1:ResourcesImpl.openRawResource()
  */
InputStream openRawResource(@RawRes int id, TypedValue value) {
    // 匹配资源 -> 关注2
    getValue(id, value, true);

    // 打开输入流
    return mAssets.openNonAsset(value.assetCookie, value.string.toString(),
                    AssetManager.ACCESS_STREAMING);
}

/**
  * 关注2:getValue()
  */
void getValue(@AnyRes int id, TypedValue outValue, boolean resolveRefs) {

    // 查找资源Id & 相关信息存储在 outValue -> 关注3
    boolean found = mAssets.getResourceValue(id, 0, outValue, resolveRefs);

    ... 
}

/**
  * 关注3:AssetManager.getResourceValue()
  */
  boolean getResourceValue(@AnyRes int resId, int densityDpi, TypedValue outValue, boolean resolveRefs) {

   // 从Native文件中查找 -> 关注4
    final int cookie = nativeGetResourceValue(mObject, resId, (short) densityDpi, outValue, resolveRefs);

    if (cookie <= 0) {
        return false;
    }

    return true;
}

/**
  * 关注4:AssetManager.NativeGetResourceValue()
  */
s
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值