Android-Universal-Image-Loader学习笔记(4)--download

该包所包含的图片如下

其中ImageDownloader为接口,BaseImageDownloader为ImageDownloaer的实现类。

ImageDownloader(接口)

该接口对外提供了一个接口方法:

InputStream getStream(String imageUri,Object extra) throws IOException;

很明显该方法的作用很明显是获取imageUri指定的图片文件的输入流。

由于imageUri所指定的文件源可以来自不同种类的服务器或者地址,所以该接口又定义了一个枚举类Scheme来指定imageUri的来源属于什么种类,其所列举的类型有如下几种:


HTTP("http"), HTTPS("https")


图片来源于http服务器


FILE("file")


imageUri为file协议的字符串


CONTENT("content")


图片文件来源于app的contentprovider


ASSETS("assets")


图片来源于app中的assets文件夹


DRAWABLE("drawable")


图片来源于app的drawable文件夹


UNKNOWN("")


图片来源于其它的途径,在这种情况下,会抛出runtimeexception异常

同时该枚举类还提供了如下几个方法:

ofUri(String uri):此方法根据图片的uri来判断该图片属于以上七个枚举类型的哪一个种。

wrap(String path):此方法用来为path加上uri的前缀,比如http://+path

corp(String uri):与wrap方法相反,去掉uri的前缀

注意:该枚举类的最重要的作用就是根据不同枚举类型来返回图片的不同的图片文件输入流。这个在该接口的实现类BaseImageDownloader会体现出来。

BaseImageDownloader(implements ImageDownLoader)

该类的主要作用是根据imageUri来获取图片文件的输入流,提供了如下几个重要属性:


字段名


属性


字段说明


DEFAULT_HTTP_CONNECT_TIMEOUT


final int


网络链接的最大超时时间


DEFAULT_HTTP_READ_TIMEOUT


final int


从主机中读书数据的超时时间


BUFFER_SIZE


final int


缓存的大小,为32k


MAX_REDIRECT_COUNT


final int


链接网络超时的时候重新请求链接的次数


CONTENT_CONTACTS_URI_PREFIX


final int


当图片来自contentprovider的时候用到它


ERROR_UNSUPPORTED_SCHEME


final int


错误信息,当imageUri的scheme属于UNKNOWN的时候,提示错误信息


context


Context


app应用的上下文


connectTimeout


int


让用户设置链接超时时间


readTimeout


int


让用户设计读取超时时间

该类提供了两个构造器:

/**
	 * 使用该构造器设置的对象,来设置默认最大连接时间
	 * @param context
	 */
	public BaseImageDownloader(Context context) {
		this.context = context.getApplicationContext();
		this.connectTimeout = DEFAULT_HTTP_CONNECT_TIMEOUT;
		this.readTimeout = DEFAULT_HTTP_READ_TIMEOUT;
	}

	/**
	 * 用户自己设定超时时间
	 * @param context
	 * @param connectTimeout
	 * @param readTimeout
	 */
	public BaseImageDownloader(Context context, int connectTimeout, int readTimeout) {
		this.context = context.getApplicationContext();
		this.connectTimeout = connectTimeout;
		this.readTimeout = readTimeout;
	}

下面看看该类是如何实现接口的getStream方法的,具体代码如下

public InputStream getStream(String imageUri, Object extra) throws IOException {
		switch (Scheme.ofUri(imageUri)) {
			case HTTP:
			case HTTPS:
				return getStreamFromNetwork(imageUri, extra);//获取网络输入流
			case FILE:
				return getStreamFromFile(imageUri, extra);//获取文件输入流
			case CONTENT:
				return getStreamFromContent(imageUri, extra);//获取应用上下文的图片文件输入流
			case ASSETS:
				return getStreamFromAssets(imageUri, extra);//获取assets的图片文件输入流
			case DRAWABLE:
				return getStreamFromDrawable(imageUri, extra);//获取drawable里面的图片文件的输入流
			case UNKNOWN:
			default:
				return getStreamFromOtherSource(imageUri, extra);//获取其他源的图片的输入流
		}
	}

该类还提供了一个createConnection方法来根据imageUrl来获取一个httpUrlConnection的链接对象

