天天看點

ImageLoader的基本使用ImageLoader的基本使用

ImageLoader的基本使用

ImageLoader是一款強大的圖檔加載緩存庫,功能非常強大,算是幾款圖檔加載開源庫中相對比較成熟和穩定的.

GitHub位址:Android-Universal-Image-Loader

下面就用一個小demo來示範一下這款功能強大的開源庫的使用,首先看一下效果:

有網的時候從伺服器加載資料,無網的時候讀取本地緩存顯示,如下:

ImageLoader的基本使用ImageLoader的基本使用

要實作如上的效果主要有以下幾個步驟:

  1. 配置

    Application

    ,初始化imageloader的配置
  2. 設定全局配置

    DisplayImageOptions

  3. 擷取圖檔URl,調用

    ImageLoader.getInstance().displayImage(url, ImageView, UILApplication.options);

    來顯示圖檔
  4. 儲存圖檔

    url

    到本地,無網的時候讀取,即可與有網情況下一樣顯示圖檔

Application

的配置

直接上代碼,解釋都在注釋當中:(全局的Options也定義在此類中)

import android.annotation.TargetApi;
import android.app.Application;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.StrictMode;

import com.brioal.imageloadertest.R;
import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
import com.nostra13.universalimageloader.core.display.RoundedBitmapDisplayer;

public class UILApplication extends Application {
    @TargetApi(Build.VERSION_CODES.GINGERBREAD)
    @SuppressWarnings("unused")
    @Override
    public void onCreate() {
        if (Constants.Config.DEVELOPER_MODE && Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectAll().penaltyDialog().build());
            StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().penaltyDeath().build());
        }
        super.onCreate();
        initImageLoader(getApplicationContext());
    }

    public static DisplayImageOptions options  = new DisplayImageOptions.Builder()
            .showImageOnLoading(R.mipmap.ic_launcher) //設定圖檔在下載下傳期間顯示的圖檔
            .showImageForEmptyUri(R.mipmap.ic_launcher)//設定圖檔Uri為空或是錯誤的時候顯示的圖檔
            .showImageOnFail(R.mipmap.ic_launcher)  //設定圖檔加載/解碼過程中錯誤時候顯示的圖檔
            .cacheInMemory(true)//設定下載下傳的圖檔是否緩存在記憶體中
            .cacheOnDisc(true)//設定下載下傳的圖檔是否緩存在SD卡中
            .considerExifParams(true)  //是否考慮JPEG圖像EXIF參數(旋轉,翻轉)
            .imageScaleType(ImageScaleType.EXACTLY_STRETCHED)//設定圖檔以如何的編碼方式顯示
            .bitmapConfig(Bitmap.Config.RGB_565)//設定圖檔的解碼類型//
            .resetViewBeforeLoading(true)//設定圖檔在下載下傳前是否重置,複位
            .displayer(new RoundedBitmapDisplayer())//是否設定為圓角,弧度為多少
            .displayer(new FadeInBitmapDisplayer())//是否圖檔加載好後漸入的動畫時間
            .build();//建構完成

    public static void initImageLoader(Context context) {
        ImageLoaderConfiguration.Builder config = new ImageLoaderConfiguration.Builder(context);
        config.threadPriority(Thread.NORM_PRIORITY - ); // 設定線程數量,Thread.NORM_PRIORITY - 2能保證讀取圖檔最大性能并且不影響主線程性能
        config.denyCacheImageMultipleSizesInMemory();
        config.diskCacheFileNameGenerator(new Md5FileNameGenerator()); // 設定磁盤儲存緩存的加密方式
        config.diskCacheSize( *  * ); // 設定磁盤緩存大小
        config.tasksProcessingOrder(QueueProcessingType.LIFO);
        config.writeDebugLogs(); // 圖檔加載情況列印到log
        ImageLoader.getInstance().init(config.build());
    }
}
           

定義好了

Application

别忘了在

Manifest

中使用,即設定

application

的name屬性,如下:

<application
        android:name=".util.UILApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
           

從伺服器讀取圖檔位址的操作就忽略了,接下來直接調用方法顯示圖檔:

//參數分别為圖檔Url位址 , 要顯示的ImageView元件 ,全局Option配置
ImageLoader.getInstance().displayImage(item.getmImageUrl(), mainImage, UILApplication.options);
           

無網讀取緩存的方法:

其他地方不用更改,需要更改的隻是擷取圖檔

Url

的方法,一般建議将圖檔

Url

位址儲存到本地資料庫,啟動的時候判斷是否存在網絡,如果不存在即讀取本地資料,當然最好的方式是預設讀取本地資料,如果有網,則進行重新整理操作,示例

Demo

中使用的是

Url

儲存在本地資料庫,那麼就順便理一下示例

Demo

的實作過程吧

1.需要兩個方法,

initData()

initView()

,前一個用于擷取資料,後一個用于顯示圖檔到界面,當然為了提升性能一般講

initData()

放到子線程中進行,讀取資料完成後通過

Handler

通知

UI

線程調用

IinitView()

方法,那麼就還需要一個

Runnable

Handler

對象,下面貼一下代碼:

private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            //調用資料更新
            initData();
        }
    };

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == INITSUCCESS) { //INITSUCCESS定義的全局變量,int
                initView();
            }
        }
    };
           

initData()

代碼(本次Demo使用Bmob來擷取伺服器資料)

if (isNetworkConnected(MainActivity.this)) {
            BmobQuery<MainHeadItem> query = new BmobQuery<>();
            query.findObjects(this, new FindListener<MainHeadItem>() {
                @Override
                public void onSuccess(List<MainHeadItem> list) {
                    item = new MainHeadItem(MainActivity.this);
                    item.setmImage(list.get().getmImage());
                    item.setmDesc(list.get().getmDesc());
                    handler.sendEmptyMessage(INITSUCCESS);
                    SaveData();
                }

                @Override
                public void onError(int i, String s) {

                }
            });
        } else {
            ReadDateBase();
            handler.sendEmptyMessage(INITSUCCESS);
        }
           

判斷是否有網絡的方法(需要在

Manifest

中申請權限):

//權限申請
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
           

具體方法

public static boolean isNetworkConnected(Context context) {
        ConnectivityManager connectivityManager
                = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetworkInfo != null && activeNetworkInfo.isConnected();
    }
           

讀取本地資料庫的方法:(本次測試隻儲存了三個屬性,

id

,

mDesc

,

MimageUrl

)

//    讀取本地資料
    private void ReadDateBase() {
        Cursor cursor = helper.getReadableDatabase().rawQuery("select * from MainHeadItem ", null);//TODO記錄
        while (cursor.moveToNext()) {
            item = new MainHeadItem(MainActivity.this, cursor.getString(), cursor.getString());
        }
        handler.sendEmptyMessage(INITSUCCESS);

    }
           

可以看到從網絡加載資料之後就調用了儲存本地資料,也一起貼出來:

//儲存本地資料
    private void SaveData() {
        SQLiteDatabase db = helper.getReadableDatabase();
        db.execSQL("insert into MainHeadItem values(null,?,?)", new String[]{item.getmImage().getFileUrl(MainActivity.this), item.getmDesc()});
    }
           

注:

helper

為自定義的

SQLiteOpenHelper

對象,隻包含建表操作,就不貼了.

經過如上的操作之後,即使無網,也能擷取到跟有網狀态下一樣的資料,即實作了無網緩存

本次隻是使用了

ImageLoader

的一些基本的使用,在實際使用中可以根據項目的實際情況來進行配置.

測試Demo位址:ImageLoaderTest