Android ImageLoader(Android-Universal-Image-Loader)【1】概述及使用简单介绍

news/2024/7/20 16:01:07 标签: 移动开发, java, 内存管理


Android ImageLoader(Android-Universal-Image-Loader)【1】概述及使用简单介绍


一,前言:为什么要引入Android-Universal-Image-Loader?

众所周知,简单的几个ImageView载入几个图像资源、或者这几个图像资源是从本地载入时无需考虑过多直接载入就可以。但当成千上百个ImageView载入成千上百个图像、尤其是当这些图片还是从网络中异步获取,那么须要考虑的问题细节非常多非常繁琐且easy出错。如今随便举例当中几条:


(1)最主要的问题,网络不可靠。可能在不可靠网络载入过程中。图片载入发生难以预估的失败。


(2)已经从网络或本地中载入成功的图片,应该避免反复载入,反复载入造成网络流量浪费。以及设备计算资源的反复浪费。因此须要考虑图片缓存策略。

缓存分为两级缓存:第一级:内存缓存,第二级:“硬盘”缓存(一般是手机的外置存储如SD卡和内置存储)。实现这种层级缓存策略须要自己维护和组织。

内存缓存能够考虑使用Android的LruCache。详情參考我的另外两篇文章:
a、《使用新式LruCache代替SoftReference缓存图片,Android异步载入图片》,文章链接地址:http://blog.csdn.net/zhangphil/article/details/43667415
b、或者自己依照LruCache设计思路实现和管理内存管理,《基于Java LinkedList,实现Android大数据缓存策略》,文章链接地址:http://blog.csdn.net/zhangphil/article/details/44116885
硬盘缓存则要自己建立缓存索引和缓存文件结构(怎样建立缓存文件夹?内存在何时机把硬盘缓存的图片增加等等问题)。


(3)设想这一种情况,在一个Android竖直方向上ListView中有成千上万条图片item,每条item中的图片均需从网络获取。

用户手指在屏幕上高速滑动,滑动过程中,极有可能可见视野内的图片还没有载入完毕后,用户已经高速的往下滑看以下的图片去了。

而上面已经消失的图片载入线程假设置之不理任由其运作,那么,当用户在不断的下拉和上拉过程中,将会造成线程不断的重建和执行,内存开销极大。而对于用户来来,最紧迫的当前可见视野的图片载入显示可能由于线程过多而被无限期迟延到最后显示。

这样的情况一般得应对策略师自己维护和管理一个线程池(关于Java线程池。详情请參考我的另外一篇文章:《Java线程池:ExecutorService。Executors》,文章链接地址:http://blog.csdn.net/zhangphil/article/details/43898637 )。自己管理和维护多线程下载任务队列。显然。须要考虑的线程队列问题非常多,非常繁琐。

等等还有非常多未列举出来的细节问题。

为了避免反复造轮子,这样的情况下最好考虑使用一些业界比較成熟稳定的开源框架。


Android ImageLoader(Android-Universal-Image-Loader),是github上的一个第三方开源图像载入库。该项目在github上的链接地址:
https://github.com/nostra13/Android-Universal-Image-Loader 
Android-Universal-Image-Loader主要应用领域是ImageView载入图片。

该开源框架对上述问题给予了充分的解决。并提供了其它额外的附加功能(如载入的图片尺寸。载入动画等等)。


二、Android-Universal-Image-Loader使用简单介绍。

首先到Android-Universal-Image-Loader官方网址下载项目包。使用能够分为两种方法
(1)把Android-Universal-Image-Loader的所有实现源码(*.java)放入到自己的项目文件夹src下,当作是自己的源码使用。
(2)导入Android-Universal-Image-Loader的jar库文件。比方universal-image-loader-1.9.4.jar。
两种方式都能够。看个人偏好。

我用的是第一种方法。这样能够方便查阅甚至直接二次定制改动Android-Universal-Image-Loader的源码为自己所用。
代码结构层次如图:


然后就能够直接使用,现给出一个演示样例。


測试用的MainActivity.java

java">package zhangphil.imageloader;

import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;

import android.app.ListActivity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;

public class MainActivity extends ListActivity {

	private ImageLoader mImageLoader = null;

	// 载入的图片资源URL
	private final String ZHANGPHIL_CSDN_LOGO_URL = "http://avatar.csdn.net/9/7/A/1_zhangphil.jpg";

	// 载入的数目。假定数据总量非常大
	private final int ITEM_COUNT = 10000;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		ListView lv = this.getListView();
		ArrayAdapter adapter = new MyArrayAdapter(this, -1);
		lv.setAdapter(adapter);

		mImageLoader = ImageLoader.getInstance();
		mImageLoader.init(getImageLoaderConfiguration());
	}

	private ImageLoaderConfiguration getImageLoaderConfiguration() {

		ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
				this)
				.threadPoolSize(3)
				// 线程数量
				.threadPriority(Thread.NORM_PRIORITY)
				// 线程优先级
				.tasksProcessingOrder(QueueProcessingType.FIFO)
				.denyCacheImageMultipleSizesInMemory()
				.memoryCacheSize(1024 * 1024 * 10) // 内存缓存的容量10MB
				.diskCacheFileCount(100)// 缓存的文件数量
				.diskCacheSize(1024 * 1014 * 100)// 硬盘缓存的大小100MB
				.writeDebugLogs()// 输出日志
				.build();

		return config;
	}

	private DisplayImageOptions getDisplayImageOptions() {

		DisplayImageOptions options = new DisplayImageOptions.Builder()
				.showImageOnLoading(R.drawable.loading)
				// 载入过程中显示的图片
				.showImageForEmptyUri(R.drawable.ic_launcher)
				// 空URI显示的图片
				.showImageOnFail(R.drawable.error)
				// 载入失败时候显示内容
				.cacheInMemory(true)
				// 缓存到内存
				.cacheOnDisk(true)
				// 缓存到硬盘
				.considerExifParams(true)
				.displayer(new FadeInBitmapDisplayer(1000))// 淡入载入图片显示
				.build();

		return options;
	}

	private class MyArrayAdapter extends ArrayAdapter {

		private LayoutInflater inflater;
		private int resId = R.layout.item;
		private DisplayImageOptions mDisplayImageOptions;

		public MyArrayAdapter(Context context, int resource) {
			super(context, resource);
			inflater = LayoutInflater.from(getContext());
			mDisplayImageOptions = getDisplayImageOptions();
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			if (convertView == null)
				convertView = inflater.inflate(resId, null);

			ImageView imageView = (ImageView) convertView
					.findViewById(R.id.image);
			mImageLoader.displayImage(ZHANGPHIL_CSDN_LOGO_URL, imageView,
					mDisplayImageOptions);

			return convertView;
		}

		@Override
		public int getCount() {
			return ITEM_COUNT;
		}
	}
	
	
	// private File getMyCacheDir() {
	// File sdRoot = Environment.getExternalStorageDirectory();
	// String myImageLoaderCacheFileDir = "ImageLodaerCache";
	// File cacheFileDir = new File(sdRoot, myImageLoaderCacheFileDir);
	// return cacheFileDir;
	// }
}


