Bitmap加載

1.加載大圖

bitmap圖片內(nèi)存消耗較大,容易出現(xiàn)OOM
bitmap configuration 使用ARGB_8888(默認(rèn))

  • ALPHA_8(一個像素消耗1個字節(jié))
  • RGB_565(一個像素消耗2個字節(jié))
  • ARGB_4444(@Deprecated,一個像素消耗2個字節(jié))
  • ARGB_8888(一個像素消耗4個字節(jié))

加載一張2592x1936 像素的分辨率的照片內(nèi)存消耗高達(dá) 19MB (259219364 bytes),

1.1獲取圖片尺寸信息

BitmapFactory.Options options = new BitmapFactory.Options();
//inJustDecodeBounds設(shè)置為true并不會真的加載圖片
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;

1.2計算采樣率inSampleSize

public static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        final int halfHeight = height / 2;
        final int halfWidth = width / 2;
        while ((halfHeight / inSampleSize) >= reqHeight
                && (halfWidth / inSampleSize) >= reqWidth) {
            inSampleSize *= 2;
        }
    }
    return inSampleSize;
}

1.3加載圖片

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
        int reqWidth, int reqHeight) {

    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}

mImageView.setImageBitmap(
    decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));
    

2.子線程加載圖片

2.1使用AsyncTask

在磁盤或網(wǎng)絡(luò)加載圖片比較耗時應(yīng)放入子線程進(jìn)行處理避免阻塞UI線程

class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
    private final WeakReference<ImageView> imageViewReference;
    private int data = 0;

    public BitmapWorkerTask(ImageView imageView) {
        imageViewReference = new WeakReference<ImageView>(imageView);
    }

    @Override
    protected Bitmap doInBackground(Integer... params) {
        data = params[0];
        return decodeSampledBitmapFromResource(getResources(), data, 100, 100));
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (imageViewReference != null && bitmap != null) {
            final ImageView imageView = imageViewReference.get();
            if (imageView != null) {
                imageView.setImageBitmap(bitmap);
            }
        }
    }
}



public void loadBitmap(int resId, ImageView imageView) {
    BitmapWorkerTask task = new BitmapWorkerTask(imageView);
    task.execute(resId);
}

2.2處理并發(fā)(例如 ListView, RecyclerView and GridView)

class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
    private final WeakReference<ImageView> imageViewReference;
    private int data = 0;

    public BitmapWorkerTask(ImageView imageView) {
        imageViewReference = new WeakReference<ImageView>(imageView);
    }

    @Override
    protected Bitmap doInBackground(Integer... params) {
        data = params[0];
        return decodeSampledBitmapFromResource(getResources(), data, 100, 100));
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (isCancelled()) {
            bitmap = null;
        }

        if (imageViewReference != null && bitmap != null) {
            final ImageView imageView = imageViewReference.get();
            final BitmapWorkerTask bitmapWorkerTask =
                    getBitmapWorkerTask(imageView);
            if (this == bitmapWorkerTask && imageView != null) {
                imageView.setImageBitmap(bitmap);
            }
        }
    }
}


private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
   if (imageView != null) {
       final Drawable drawable = imageView.getDrawable();
       if (drawable instanceof AsyncDrawable) {
           final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
           return asyncDrawable.getBitmapWorkerTask();
       }
    }
    return null;
}
static class AsyncDrawable extends BitmapDrawable {
    private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;

    public AsyncDrawable(Resources res, Bitmap bitmap,
            BitmapWorkerTask bitmapWorkerTask) {
        super(res, bitmap);
        bitmapWorkerTaskReference =
            new WeakReference<BitmapWorkerTask>(bitmapWorkerTask);
    }

    public BitmapWorkerTask getBitmapWorkerTask() {
        return bitmapWorkerTaskReference.get();
    }
}



