標籤:android
一.Universal-Image-Loader概述:
Android-Universal-Image-Loader是一個開源的圖片載入架構,這個項目的目的是提供一個可重複使用的儀器為非同步映像載入,緩衝和顯示。
開源庫的特性:
(1).多線程下載圖片。
(2).可通過配置ImageLoader,改變線程池,圖片下載器,等等的配置。
(3).支援圖片的在記憶體緩衝,檔案系統快取或sd卡緩衝。
(4).支援圖片下載的監聽。
(5).可以較好的控製圖片的載入過程,例如在listview滑動時停止載入圖片,停止滑動時載入圖片。
其他的一些特性就去http://blog.csdn.net/xiaanming/article/details/26810303這位大神部落格去看吧。
二.簡單的使用:
:
未載入出來時:
載入成功:
在項目裡匯入jar包後,先要配置ImageLoaderConfiguration,這個是對全域圖片緩衝還有線程,緩衝大小,解析等等進行配置,然後ImageLoader是具體實現下載圖片、緩衝圖片顯示圖片的執行類,把配置好的ImageLoaderConfiguration傳入ImageLoader,完成初始化工作,也就是初始化後才能使用ImageLoader.getInstance().displayImage()載入圖片。
ImageLoader的初始化可以在Application中實現:
public class MyApp extends Application {@Overridepublic void onCreate() {super.onCreate();initImageLoader1(getApplicationContext());}/* * 自訂配置 */public static void initImageLoader(Context context) {ImageLoaderConfiguration.Builder config = new ImageLoaderConfiguration.Builder(context);config.threadPoolSize(3);//線程池內載入的數量 config.threadPriority(Thread.NORM_PRIORITY - 2);config.denyCacheImageMultipleSizesInMemory();// 不緩衝圖片的多種尺寸在記憶體中config.diskCacheFileNameGenerator(new Md5FileNameGenerator());// 將儲存的時候的URI名稱用MD5config.diskCacheSize(50 * 1024 * 1024); // 50 MiBconfig.tasksProcessingOrder(QueueProcessingType.LIFO);config.writeDebugLogs();// Remove for release app// 初始化ImageLoaderImageLoader.getInstance().init(config.build());}/* * 預設的配置,一般沒有特殊的要求的時候就使用預設就好了。 */public static void initImageLoader1(Context context) {// 建立預設的ImageLoader配置參數ImageLoaderConfiguration configuration = ImageLoaderConfiguration.createDefault(context);// 初始化ImageLoaderImageLoader.getInstance().init(configuration);}}
在diskCacheFileNameGenerator();這是表示將緩衝下來的檔案以什麼方式命名,有以下兩種方式:
1.new Md5FileNameGenerator() //使用MD5對UIL進行加密命名
2.new HashCodeFileNameGenerator()//使用HASHCODE對UIL進行加密命名
然後在AndroidManifest.xml配置下:
<!-- 網路許可權和緩衝許可權 --> <span style="color:#ff0000;"><uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /></span> <application android:name="com.example.androidimageview.MyApp" android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity <span style="color:#ff0000;">android:name="com.example.androidimageview.MainActivity"</span> 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>
定義布局檔案:
<RelativeLayout 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" > <ListView android:id="@+id/listview1"android:layout_width="fill_parent"android:layout_height="fill_parent" /></RelativeLayout>
圖片加載使用DisplayImageOptions,這時我們可以配置一下這個圖片顯示的選項,比片載入完成之前先顯示什麼圖片,載入失敗顯示什麼圖片等等:
<span style="font-size:24px;">options = new DisplayImageOptions.Builder().showImageOnLoading(R.drawable.ic_stub)//設定圖片在下載期間顯示的圖片 .showImageForEmptyUri(R.drawable.ic_empty)//設定圖片Uri為空白或是錯誤的時候顯示的圖片 .showImageOnFail(R.drawable.ic_error)//設定圖片載入/解碼過程中錯誤時候顯示的圖片.delayBeforeLoading(1000)//設定延時多少時間後開始下載.cacheInMemory(true)//設定下載的圖片是否緩衝在記憶體中.cacheOnDisk(true)// 設定下載的資源是否緩衝在SD卡中.considerExifParams(true)// 是否考慮JPEG映像EXIF參數(旋轉,翻轉).imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)//設定圖片以何種編碼方式顯示.bitmapConfig(Bitmap.Config.RGB_565) // 設定圖片的解碼類型.displayer(new RoundedBitmapDisplayer(20))//是否設定為圓角,弧度為多少.displayer(new FadeInBitmapDisplayer(1000))//是否圖片載入好後漸入的動畫時間.build();</span>
圖片的顯示大小會根據你ImageView的狂傲在上邊的配置中:
imageScaleType(ImageScaleType imageScaleType):
縮放類型mageScaleType:
(1). EXACTLY :映像將完全按比例縮小的目標大小。
(2). EXACTLY_STRETCHED:圖片會縮放到目標大小完全
(3). IN_SAMPLE_INT:映像將被二次採樣的整數倍
(4). IN_SAMPLE_POWER_OF_2:圖片將降低2倍,直到下一減少步驟,使映像更小的目標大小
(5). NONE:圖片不會調整
item的布局:
<?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"><ImageViewandroid:id="@+id/image"android:layout_width="72dp"android:layout_height="72dp"android:layout_margin="3dip"android:adjustViewBounds="true"android:contentDescription="@string/descr_image"android:scaleType="centerCrop" /><TextViewandroid:id="@+id/text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="start|center_vertical"android:layout_marginLeft="20dip"android:textSize="22sp" /></LinearLayout>
主介面實現:
public class MainActivity extends Activity {private static final String TEST_FILE_NAME = "Universal Image Loader @#&=+-_.,!()~'%20.png";ListView listview1 ;public static final String[] IMAGES = new String[] {"http://img.dapixie.com/uploads/allimg/111105/1-111105145231.jpg"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listview1 = (ListView)findViewById(R.id.listview1); listview1.setAdapter(new ImageAdapter(this)); } @Override protected void onDestroy() { super.onDestroy(); AnimateFirstDisplayListener.displayedImages.clear(); ImageLoader.getInstance().clearMemoryCache(); ImageLoader.getInstance().stop(); } private static class ImageAdapter extends BaseAdapter {private static final String[] IMAGE_URLS = MainActivity.IMAGES;private LayoutInflater inflater;private ImageLoadingListener animateFirstListener = new AnimateFirstDisplayListener();private DisplayImageOptions options;ImageAdapter(Context context) {inflater = LayoutInflater.from(context);options = new DisplayImageOptions.Builder().showImageOnLoading(R.drawable.ic_stub)//設定圖片在下載期間顯示的圖片 .showImageForEmptyUri(R.drawable.ic_empty)//設定圖片Uri為空白或是錯誤的時候顯示的圖片 .showImageOnFail(R.drawable.ic_error)//設定圖片載入/解碼過程中錯誤時候顯示的圖片.delayBeforeLoading(1000)//設定延時多少時間後開始下載.cacheInMemory(true)//設定下載的圖片是否緩衝在記憶體中.cacheOnDisk(true)// 設定下載的資源是否緩衝在SD卡中.considerExifParams(true)// 是否考慮JPEG映像EXIF參數(旋轉,翻轉).imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)//設定圖片以何種編碼方式顯示.bitmapConfig(Bitmap.Config.RGB_565) // 設定圖片的解碼類型.displayer(new RoundedBitmapDisplayer(20))//是否設定為圓角,弧度為多少.displayer(new FadeInBitmapDisplayer(1000))//是否圖片載入好後漸入的動畫時間.build();}@Overridepublic int getCount() {return IMAGE_URLS.length;}@Overridepublic Object getItem(int position) {return position;}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(final int position, View convertView, ViewGroup parent) {View view = convertView;final ViewHolder holder;if (convertView == null) {view = inflater.inflate(R.layout.listview_item, parent, false);holder = new ViewHolder();holder.text = (TextView) view.findViewById(R.id.text);holder.image = (ImageView) view.findViewById(R.id.image);view.setTag(holder);} else {holder = (ViewHolder) view.getTag();}holder.text.setText("Item " + (position + 1));ImageLoader.getInstance().displayImage(IMAGE_URLS[position], holder.image, options, animateFirstListener);return view;}}static class ViewHolder {TextView text;ImageView image;}private static class AnimateFirstDisplayListener extends SimpleImageLoadingListener {static final List<String> displayedImages = Collections.synchronizedList(new LinkedList<String>());@Overridepublic void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {if (loadedImage != null) {ImageView imageView = (ImageView) view;boolean firstDisplay = !displayedImages.contains(imageUri);if (firstDisplay) {FadeInBitmapDisplayer.animate(imageView, 500);displayedImages.add(imageUri);}}}}}
在使用,主要是這幾個ImageLoader.getInstance().displayImage(),ImageLoader.getInstance().loadImage(),ImageLoader.getInstance().loadImageSync(),ImageLoader.getInstance().loadImageSync()方法是同步的,android4.0有個特性,網路操作不能在主線程,所以ImageLoader.getInstance().loadImageSync()方法我們就不去使用。
主要介紹ImageLoader.getInstance().displayImage()其中三種重載方法:
(1).ImageLoader.getInstance().displayImage(imageUrl, imageView):其中參數imageUrl代表圖片的URL地址,imageView代表承載圖片的IMAGEVIEW控制項
(2).ImageLoader.getInstance().displayImage(imageUrl, imageView,options):其中的參數imageUrl代表圖片的URL地址,imageView代表承載圖片的IMAGEVIEW控制項 , options代表DisplayImageOptions設定檔
(3).ImageLoader.getInstance().displayImage(IMAGE_URLS[position], holder.image, options, animateFirstListener):這就是上面代碼中使用的一種方式。animateFirstListener圖片載入監聽的。
圖片下載監聽還有可以用ImageLoadingListener,這種方式就是比較複雜,可以使用簡單點的SimpleImageLoadingListener。
new ImageLoadingListener(){@Overridepublic void onLoadingCancelled(String arg0, View arg1) {//載入取消的時候執行 }@Overridepublic void onLoadingComplete(String arg0, View arg1,Bitmap arg2) {//載入成功的時候執行 }@Overridepublic void onLoadingFailed(String arg0, View arg1,FailReason arg2) {//載入失敗的時候執行 }@Overridepublic void onLoadingStarted(String arg0, View arg1) {//開始載入的時候執行 } };
三.載入其他來源的圖片:
String imageUri = "http://site.com/image.png"; // from WebString imageUri = "file:///mnt/sdcard/image.png"; // from SD cardString imageUri = "content://media/external/audio/albumart/13"; // from content providerString imageUri = "assets://image.png"; // from assetsString imageUri = "drawable://" + R.drawable.image; // from drawables (only images, non-9patch)
四.避免oom(我也從別人的部落格學習來的,貼上大神部落格地址http://blog.csdn.net/xiaanming/article/details/26810303):
1.減少線程池中線程的個數,在ImageLoaderConfiguration中的(.threadPoolSize)中配置,推薦配置1-5。
2.在DisplayImageOptions選項中配置bitmapConfig為Bitmap.Config.RGB_565,因為預設是ARGB_8888, 使用RGB_565會比使用ARGB_8888少消耗2倍的記憶體
3.在ImageLoaderConfiguration中配置圖片的記憶體緩衝為memoryCache(new WeakMemoryCache()) 或者不使用記憶體緩衝
4.在DisplayImageOptions選項中設定.imageScaleType(ImageScaleType.IN_SAMPLE_INT)或者imageScaleType(ImageScaleType.EXACTLY)
通過上面這些,相信大家對Universal-Image-Loader架構的使用已經非常的瞭解了,我們在使用該架構的時候盡量的使用displayImage()方法去載入圖片,loadImage()是將圖片對象回調到ImageLoadingListener介面的onLoadingComplete()方法中,需要我們手動去設定到ImageView上面,displayImage()方法中,對ImageView對象使用的是Weak references,方便記憶體回收行程回收ImageView對象,如果我們要載入固定大小的圖片的時候,使用loadImage()方法需要傳遞一個ImageSize對象,而displayImage()方法會根據ImageView對象的測量值,或者android:layout_width and android:layout_height設定的值,或者android:maxWidth and/or android:maxHeight設定的值來裁剪圖片
android Universal-Image-Loader架構學習