歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

【Google官方教程】第二課:在非UI線程處理Bitmap

譯者按: 在Google最新的文檔中,提供了一系列含金量相當高的教程。因為種種原因而鮮為人知,真是可惜!Ryan將會細心整理,將之翻譯成中文,希望對開發者有所幫助。

本系列是Google關於展示大Bitmap(位圖)的官方演示,可以有效的解決內存限制,更加有效的加載並顯示圖片,同時避免讓人頭疼的OOM(Out Of Memory)。

【Google官方教程】系列相關閱讀: http://www.linuxidc.com/search.aspx?where=nkey&keyword=14914

-------------------------------------------------------------------------------------

譯文:

在高效地加載Bitmap中,我們討論了BitmapFactory.decode*系列方法,如果源數據來自硬盤或者網絡(或者除內存之外的來源),是不應該在主UI線程執行的。這是因為讀取這樣的數據所需的加載時間是不確定的,它依賴於多種因素(從硬盤或網絡的讀取速度、圖片的大小、CPU的功率等等)。如果這些任務裡面任何一個阻塞了UI線程,系統會將你的應用標記為未響應,並且用戶可以選擇關閉應用(更多信息,請參閱Designing for Responsiveness)。

這節課將教會你使用AsyncTask在後台線程處理Bitmap並向你展示如何處理並發問題。

使用AsyncTask(異步任務)

AsyncTask類提供了一種簡單的方法,可以在後來線程處理一些事情,並將結果返回到UI線程。要使用它,需要創建一個繼承於它的子類,並且覆寫它提供的方法。這裡有一個使用AsyncTask和decodeSampledBitmapFromResource()加載大圖片到ImageView中的例子:

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

    public BitmapWorkerTask(ImageView imageView) {
        // Use a WeakReference to ensure the ImageView can be garbage collected
        imageViewReference = new WeakReference<ImageView>(imageView);
    }

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

    // Once complete, see if ImageView is still around and set bitmap.
    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (imageViewReference != null && bitmap != null) {
            final ImageView imageView = imageViewReference.get();
            if (imageView != null) {
                imageView.setImageBitmap(bitmap);
            }
        }
    }
}

ImageView的WeakReference(弱引用)可以確保AsyncTask不會阻止ImageView和它的任何引用被垃圾回收器回收。不能保證在異步任務完成後ImageView依然存在,因此你必須在onPostExecute()方法中檢查引用。ImageView可能已經不存在了,比如說,用戶在任務完成前退出了當前Activity或者應用配置發生了變化(橫屏)。

為了異步加載Bitmap,我們創建一個簡單的異步任務並且執行它:

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

Copyright © Linux教程網 All Rights Reserved