public static boolean cancelPotentialWork(int data, ImageView imageView) {
    final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);

    if (bitmapWorkerTask != null) {
        final int bitmapData = bitmapWorkerTask.data;

        if (bitmapData == 0 || bitmapData != data) {

            bitmapWorkerTask.cancel(true);
        } else {

            return false;
        }
    }

    return true;
}
public void loadBitmap(int resId, ImageView imageView) {
    if (cancelPotentialWork(resId, imageView)) {
        final BitmapWorkerTask task = new BitmapWorkerTask(imageView);
        final AsyncDrawable asyncDrawable =
                new AsyncDrawable(getResources(), mPlaceHolderBitmap, task);
        imageView.setImageDrawable(asyncDrawable);
        task.execute(resId);
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末癞谒,一起剝皮案震驚了整個濱河市懂盐,隨后出現(xiàn)的幾起案子扒磁,更是在濱河造成了極大的恐慌登馒,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,627評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件朗和,死亡現(xiàn)場離奇詭異错沽,居然都是意外死亡,警方通過查閱死者的電腦和手機眶拉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來憔儿,“玉大人忆植,你說我怎么就攤上這事≮司剩” “怎么了朝刊?”我有些...
    開封第一講書人閱讀 169,346評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蜈缤。 經(jīng)常有香客問我拾氓,道長,這世上最難降的妖魔是什么底哥? 我笑而不...
    開封第一講書人閱讀 60,097評論 1 300
  • 正文 為了忘掉前任咙鞍,我火速辦了婚禮,結(jié)果婚禮上趾徽,老公的妹妹穿的比我還像新娘续滋。我一直安慰自己,他們只是感情好孵奶,可當(dāng)我...
    茶點故事閱讀 69,100評論 6 398
  • 文/花漫 我一把揭開白布疲酌。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪朗恳。 梳的紋絲不亂的頭發(fā)上湿颅,一...
    開封第一講書人閱讀 52,696評論 1 312
  • 那天,我揣著相機與錄音粥诫,去河邊找鬼肖爵。 笑死,一個胖子當(dāng)著我的面吹牛臀脏,可吹牛的內(nèi)容都是我干的劝堪。 我是一名探鬼主播,決...
    沈念sama閱讀 41,165評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼揉稚,長吁一口氣:“原來是場噩夢啊……” “哼秒啦!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起搀玖,我...
    開封第一講書人閱讀 40,108評論 0 277
  • 序言:老撾萬榮一對情侶失蹤余境,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后灌诅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體芳来,經(jīng)...
    沈念sama閱讀 46,646評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,709評論 3 342
  • 正文 我和宋清朗相戀三年猜拾,在試婚紗的時候發(fā)現(xiàn)自己被綠了即舌。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,861評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡挎袜,死狀恐怖顽聂,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情盯仪,我是刑警寧澤紊搪,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站全景,受9級特大地震影響耀石,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜爸黄,卻給世界環(huán)境...
    茶點故事閱讀 42,196評論 3 336
  • 文/蒙蒙 一滞伟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧馆纳,春花似錦诗良、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春径荔,著一層夾襖步出監(jiān)牢的瞬間督禽,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評論 1 274
  • 我被黑心中介騙來泰國打工总处, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留狈惫,地道東北人。 一個月前我還...
    沈念sama閱讀 49,287評論 3 379
  • 正文 我出身青樓鹦马,卻偏偏與公主長得像胧谈,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子荸频,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,860評論 2 361

推薦閱讀更多精彩內(nèi)容

  • Bitmap加載和Cache BitmapOptions decodeFile decodeStream deco...
    jiaming_閱讀 322評論 0 1
  • 在Android開發(fā)中經(jīng)常會遇到關(guān)于圖片加載旭从、緩存的問題稳强,經(jīng)常會遇到內(nèi)存溢出OOM,Android對單個應(yīng)用內(nèi)存加...
    西鳳梨閱讀 265評論 0 1
  • 這兩天看了一下官方關(guān)于圖片加載的東西和悦,記錄一下 大圖加載 有時候圖片加載沒必要加載原圖那么大的解析度退疫,就像系統(tǒng)相冊...
    lxacoder閱讀 343評論 0 1
  • 1.密度概念density 1 1.5 2 2.5densityDpi 160 320 4802.內(nèi)存大小占用內(nèi)存...
    瓊花落盡lxn閱讀 494評論 0 0
  • 下雨的時候 下雨的時候 天灰蒙蒙的 仿佛蓋上了一層茅草 心也灰蒙蒙 就像扻壓了一塊堅石 終揮之不去 空氣添滿水...
    渺渺量心閱讀 94評論 1 2