西西軟件園多重安全檢測下載網(wǎng)站、值得信賴的軟件下載站!
軟件
軟件
文章
搜索

首頁編程開發(fā)Android → Android開發(fā)實現(xiàn)圖片異步加載與緩存

Android開發(fā)實現(xiàn)圖片異步加載與緩存

相關(guān)軟件相關(guān)文章發(fā)表評論 來源:西西整理時間:2012/9/16 9:15:54字體大。A-A+

作者:佚名點擊:199次評論:9次標(biāo)簽: Android開發(fā)

  • 類型:編程工具大。13.8M語言:英文 評分:5.5
  • 標(biāo)簽:
立即下載

開發(fā)Android程序,一般情況下都會有兩個操作,圖片的異步加載與緩存,而圖片的異步加載大都是從網(wǎng)絡(luò)讀取圖片(還有生成本地圖片縮略圖等操作),為了減少網(wǎng)絡(luò)操作,加快圖片加載速度就需要對圖片進(jìn)行緩存,所以網(wǎng)上的好多圖片異步加載方法都是與圖片的緩存緊密關(guān)聯(lián)的。但也有可能用戶已經(jīng)有了緩存的相關(guān)類庫,這樣使用起來就會有點麻煩。

  最近一段處理跟圖片相關(guān)的問題,本來是自己寫的圖片加載,不過有些狀態(tài)的控制還是比較煩人的,比如ListView滾動時ImageView的重用,所以本著偷懶與充分利用現(xiàn)有資源的態(tài)度去網(wǎng)上搜羅圖片異步加載的代碼,最終在GreenDroid UI庫中找到一個,其中有個AsyncImageView的自定義View用于異步加載圖片,不過也像網(wǎng)上的大多數(shù)圖片異步加載方法一樣,是跟圖片的緩存關(guān)聯(lián)在一起的,不過只是很簡單的內(nèi)存緩存,無文件緩存。圖片的加載方法也如其他的一樣是寫死了的,這就限制了其使用范圍,只可通過InputStream來decode圖片,而像生成縮略圖或其他一些圖片處理的異步處理就無法用途。修改現(xiàn)有類庫總比自己從頭寫來的簡單,于是稍微修改了下AsyncImageView,使其可以自定義緩存與圖片加載方法,對于AsyncImageView只有一點點的修改,大都是別人源碼。

1. 核心類

  ImageLoader:圖片加載核心類,內(nèi)部使用線程池加載圖片

  ImageRequest:表示一個圖片加載的請求

  AsyncImageView:自定義的圖片異步加載View

  LoadMethod:自定義圖片加載方法的接口,可以通過實現(xiàn)此接口來自定義圖片的加載方法

  CacheCallback:緩存接口,可以通過實現(xiàn)此接口實現(xiàn)對緩存的讀寫

AsyncImageView.OnImageViewLoadListener:圖片加載狀態(tài)監(jiān)聽(開始,失敗,結(jié)束)

2。圖片加載方法

