概述
最近遇到ImageView控件设置的图片延迟才显示的问题(虽然最终发现原因是图片是全透明的)。
顺势跟踪了一下给ImageView设置图片的源码。
以下分析都是基于Android8.0
setImageResource
源码中对该接口的注释:
/**
* Sets a drawable as the content of this ImageView.
* <p class="note">This does Bitmap reading and decoding on the UI
* thread, which can cause a latency hiccup. If that's a concern,
* consider using {@link #setImageDrawable(android.graphics.drawable.Drawable)} or
* {@link #setImageBitmap(android.graphics.Bitmap)} and
* {@link android.graphics.BitmapFactory} instead.</p>
*
* @param resId the resource identifier of the drawable
*
* @attr ref android.R.styleable#ImageView_src
*/
@android.view.RemotableViewMethod(asyncImpl="setImageResourceAsync")
public void setImageResource(@DrawableRes int resId) {
// The resource configuration may have changed, so we should always
// try to load the resource even if the resId hasn't changed.
.....
}
在UI线程中处理bitmap,这可能造成主线程的延迟(如导致Activity启动延迟等情况)。
可以考虑使用setImageDrawable(Drawable)或setImageBitmap(Bitmap)代替。
setImageDrawable
/**
* Sets a drawable as the content of this ImageView.
*
* @param drawable the Drawable to set, or {@code null} to clear the
* content
*/
public void setImageDrawable(@Nullable Drawable drawable) {
if (mDrawable != drawable) {
mResource = 0;
mUri = null;
final int oldWidth = mDrawableWidth;
final int oldHeight = mDrawableHeight;
updateDrawable(drawable);
if (oldWidth != mDrawableWidth || oldHeight != mDrawableHeight) {
requestLayout();
}
invalidate();
}
}
setImageDrawable(null)可以清除一个ImageView控件设置的图片。
setImageBitmap
/**
* Sets a Bitmap as the content of this ImageView.
*
* @param bm The bitmap to set
*/
@android.view.RemotableViewMethod
public void setImageBitmap(Bitmap bm) {
// Hacky fix to force setImageDrawable to do a full setImageDrawable
// instead of doing an object reference comparison
mDrawable = null;
if (mRecycleableBitmapDrawable == null) {
mRecycleableBitmapDrawable = new BitmapDrawable(mContext.getResources(), bm);
} else {
mRecycleableBitmapDrawable.setBitmap(bm);
}
setImageDrawable(mRecycleableBitmapDrawable);
}
setImageBitmap实际还是调用的setImageDrawable,但是强制setImageDrawble执行完整的setImageDrawable而不是做对象引用比较。setImageBitmap将Bitmap对象封装成Drawable对象,
setImageBitmap和setImageDrawable的区别
参考自赵雅智_setImageResource和setImageBitmap_柠檬不萌-CSDN博客_setimagebitmap
同样的布局文件,小分辨率手机:
- 使用setImageBitmap设置时,显示如下:
2. 使用setImageResource设置时,显示正常:
原因:
setImageResource(id)会根据设备分辨率进行图片大小缩放适配。
setImageBitmap(BitmapFactory.decodeResource(res, id))大小需要手动调。
如果提供了完整的各种分辨率下的图片,两种方法没有区别。
总结
综合来看,setImageDrawable是最省内存最高效的,如果担心图片过大或者图片过多影响内存和加载效率,可以自己解析图片然后通过调用setImageDrawable方法进行设置。
最后
以上就是贪玩棒棒糖为你收集整理的Android | setImageResource、setImageDrawable和setImageBitmap的区别的全部内容,希望文章能够帮你解决Android | setImageResource、setImageDrawable和setImageBitmap的区别所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复