Android圖片異步加載框架Android-Universal-Image-Loader
Android-Universal-Image-Loader是一個(gè)圖片異步加載,緩存和顯示的框架。這個(gè)框架已經(jīng)被很多開(kāi)發(fā)者所使用,是最常用的幾個(gè)Android開(kāi)源項(xiàng)目之一,主流的應(yīng)用,隨便反編譯幾個(gè),都可以見(jiàn)到它的身影。淘寶,天貓,F(xiàn)acebook,京東商城等都用到了這個(gè)項(xiàng)目。
該項(xiàng)目的Github地址鏈接
運(yùn)行流程:
每一個(gè)圖片的加載和顯示任務(wù)都運(yùn)行在獨(dú)立的線程中,除非這個(gè)圖片緩存在內(nèi)存中,這種情況下圖片會(huì)立即顯示。如果需要的圖片緩存在本地,它會(huì)開(kāi)啟一個(gè)獨(dú)立的線程隊(duì)列。如果在緩存中沒(méi)有正確的圖片,任務(wù)線程會(huì)從網(wǎng)絡(luò)中獲取。
使用步驟:
1、加載圖片之前,先要做初始化配置,這個(gè)類(lèi)似很多游戲引擎使用前要做一下初始化,其實(shí)只做了一件事,實(shí)例化一個(gè)全局的ImageLoader對(duì)象,同時(shí)傳入圖片加載緩存的配置,ImageLoaderConfiguration封裝了基本的配置信息,比如加載圖片事用的線程池大小,線程的優(yōu)先級(jí),內(nèi)存緩存大小,是否支持同一圖片的多尺寸緩存(默認(rèn)是支持的,可以手動(dòng)關(guān)閉),還有緩存的命名規(guī)則等等。
2、配置完后,就可以開(kāi)始使用了,通過(guò)ImageLoader的displayImage()綁定一個(gè)圖片和ImageView。
displayImage(String uri, ImageView imageView, DisplayImageOptions options)
DisplayImageOptions用于指導(dǎo)每一個(gè)Imageloader根據(jù)網(wǎng)絡(luò)圖片的狀態(tài)(空白、下載錯(cuò)誤、正在下載)顯示對(duì)應(yīng)的圖片,是否將緩存加載到磁盤(pán)上,下載完后對(duì)圖片進(jìn)行怎么樣的處理。
實(shí)例:UniversalImageLoaderDemo
運(yùn)行效果:
代碼清單:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.rainsong.universalimageloaderdemo" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.INTERNET" /> <application android:name="com.rainsong.universalimageloaderdemo.UILApplication" android:allowBackup="true" android:icon="@drawable/logo" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.rainsong.universalimageloaderdemo.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
布局文件:activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" > <ListView android:id="@+id/list" android:layout_width="match_parent" android:layout_height="match_parent" > </ListView> </LinearLayout>
布局文件:item_list.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" > <ImageView android:id="@+id/image" android:layout_width="72dip" android:layout_height="72dip" android:layout_margin="3dip" android:adjustViewBounds="true" android:contentDescription="@string/descr_image" android:scaleType="centerCrop" /> <TextView android:id="@+id/text" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="start|center_vertical" android:layout_marginLeft="20dip" android:textSize="22sp" /> </LinearLayout>
Java源代碼文件:UILApplication.java
package com.rainsong.universalimageloaderdemo; import java.io.File; import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiscCache; import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator; import com.nostra13.universalimageloader.cache.memory.impl.UsingFreqLimitedMemoryCache; import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; import com.nostra13.universalimageloader.core.assist.QueueProcessingType; import com.nostra13.universalimageloader.core.download.BaseImageDownloader; import com.nostra13.universalimageloader.utils.StorageUtils;import android.app.Application; import android.content.Context; public class UILApplication extends Application { @Override public void onCreate() { super.onCreate(); initImageLoader(getApplicationContext()); } public static void initImageLoader(Context context) { //緩存文件的目錄 File cacheDir = StorageUtils.getOwnCacheDirectory(context, "universalimageloader/Cache"); ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context) .memoryCacheExtraOptions(480, 800) // max width, max height,即保存的每個(gè)緩存文件的最大長(zhǎng)寬 .threadPoolSize(3) //線程池內(nèi)線程的數(shù)量 .threadPriority(Thread.NORM_PRIORITY - 2) .denyCacheImageMultipleSizesInMemory() .diskCacheFileNameGenerator(new Md5FileNameGenerator()) //將保存的時(shí)候的URI名稱用MD5 加密 .memoryCache(new UsingFreqLimitedMemoryCache(2 * 1024 * 1024)) .memoryCacheSize(2 * 1024 * 1024) // 內(nèi)存緩存的最大值 .diskCacheSize(50 * 1024 * 1024) // SD卡緩存的最大值 .tasksProcessingOrder(QueueProcessingType.LIFO) // 由原先的discCache -> diskCache .diskCache(new UnlimitedDiscCache(cacheDir))//自定義緩存路徑 .imageDownloader(new BaseImageDownloader(context, 5 * 1000, 30 * 1000)) // connectTimeout (5 s), readTimeout (30 s)超時(shí)時(shí)間 .writeDebugLogs() // Remove for release app .build(); //全局初始化此配置 ImageLoader.getInstance().init(config); } }
Java源代碼文件:MainActivity.java
package com.rainsong.universalimageloaderdemo; import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.display.RoundedBitmapDisplayer; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; public class MainActivity extends Activity { private ImageLoader imageLoader; private ListView lv; private String[] imageUrls; private DisplayImageOptions options; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageLoader = ImageLoader.getInstance(); lv = (ListView)findViewById(R.id.list); imageUrls = Constants.images; // 使用DisplayImageOptions.Builder()創(chuàng)建DisplayImageOptions options = new DisplayImageOptions.Builder() .showImageOnLoading(R.drawable.ic_stub) // 設(shè)置圖片下載期間顯示的圖片 .showImageForEmptyUri(R.drawable.ic_empty) // 設(shè)置圖片Uri為空或是錯(cuò)誤的時(shí)候顯示的圖片 .showImageOnFail(R.drawable.ic_error) // 設(shè)置圖片加載或解碼過(guò)程中發(fā)生錯(cuò)誤顯示的圖片 .cacheInMemory(true) // 設(shè)置下載的圖片是否緩存在內(nèi)存中 .cacheOnDisk(true) // 設(shè)置下載的圖片是否緩存在SD卡中 .displayer(new RoundedBitmapDisplayer(20)) // 設(shè)置成圓角圖片 .build(); // 構(gòu)建完成 lv.setAdapter(new ItemListAdapter()); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.item_clear_memory_cache: ImageLoader.getInstance().clearMemoryCache(); return true; case R.id.item_clear_disc_cache: ImageLoader.getInstance().clearDiskCache(); return true; default: return false; } } class ItemListAdapter extends BaseAdapter { @Override public int getCount() { // TODO Auto-generated method stub return imageUrls.length; } @Override public Object getItem(int position) { // TODO Auto-generated method stub return imageUrls[position]; } @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub ViewHolder holder = null; if (convertView == null) { convertView = getLayoutInflater().inflate(R.layout.item_list, parent, false); holder = new ViewHolder(); holder.text = (TextView) convertView.findViewById(R.id.text); holder.image = (ImageView) convertView.findViewById(R.id.image); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.text.setText("Item " + (position + 1)); imageLoader.displayImage(imageUrls[position], holder.image, options); return convertView; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } class ViewHolder { public ImageView image; public TextView text; } } }
- Android編程實(shí)現(xiàn)異步消息處理機(jī)制的幾種方法總結(jié)
- Android異步方法以同步方式實(shí)現(xiàn)
- Android使用OkHttp進(jìn)行網(wǎng)絡(luò)同步異步操作
- Android 異步任務(wù) 設(shè)置 超時(shí)使用handler更新通知功能
- Android開(kāi)發(fā)實(shí)現(xiàn)ListView異步加載數(shù)據(jù)的方法詳解
- Android開(kāi)發(fā)之HttpClient異步請(qǐng)求數(shù)據(jù)的方法詳解【附demo源碼下載】
- Android上傳多張圖片的實(shí)例代碼(RxJava異步分發(fā))
- Android異步消息處理機(jī)制實(shí)現(xiàn)原理詳解
相關(guān)文章
Android使用Item Swipemenulistview實(shí)現(xiàn)仿QQ側(cè)滑刪除功能
大家都用過(guò)QQ,肯定有人好奇QQ滑動(dòng)刪除Item的效果是怎樣實(shí)現(xiàn)的,其實(shí)我們使用Swipemenulistview就可以簡(jiǎn)單的實(shí)現(xiàn)。這篇文章主要介紹了Android使用ItemSwipemenulistview實(shí)現(xiàn)仿QQ側(cè)滑刪除功能,需要的朋友可以參考下2017-02-02Android游戲開(kāi)發(fā)之碰撞檢測(cè)(矩形碰撞、圓形碰撞、像素碰撞)
這篇文章主要介紹了Android游戲開(kāi)發(fā)之碰撞檢測(cè),主要內(nèi)容包含矩形碰撞、圓形碰撞、像素碰撞、多矩形碰撞的代碼,感興趣的小伙伴們可以參考一下2016-07-07Android實(shí)現(xiàn)自動(dòng)提取短信驗(yàn)證碼功能
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)自動(dòng)提取短信驗(yàn)證碼功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-01-01Android實(shí)現(xiàn)彈出列表、單選、多選框
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)彈出列表、單選、多選框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-10-10Android自定義View圓形和拖動(dòng)圓、跟隨手指拖動(dòng)效果
單純的自定義一個(gè)圓非常簡(jiǎn)單 只需要幾步就完成 拖動(dòng)圓添加實(shí)現(xiàn)觸摸事件即可 。接下來(lái)通過(guò)本文給大家分享Android自定義View圓形和拖動(dòng)圓、跟隨手指拖動(dòng)效果,感興趣的朋友一起看看吧2017-09-09Flutter UI實(shí)現(xiàn)側(cè)拉抽屜菜單
這篇文章主要為大家詳細(xì)介紹了Flutter UI實(shí)現(xiàn)側(cè)拉抽屜菜單,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03Flutter StatefulBuilder實(shí)現(xiàn)局部刷新實(shí)例詳解
這篇文章主要為大家介紹了Flutter StatefulBuilder實(shí)現(xiàn)局部刷新實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08Android實(shí)現(xiàn)點(diǎn)擊AlertDialog上按鈕時(shí)不關(guān)閉對(duì)話框的方法
這篇文章主要介紹了Android實(shí)現(xiàn)點(diǎn)擊AlertDialog上按鈕時(shí)不關(guān)閉對(duì)話框的方法,涉及設(shè)置監(jiān)聽(tīng)的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-02-02Android未讀消息拖動(dòng)氣泡示例代碼詳解(附源碼)
這篇文章主要介紹了Android未讀消息拖動(dòng)氣泡示例代碼詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02