public void run() {

            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);

            final Handler h = mHandler;
            Bitmap bitmap = null;
            Throwable throwable = null;

            h.sendMessage(Message.obtain(h, ON_START));

            try {
                if (TextUtils.isEmpty(mUrl)) {
                    throw new Exception("The given URL cannot be null or empty");
                }

                // 如果自定義了加載方法,則用自定義的方法
                if (mLoadMethod != null) {
                    bitmap = mLoadMethod.load(mUrl);
                } else {

                    InputStream inputStream = null;

                    // Asset
                    if (mUrl.startsWith("file:///android_asset/")) {
                        inputStream = sAssetManager.open(mUrl.replaceFirst(
                                "file:///android_asset/", ""));
                    }
                    // File
                    else if (mUrl.startsWith("file:///") || mUrl.startsWith("/")) {
                        if (mUrl.startsWith("file:///"))
                            mUrl = mUrl.replaceFirst("file:///", "/");
                        inputStream = new FileInputStream(mUrl);
                    }
                    // NetWork
                    else {
                        // 在用URL類加載圖片時,發(fā)現(xiàn)有的機型上面通過URL類獲得的InputStream解析獲得的圖片總是null,故使用HttpClient
                        HttpGet httpRequest = new HttpGet(mUrl);
                        HttpClient httpclient = new DefaultHttpClient();
                        HttpParams httpParams = new BasicHttpParams();
                        HttpConnectionParams.setConnectionTimeout(httpParams, 5000);
                        HttpConnectionParams.setSoTimeout(httpParams, 5000);
                        httpRequest.setParams(httpParams);
                        HttpResponse response = (HttpResponse)httpclient.execute(httpRequest);
                        HttpEntity entity = response.getEntity();
                        BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(entity);
                        InputStream instream = bufHttpEntity.getContent();
                        BufferedInputStream bi = new BufferedInputStream(instream);
                        inputStream = bi;
                    }

                    // 雖然AsyncImageView中有設(shè)置BitmapFactory.Options的方法,但一般情況下都未知圖片的大小,也就無法計算相應(yīng)的inSampleSize,
                    // 也就無法設(shè)置相應(yīng)的BitmapFactory.Options,所以一般情況下還是根據(jù)自己的需要自定義LoadMethod為好
                    bitmap = BitmapFactory.decodeStream(inputStream, null,
                            (mOptions == null) ? sDefaultOptions : mOptions);
                    inputStream.close();
                }
                if (mBitmapProcessor != null && bitmap != null) {
                    final Bitmap processedBitmap = mBitmapProcessor.processImage(bitmap);
                    if (processedBitmap != null) {
                        bitmap.recycle();
                        bitmap = processedBitmap;
                    }
                }

            } catch (Exception e) {
                Log.e(LOG_TAG, "Error while fetching image", e);
                throwable = e;
            }

            if (bitmap == null) {
                if (throwable == null) {
                    throwable = new Exception("Skia image decoding failed");
                }
                h.sendMessage(Message.obtain(h, ON_FAIL, throwable));
            } else {
                h.sendMessage(Message.obtain(h, ON_END, bitmap));
                if (mCache != null) {
                    mCache.writeCache(TextUtils.isEmpty(mCacheKey) ? mUrl : mCacheKey, bitmap);
                }
            }
        }

  如果自定義了LoadMethod,會調(diào)用相應(yīng)的方法加載圖片,如果沒有自定義,會使用默認(rèn)的加載方法,可以加載本地圖片,Asset圖片與網(wǎng)絡(luò)圖片,GreenDroid的源碼中加載網(wǎng)絡(luò)圖片是用的URL的,但我們以前在加載網(wǎng)絡(luò)圖片時遇到一個問題,有的機型通過URL類獲得的ImputStream解析圖片總是返回null,所以就改為了HttpClient。

3。使用方法

通過AsyncImageView的setPath方法來加載圖片,setPath有3個重載方法:

public void setPath(String path)

public void setPath(String path, LoadMethod loadMethod)

public void setPath(String path, LoadMethod loadMethod, String cacheKey)

第一個參數(shù)指定要加載的圖片的路徑,第二個參數(shù)為自定義的圖片加載方法,若不指定則用默認(rèn)的。

至于加第三個參數(shù),是做緩存用的,一般要加載的圖片的路徑都是唯一的,所以一般用第一個參數(shù)來做為緩存的Key就行了,但也有特殊情況,比如讀取局域網(wǎng)中的圖片,一般都是自動獲取IP,所以根據(jù)圖片路徑做為緩存的Key可能是不合適的,所以就需要根據(jù)需要手動指定用來作為緩存的Key。

/**
     * 設(shè)置要加載的圖片的路徑, 可為網(wǎng)絡(luò)路徑, Asset文件路徑(file:///android_asset), 本地圖片路徑(file:///或/)
     *
     * @param path 要加載的圖片的路徑, 若為null則加載默認(rèn)圖片
     * @param loadMethod 自定義的圖片加載的方法, 可以null, 使用默認(rèn)的加載方法
     * @param cacheKey 緩存key
     */
    public void setPath(String path, LoadMethod loadMethod, String cacheKey) {

        // Check the url has changed
        if (mBitmap != null && path != null && path.equals(mUrl)) { // TODO mBitmap != null necessary?
            return;
        }

        stopLoading();
        mUrl = path;
        mCacheKey = cacheKey;
        mLoadMethod = loadMethod;

        // Setting the url to an empty string force the displayed image to the
        // default image
        if (TextUtils.isEmpty(mUrl)) {
            mBitmap = null;
            setDefaultImage();
        } else {
            if (!mPaused) {
                reload();
            } else {
                // We're paused: let's look in a synchronous and efficient cache
                // prior using the default image.
                mBitmap = readCache(); // TODO 可能會耗時間
                if (mBitmap != null) {
                    setImageBitmap(mBitmap);
                } else {
                    setDefaultImage();
                }
            }
        }
    }

