ImageLoader的基本使用
ImageLoader是一款強大的圖檔加載緩存庫,功能非常強大,算是幾款圖檔加載開源庫中相對比較成熟和穩定的.
GitHub位址:Android-Universal-Image-Loader
下面就用一個小demo來示範一下這款功能強大的開源庫的使用,首先看一下效果:
有網的時候從伺服器加載資料,無網的時候讀取本地緩存顯示,如下:
要實作如上的效果主要有以下幾個步驟:
- 配置
,初始化imageloader的配置Application
- 設定全局配置
DisplayImageOptions
- 擷取圖檔URl,調用
來顯示圖檔ImageLoader.getInstance().displayImage(url, ImageView, UILApplication.options);
- 儲存圖檔
到本地,無網的時候讀取,即可與有網情況下一樣顯示圖檔url
Application
的配置
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
Manifest
application
<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
的實作過程吧
Url
Url
Demo
Url
Demo
1.需要兩個方法, initData()
和 initView()
,前一個用于擷取資料,後一個用于顯示圖檔到界面,當然為了提升性能一般講 initData()
放到子線程中進行,讀取資料完成後通過 Handler
通知 UI
線程調用 IinitView()
方法,那麼就還需要一個 Runnable
和 Handler
對象,下面貼一下代碼:
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來擷取伺服器資料)
initData()
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
中申請權限):
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
)
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
對象,隻包含建表操作,就不貼了.
helper
SQLiteOpenHelper
經過如上的操作之後,即使無網,也能擷取到跟有網狀态下一樣的資料,即實作了無網緩存
本次隻是使用了 ImageLoader
的一些基本的使用,在實際使用中可以根據項目的實際情況來進行配置.
ImageLoader