我是靠谱客的博主 贪玩棒棒糖,最近开发中收集的这篇文章主要介绍Android | setImageResource、setImageDrawable和setImageBitmap的区别,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

最近遇到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

同样的布局文件,小分辨率手机:

  1. 使用setImageBitmap设置时,显示如下:

  2. 使用setImageResource设置时,显示正常:

原因:

setImageResource(id)会根据设备分辨率进行图片大小缩放适配。

setImageBitmap(BitmapFactory.decodeResource(res, id))大小需要手动调。

如果提供了完整的各种分辨率下的图片,两种方法没有区别。

总结

综合来看,setImageDrawable是最省内存最高效的,如果担心图片过大或者图片过多影响内存和加载效率,可以自己解析图片然后通过调用setImageDrawable方法进行设置。

最后

以上就是贪玩棒棒糖为你收集整理的Android | setImageResource、setImageDrawable和setImageBitmap的区别的全部内容,希望文章能够帮你解决Android | setImageResource、setImageDrawable和setImageBitmap的区别所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(58)

评论列表共有 0 条评论

立即
投稿
返回
顶部