public void reload(boolean force) {
        if (mRequest == null && mUrl != null) {

            // Prior downloading the image ... let's look in a cache !
            mBitmap = null;
            if (!force) {
                // This may take a long time.
                mBitmap = readCache();
            }

            if (mBitmap != null) {
                setImageBitmap(mBitmap);
                return;
            }

            setDefaultImage();
            mRequest = new ImageRequest(mUrl, this, mImageProcessor, mOptions, mCacheKey);
            mRequest.load(getContext(), mLoadMethod);
            if (ImageLoader.getInstance() != null && ImageLoader.getInstance().getCache() == null) {
                ImageLoader.getInstance().setCache(mCache);
            }
        }

  readCache()用于讀取緩存,代碼如下:

    private Bitmap readCache() {
        if (mCache != null)
            return mCache.readCache(TextUtils.isEmpty(mCacheKey) ? mUrl : mCacheKey);
        return null;
    }

  其中的mCache由用戶能過setCacheCallback(CacheCallback callback)設(shè)置用戶自定義的緩存方法,由此將圖片的加載與緩存分離開,使用戶可以使用現(xiàn)有的緩存實現(xiàn)。如要用戶指定了緩存Key就使用用戶指定的Key,否則就用圖片的路徑作Key。

4.AsyncImageView中的其他重要方法

reload([boolean force]):重新加載

stopLoading():停止加載,如果當(dāng)前正在加載則沒有效果,如果加載任務(wù)在加載線程池隊列中則取消。

setDefaultImage...()類方法:設(shè)置默認(rèn)圖片。

setPause(boolean pause):是否加載圖處

    app制作
    (8)app制作
    一款好的不僅需要有創(chuàng)意的開發(fā)人員還要有一款合適的制作軟件,有時候一款好用的制作軟件可以讓開發(fā)人員節(jié)省很多不必要的時間。另外對于一些不懂編程的人員來說制作一款也不是沒有可能的,有些功能強大的制作軟件可以讓完全不懂編程的人也能制作出一些精美的來,比如一些公司的產(chǎn)品展示這類不需要有自己特色的就可以通過制作軟件輕松做出來。這里西西給大家收整理了一些好用的制作軟件下載,希望對大家有所幫助。...更多>>
    • appBookv1.0 官方版

      07-04 / 132.6M

      推薦理由:appBook 一次編輯多平臺發(fā)布 輕松擁有自己的app,appBook是全球首家運行在PC和Mac的移動平臺應(yīng)用編輯制作軟
    • 安卓平臺反編譯神器(Apktool)v6.0.

      02-19 / 13.0M

      推薦理由:Apktool,一款安卓移動平臺上的反編譯利器!Apktool現(xiàn)已完美兼容Android5.0L,使用它可以修改軟件應(yīng)用名稱,
    • myeclipse 10.0

      11-03 / 886M

      推薦理由:MyEclipse 10使用最高級的桌面和Web開發(fā)技術(shù),包括 HTML5 和 Java EE 6,支持 JPA 2.0、JSF 2.0 、Eclipsel
    • 移動應(yīng)用開發(fā)工具(AppCan IDE)V3.1

      11-14 / 421.8M

      推薦理由:AppCan應(yīng)用使用HTML5、CSS3和JavaScript語言編寫,通過AppCan IDE提供的本地打包工具或在線編譯系統(tǒng)生成可在
    • appMaker中文版v1.0 官方免費版

      03-06 / 315.8M

      推薦理由:appMaker中文版是一款免費的app制作軟件,可以制作各種展示類的app。如:移動互動電子書、電子雜志、地產(chǎn)樓
    • 安卓開發(fā)(Google Android SDK)r24.

      05-15 / 85.8M

      推薦理由:Google Android SDKAndroid是Google自己研發(fā)的手機平臺操作系統(tǒng),該平臺基于開源軟件Linux,由操作系統(tǒng)、中
    eclipse
    (119)eclipse
    是對的擴展,利用它我們可以在數(shù)據(jù)庫和的開發(fā)發(fā)布以及應(yīng)用程序服務(wù)器的整合方面極大的提高工作效率。它是功能豐富的集成開發(fā)環(huán)境,包括了完備的編碼調(diào)試測試和發(fā)布功能,完整支持,,,,,,,。分類在結(jié)構(gòu)上,的特征可以被分為類模型開發(fā)工具開發(fā)工具應(yīng)用程序服務(wù)器的連接器項目部署服務(wù)數(shù)據(jù)庫服務(wù)整合幫助...更多>>
    • android sdk 64位22.3 官方最新版

      11-07 / 480.4M

      推薦理由:完整的android開發(fā)工具,基于Android 4.4的android sdk 22.3 官方最新版,各版本都是相互匹配的,不會出現(xiàn)安
    • Eclipse 4.3.X 漢化包官方版

      11-14 / 4.3M

      推薦理由:Eclipse4.3漢化包是Eclipse4.3.x的一個中文漢化包,有了中文語言環(huán)境,搞起開發(fā)來也順手。 Eclipse4.3漢化
    • ADT Plugin for Eclipse(Android開

      02-24 / 13.8M

      推薦理由:這是一個Eclipse插件,作用是關(guān)聯(lián)Android SDK,使你的Eclipse能夠新建Android工程,安裝方法如下:打開Ecli
    • Tomcat Eclipse集成插件

      03-15 / 333KB

      推薦理由:Tomcat Eclipse集成插件,在Eclipse里控制Tomcat啟動、停止。你懂的 使用方法:放入 eclipse 的 plugins 目
    • Eclipse C語言開發(fā)工具(Eclipse ID

      04-10 / 85.6M

      推薦理由:一個C / C + +的IDE與Mylyn集成開發(fā)。Feature Listorg.eclipse.cdt 7.0.0org.eclipse.cdt.debug.ui.memory
    • Eclipse 3.6.2 漢化包官方簡體中文

      04-10 / 3.8M

      推薦理由:漢化包安裝有兩種方法:第一種最簡單,直接拷貝將對應(yīng)目錄下的文件拷貝到和Eclipse對應(yīng)目錄下即可。(將解壓
    eclipse中文版下載
    (27)eclipse中文版下載
    是一個開放源代碼的基于的可擴展開發(fā)平臺。還包括插件開發(fā)環(huán)境,,這個組件主要針對希望擴展的軟件開發(fā)人員,因為它允許他們構(gòu)建與環(huán)境無縫集成的工具。它只是一個框架和一組服務(wù),用于通過插件組件構(gòu)建開發(fā)環(huán)境。幸運的是,附帶了一個標(biāo)準(zhǔn)的插件集,包括開發(fā)工具,。漢化方法把語言包中的,文件夾直接覆蓋到安裝目錄中,或者把漢化包放到目錄下面。常用快捷鍵.快速修復(fù).刪除當(dāng)前行.復(fù)制當(dāng)前行到下一行.或者說是空格由于后者與輸入法...更多>>
    JAVA軟件
    (60)JAVA軟件
    軟件下載,編程軟件下載專題有多款適合編程愛好者學(xué)習(xí)使用的軟件,我們提供了適用于開發(fā)者使用的相關(guān)軟件的各個版本跟新的下載地址,以方便各位愛好者使用學(xué)習(xí)。如果您有什么好的編程軟件可以向我們提供分享下載,如果下載的軟件有什么問題也可以向我們提供建議,祝程序員們學(xué)習(xí)愉快軟件開發(fā)其實可以不用其他軟件的。只需要安裝了工具包即可,這個是必須的。并且一定要配置好系統(tǒng)的環(huán)境變量。這個可以到網(wǎng)上去查,網(wǎng)上很多。然后進(jìn)...更多>>

    相關(guān)評論

    閱讀本文后您有什么感想? 已有人給出評價!

    • 8 喜歡喜歡
    • 3 頂
    • 1 難過難過
    • 5 囧
    • 3 圍觀圍觀
    • 2 無聊無聊

    熱門評論

    最新評論

    發(fā)表評論 查看所有評論(9)

    昵稱:
    表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
    字?jǐn)?shù): 0/500 (您的評論需要經(jīng)過審核才能顯示)