protected HttpURLConnection createConnection(String url, Object extra) throws IOException {
		String encodedUrl = Uri.encode(url, ALLOWED_URI_CHARS);
		//通过url链接获取一个HttpUrlConnecttion
		HttpURLConnection conn = (HttpURLConnection) new URL(encodedUrl).openConnection();
		conn.setConnectTimeout(connectTimeout);
		conn.setReadTimeout(readTimeout);
		return conn;
	}

当imageuri的scheme为http,https和file的时候返回的输入流对象是经过装饰(装饰模式的应用)的输入流对象ContentLengthInputStream

下面贴出来getStream方法中所涉及的方法如下:

protected InputStream getStreamFromNetwork(String imageUri, Object extra) throws IOException {
		HttpURLConnection conn = createConnection(imageUri, extra);//根据imagUri来获取一个HttpUrlConnection对象

		int redirectCount = 0;
		//如果请求不成功,就再次请求直到请求成功并或者重定向的次数超过了最大请求次数
		while (conn.getResponseCode() / 100 == 3 && redirectCount < MAX_REDIRECT_COUNT) {
			conn = createConnection(conn.getHeaderField("Location"), extra);
			redirectCount++;
		}

		InputStream imageStream;
		try {
			//获取网络输入流,有了这个对象才能从网络中读取数据
			imageStream = conn.getInputStream();
		} catch (IOException e) {
			// Read all data to allow reuse connection (http://bit.ly/1ad35PY)
			IoUtils.readAndCloseStream(conn.getErrorStream());
			throw e;
		}
		//对网络输入流进行进一步封装,这里面应用了装饰模式
		return new ContentLengthInputStream(new BufferedInputStream(imageStream, BUFFER_SIZE), conn.getContentLength());
	}

protected InputStream getStreamFromFile(String imageUri, Object extra) throws IOException {
		String filePath = Scheme.FILE.crop(imageUri);//根据url获取路径
		return new ContentLengthInputStream(new BufferedInputStream(new FileInputStream(filePath), BUFFER_SIZE),
				(int) new File(filePath).length());
	}

protected InputStream getStreamFromContent(String imageUri, Object extra) throws FileNotFoundException {
		/*
		 * ContentProviders存储和检索数据,通过它可以让所有的应用程序访问到,这也是应用程序之间唯一共享数据的方法,则负责获取ContentProvider提供的数据;
		 */
		ContentResolver res = context.getContentResolver();
		Uri uri = Uri.parse(imageUri);
		if (imageUri.startsWith(CONTENT_CONTACTS_URI_PREFIX)) {
			return ContactsContract.Contacts.openContactPhotoInputStream(res, uri);
		} else {
			return res.openInputStream(uri);
		}
	}

protected InputStream getStreamFromAssets(String imageUri, Object extra) throws IOException {
		String filePath = Scheme.ASSETS.crop(imageUri);//获取文件的路径
		return context.getAssets().open(filePath);//获取文件的输入流
	}

protected InputStream getStreamFromDrawable(String imageUri, Object extra) {
		String drawableIdString = Scheme.DRAWABLE.crop(imageUri);
		int drawableId = Integer.parseInt(drawableIdString);
		return context.getResources().openRawResource(drawableId);
	}

protected InputStream getStreamFromOtherSource(String imageUri, Object extra) throws IOException {
		throw new UnsupportedOperationException(String.format(ERROR_UNSUPPORTED_SCHEME, imageUri));
	}

Android-Universal-Image-Loader学习笔记(4)--download

时间: 2024-10-30 05:37:28

Android-Universal-Image-Loader学习笔记(4)--download的相关文章

Android Universal Image Loader java.io.FileNotFoundException: http:/xxx/lxx/xxxx.jpg

前段时间在使用ImageLoader异步加载服务端返回的图片时总是出现 java.io.FileNotFoundException: http://xxxx/l046/10046137034b1c0db0.jpg at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177) at com.nostra13.universalimageloader.core.download.URL

Android Universal Image Loader 使用

1. 功能介绍 1.1 Android Universal Image Loader Android Universal Image Loader 是一个强大的.可高度定制的图片缓存,本文简称为UIL. 简单的说 UIL 就做了一件事--获取图片并显示在相应的控件上. 1.2 基本使用 1.2.1 初始化 添加完依赖后在Application或Activity中初始化ImageLoader,如下: public class YourApplication extends Application

