BitmapDrawable 构造函数中的"Resources"到底是什么?



由于不赞成使用无参数BitmapDrawable构造函数,我们必须为该构造函数提供资源id。

BitmapDrawable bitmapDrawable = new BitmapDrawable(res, bmap);

其中res一般为getResources()

为什么构造函数需要它?如果我们使用通用图像缓存,我们如何定义该值?

构造函数为什么需要它?

来自BitmapDrawable(Resources res, Bitmap bitmap):的文档

从位图创建可绘制对象,根据资源的显示指标设置初始目标密度。

因此,这是使用显示度量设置初始目标密度所必需的,并且DisplayMetrics将从作为参数提供给BitmapDrawableResources中提取。

如果使用通用图像缓存,我们如何定义该值?

对不起,我不能理解这个问题。你能换个说法吗?

如果我自己已经缩放了位图,为什么BitmapDrawable需要资源?

BitmapDrawable怎么知道你已经缩放了Bitmap?通常,如果您正在创建BitmapDrawable,则不应该自行对其进行缩放,这就是为什么API是这样设计的。

位图转换为Drawable时,避免缩放的唯一方法似乎是使用不推荐使用的构造函数?

虽然这听起来很糟糕,但您可以看到转换框架中的类是如何使用该构造函数的,例如ChangeBoundsCrossfade

我挖掘了一些源代码,在Bitmap类中找到了这段代码:

static public int scaleFromDensity(int size, int sdensity, int tdensity) {
    if (sdensity == DENSITY_NONE || tdensity == DENSITY_NONE || sdensity == tdensity) {
        return size;
    }
    // Scale by tdensity / sdensity, rounding up.
    return ((size * tdensity) + (sdensity >> 1)) / sdensity;
}

这在以下链中被调用:

* BitmapDrawable#constructor
* BitmapDrawable#updateLocalState()
* BitmapDrawable#computeBitmapSize()
* Bitmap#getScaledWidth()
* scaleFromDensity(getWidth(), mDensity, targetDensity)

如果您将Bitmap的密度明确设置为DENSITY_NONE,该怎么办?然后CCD_ 16检查将评估为CCD_ 17,并且将不执行缩放。

Bitmap bitmap = ...
bitmap.setDensity(Bitmap.DENSITY_NONE);

没有测试,只是根据来源做出假设。

在此构造函数中,需要getResources()"根据资源的显示度量设置初始目标密度"。我是这样理解的——你获取显示指标,其中包含关于大小、密度、字体缩放的信息,并将这些信息传递给构造函数。如果您在res/文件夹中有不同大小的图像——在适当的子文件夹中,如drawable-ldpidrawable-hdpi——您可能会得到不同的信息。

要在图像缓存中使用它,您需要向它传递一个Context,然后像这样调用:Context ctx; ctx.getResources();希望能有所帮助。

关于已弃用的构造函数和新构造函数

BitmapDrawable(Resources res) /* deprecated constructor */
BitmapDrawable(android.content.res.Resources, android.graphics.Bitmap) /* new constructor they introduced to replace above deprecated constructor */

不推荐使用的构造函数创建了一个空的drawable,而不处理密度。但是,新的构造函数从位图创建drawable,根据资源的显示度量设置初始目标密度。使用新的构造函数可以为您提供Bitmap(最终类)所能提供的所有功能。https://developer.android.com/reference/android/graphics/Bitmap.html#pubmethods

如果不通过构造函数传递位图变量,会发生什么从参数传递变量时,不需要在传递的位置创建新的位图变量。您创建了另一个变量,它只是引用位图的(静态引用)。由于位图是大尺寸文件,当您传递引用时,您节省了在ImageView中加载位图所需的大量空间和处理能力。所以它可以帮助你避免OutOfMemory Exception

例如,

public void passA(String); /* method signature*/
String s = "dfsfsdf";
passA(s); /* method calling */

另一面:

public void passA(String newVar) {
   /* newVar simply points (references) to the memory of "dfsfsdf". */
   /* passing references */ /* for Bitmap creating new copy is expensive 
    operations */
/*Note: Java does manipulate objects by reference, and all object variables are references */
}

他们传递Bitmap变量(android.graphics.Bitmap)的另一个想法是因为Bitmap是Parcelable(如果实现Parcelable)。Parcelable对象可以包含在Bundle中。捆绑包是IPCS(进程间通信)和通过各种Android组件进行通信的核心。

关于常规图像缓存您可以从位图中设置所有必要的密度和其他内容,位图通过新的构造函数传递了一个变量。然后,您可以在Least Recently Used (Lru)缓存中创建一个HashMap,在其中定义字符串key以指出配置的Bitmap variable。例如,LruCache。现在,在处理器的最近最少缓存中,您已经配置了位图。这样可以节省大量的处理能力。

https://developer.android.com/reference/android/util/LruCache.html

希望,我的回答能帮助你!

相关内容

最新更新