Item.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/image" >
    
</ImageView>

素材error.png和Loading.gif能够依据个人的须要选取不同的图片资源。


ImageLoader在使用之前须要做一些初始化工作。配置ImageLoaderConfiguration和DisplayImageOptions 。

然后就能够直接使用ImageLoader的displayImage()方法从网络或本地存储中异步载入图片资源。而关于图片资源的缓存和异步下载线程池队列则交由ImageLoader为我们妥善在后台管理好。


http://www.niftyadmin.cn/n/545842.html

相关文章

良禽择木而栖

士为知己者死 ------ 兔死狗烹 看电影《鸿门宴》有感。 转载于:https://www.cnblogs.com/hellojesson/p/6949798.html

Java中hashCode和equals方法的正确使用

在这篇文章中&#xff0c;我将告诉大家我对hashCode和equals方法的理解。我将讨论他们的默认实现&#xff0c;以及如何正确的重写他们。我也将使用Apache Commons提供的工具包做一个实现。 目录&#xff1a; 1.hashCode()和equals()的用法 2.重写默认实现 3.使用Apache Commons…

openssl的vs/vc工程配置与make

openssl在windows上的编译方式很多人都了解&#xff0c;然而很多人因为习惯于windows的ide又很想知道如何在vs2005之类的ide中点击“生成”菜单项编译openssl&#xff0c;然后点击上面的那个绿色的小箭头调试或者单步跟踪&#xff0c;那是一件多么轻松的事情啊&#xff0c;要比…

寻找最好的编程语言

我们社会生活的方方面面越来越依赖着科技技术。从工厂生产&#xff0c;商业贸易到社会互动&#xff0c;几乎在每一个行业中都有软件开发者的身影。计算机编程已经迅速成为最赚钱的职业之一&#xff0c;计算机程序员的平均工资在不断创造新高&#xff0c;目前在美国这一数字已经…

MFC程序总结

一、MFC 获取系统时间GetCurrentTime  GetCurrentTime函数可以用来获取系统时间&#xff0c;用于VC编程。使用方法  在VC中&#xff0c;我们可以借助CTime时间类&#xff0c;获取系统当前日期&#xff0c;具体使用方法如下&#xff1a;  CTime t CTime::GetCurrentTime(…

sql语句的一些基本用法

create database zouxiouuse zouxiou--1仓库(WareHouse)create table WareHouse ( cwcode varchar(20) not null primary key, --仓库编码 cwname varchar(100) , --仓库名称 cwadd varchar(100) , --地址 cwtel varchar(50) , --电话 cwadmin varchar(50) --管理员 ) --2.采…

肺结节CT影像特征提取(四)——肺结节CT影像特征提取MATLAB代码实现

之前的文章讲述了肺结节CT影像数据特征提取算法及基于MATLAB GUI设计的肺结节CT影像特征提取系统。本文将讲述几个主要部分的代码实现&#xff0c;分别是预处理、灰度特征提取、纹理特征提取、形态特征提取数据。 一.预处理部分代码 1、读取肺结节CT数据和专家标记的mask数据 f…

JSTL标签库的导入

(下载jstl) 在tomcat.apache.org/taglibs/下载JSTL1.2标签库到本地。然后放置到tomcat/lib目录下面。拿出其中的c.tldfmt.tldfn.tldsql.tldx.tld五个文件放如所在project的WEB_INF下面。。 >> >> >> (配置jstl) 在Project里的web.xml里面配置JStl。&am…