[转载]Android Bitmap和Canvas学习笔记

http://blog.chinaunix.net/uid-20771867-id-3053339.html [转载]Android Bitmap和Canvas学习笔记,布布扣,bubuko.com

Android(java)学习笔记167:Java中操作文件的类介绍

1.File类:对硬盘上的文件和目录进行操作的类.    File类是文件和目录路径名抽象表现形式  构造函数:        1) File(String pathname)       Creates a new File instance by converting the given pathname string into an abstract pathname. 2)File(File parent, String child)       Creates a new File i

Android(java)学习笔记205:网易新闻客户端应用编写逻辑过程

1.我们的项目需求是编写一个新闻RSS浏览器,RSS(Really Simple Syndication)是一种描述和同步网站内容的格式,是使用最广泛的XML应用.RSS目前广泛用于网上新闻频道,blog和wiki,主要的版本有0.91, 1.0, 2.0.使用RSS订阅能更快地获取信息,网站提供RSS输出,有利于让用户获取网站内容的最新更新.网络用户可以在客户端借助于支持RSS的聚合工具软件,在不打开网站内容页面的情况下阅读支持RSS输出的网站内容. 例如如下的网易RSS订阅: 2.由于我们这

Android(java)学习笔记204:自定义SmartImageView(继承自ImageView,扩展功能为自动获取网络路径图片)

1.有时候Android系统配置的UI控件,不能满足我们的需求,Android开发做到了一定程度,多少都会用到自定义控件,一方面是更加灵活,另一方面在大数据量的情况下自定义控件的效率比写布局文件更高. 2.下面我们是自定义一个SmartImageView继承自ImageView,扩展了ImageView的功能:     步骤: • 新建一个SmartImageView类,让继承自ImageView(放置特定的包下): • 实现SmartImageView类下的构造方法,最好全部实现,这个不容易出

Android Universal Image Loader 架构剖析

简介 Android Universal Image Loader简称UIL, 其github链接https://github.com/nostra13/Android-Universal-Image-Loader, 它用于Android应用中的图片加载(从网络,本地文件,或资源文件),本地缓存(内存和磁盘), 以及展示在ImageView中. 示例 整体框架 各模块的流程图 Task流程: 下载流程: decode流程: cache流程: 主要类图:

Android(java)学习笔记227:服务(service)之服务的生命周期(service)

1.之前我们在Android(java)学习笔记171:Service生命周期 (2015-08-18 10:56)说明过,可以回头看看: 2.接下来就简单概括性描述一下: (1)start的方式开启服务,服务会执行onCreate方法 (2)如果服务已经被创建,就不会再去执行onStartCommand()  (onStart过时) (3)停止服务,服务会执行onDestory(): (4)如果服务已经停止,多次调用stopService()无效的

Android(java)学习笔记207:开源项目使用之gif view

1. 由于android没有自带的gif动画,我在Android(java)学习笔记198:Android下的帧动画(Drawable Animation) 播客中提到可以使用AnimationView(帧动画)方法先将一个gif动画利用软件分割成若干静态图片,然后按照一定的时间间隔和播放顺序一帧一帧播放图片,从而给用户体验仿佛是动画gif播放的效果 2.其实网上的开源项目中有更为完善的gif动画播放的代码,下面以此为例进一步了解开源项目的使用: (1)在https://github.com/网

Android(java)学习笔记233: 远程服务的应用场景(移动支付案例)

一. 移动支付:       用户需要在移动终端提交账号.密码以及金额等数据 到 远端服务器.然后远端服务器匹配这些信息,进行逻辑判断,进而完成交易,返回交易成功或失败的信息给移动终端.用户提交账号.密码以及金额等数据都是比较敏感的数据,这些数据不能让外界获取.       阿里等等支付宝平台把支付的逻辑封装起来,只给我们提供一个方法去调用,这样提高了安全性.当我们用户提交账号.密码以及金额等数据,点击"支付"的时候,支付宝平台已经调用方法加密数据(这个支付逻辑是远程服务,为了安全,防