getDrawable()的效率:是框架缓存的Drawable吗?

时间:2014-05-06 20:40:51

标签: android performance android-drawable

每次点击时我都需要更改切换按钮的图像。

这样做有效吗?

public void onClickToggleButton(View v) {
    if(_on) {
        _on=false;
        myImageView.setImageDrawable(getResources().getDrawable(R.drawable.btn_off));
    } else {
        _on=true;
        myImageView.setImageDrawable(getResources().getDrawable(R.drawable.btn_on));
    }
}

或者是否意味着每次都会从PNG文件中解码Drawable

在这种情况下,只调用getDrawable()两次(在onCreate()中)并保留我自己对2 Drawable的引用会更好。

2 个答案:

答案 0 :(得分:0)

如果每次使用此方法时调用是否有效,则不响应您的问题。 但正如@ n​​jzk2所说,您可以在切换按钮上使用 State Selector

我向你复制一个工作的例子(我正在使用)。只需更改您的drawables可绘制的名称。

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:drawable="@drawable/toggle_on" android:state_checked="true" />
  <item android:drawable="@drawable/toggle_off" android:state_checked="false" />
</selector>

在您定义toogle按钮的xml上,将背景设置为:

android:background="@drawable/toogle_selector"

其中“toogle_selector”是我之前复制过的文件的名称。

有了这个,你可以忘记每次加载drawable的效率。

希望这有帮助。

答案 1 :(得分:0)

从Android API 28源代码开始,当您调用Resources#getDrawable时,将调用ResourceImpl#loadDrawable,该代码段的开头是这样:

// If the drawable's XML lives in our current density qualifier,
// it's okay to use a scaled version from the cache. Otherwise, we
// need to actually load the drawable from XML.
final boolean useCache = density == 0 || value.density == mMetrics.densityDpi;

ResourceImpl类中还有一个由Android Zygote进程操纵的字段,称为mIsPreloading。如果useCache为true,并且ResourcesImpl没有预加载,则使用drawable的缓存版本。关于缓存ColorDrawables和主题Drawables,还有一些其他逻辑。

如果您像我一样,并且需要Drawable的深层副本,并且这种缓存行为正在妨碍您,请查看以下相关答案: Deep copy of a Drawable