彻底掌握如何有效处理高清大图:Android-Universal-Image-Loader框架解析(三)下载模块,解码模块和显示模块

彻底掌握如何有效处理高清大图:Android-Universal-Image-Loader框架解析(一)基本使用
彻底掌握如何有效处理高清大图:Android-Universal-Image-Loader框架解析(二)缓存

在UIL框架中,下载,解码和显示三个模块也是比较核心的内容;这篇我们将逐一分析

  1. 下载模块
    在这里插入图片描述

在这个模块当中,所有的下载类都实现了ImageDownloader接口,其默认下载类为BaseImageDownloader

  BaseImageDownloader主要作用:
他能够从网络,文件系统,app本身资源当中根据图片URL来获得图片的输入流

  BaseImageDownloader核心方法

	@Override
	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);
			case DRAWABLE:
				return getStreamFromDrawable(imageUri, extra);
			case UNKNOWN:
			default:
				return getStreamFromOtherSource(imageUri, extra);
		}
	}

从getStream方法可知,UIL框架提供解析http,https,file,content,assets,和drawable类型的scheme的文件;(我们这里以解析http和https文件为例)

当一个图片的url的scheme以http或者https为开始的时候,则会调用getStreamFromNetwork来从网络下载图片

	protected InputStream getStreamFromNetwork(String imageUri, Object extra) throws IOException {
		HttpURLConnection conn = createConnection(imageUri, extra);

		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;
		}
		if (!shouldBeProcessed(conn)) {
			IoUtils.closeSilently(imageStream);
			throw new IOException("Image request failed with response code " + conn.getResponseCode());
		}

		return new ContentLengthInputStream(new BufferedInputStream(imageStream, BUFFER_SIZE), conn.getContentLength());
	}

这个方法比较简单,就是通过HttpURLConnection的方式获得url的输入流,同时在下载的时候,我们应该注意到URL框架默认的重定向次数为5次,同时也可以记住一个小知识点,如果服务端返回的状态码以3开头,则均表示为重定向


  1. 解码模块
    当通过下载模块将图片转换为输入流之后,我们就需要通过解码模块来解码这个输入流了
    在这里插入图片描述

在解码模块当中,ImageDecoder是所有解码器的接口,BaseImageDecoder是默认的解码器,而ImageDecodingInfo里面则是需要解码的信息

  ImageDecodingInfo主要作用
封装解码信息,里面主要包含图片的url信息,图片缩放类型,另外里面有一个重要的成员,即Options decodingOptions;
    Options类,通常用于设置一些加载到内存中的图片的参数,这个在图片加载的时候都会使用这个类来控制加载的图片
Options.inJustDecodeBounds 设置为true,只会返回图片尺寸,不加载图片到内存
Options.inSampleSize 这个值是一个int,当它小于1的时候,将会被当做1处理,如果大于1,那么就会按照比例(1 / inSampleSize)缩小bitmap的宽和高、降低分辨率,大于1时这个值将会被处置为2的倍数。例如,width=100,height=100,inSampleSize=2,那么就会将bitmap处理为,width=50,height=50,宽高降为1 / 2,像素数降为1 / 4
Options.inScaled设置这个Bitmap是否可以被缩放,默认值是true,表示可以被缩放。
Options.inPreferQualityOverSpeed这个值表示是否在解码时图片有更高的品质,仅用于JPEG格式。如果设置为true,则图片会有更高的品质,但是会解码速度会很慢(API24之后被废弃,即24之后,默认解图为高质量,24之前如果设置为true,)
Options.outWidth和Options.outHeight表示这个Bitmap的宽和高,一般和inJustDecodeBounds一起使用来获得Bitmap的宽高,但是不加载到内存
Options.inMutable如果设置为true,则decoder返回的是可变的Bitmap,这可以用来对Bitmap施加一些效果

  BaseImageDecoder主要作用
通过ImageDecodingInfo来获得带解码的图片的scheme,根据scheme去获得对应图片的输入流,BaseImageDecoder根据得到的输入流来进行解码

  BaseImageDecoder核心方法

	public Bitmap decode(ImageDecodingInfo decodingInfo) throws IOException {
		Bitmap decodedBitmap;
		ImageFileInfo imageInfo;

		InputStream imageStream = getImageStream(decodingInfo);
		if (imageStream == null) {
			L.e(ERROR_NO_IMAGE_STREAM, decodingInfo.getImageKey());
			return null;
		}
		try {
			imageInfo = defineImageSizeAndRotation(imageStream, decodingInfo);
			imageStream = resetStream(imageStream, decodingInfo);
			Options decodingOptions = prepareDecodingOptions(imageInfo.imageSize, decodingInfo);
			decodedBitmap = BitmapFactory.decodeStream(imageStream, null, decodingOptions);
		} finally {
			IoUtils.closeSilently(imageStream);
		}

		if (decodedBitmap == null) {
			L.e(ERROR_CANT_DECODE_IMAGE, decodingInfo.getImageKey());
		} else {
			decodedBitmap = considerExactScaleAndOrientatiton(decodedBitmap, decodingInfo, imageInfo.exif.rotation,
					imageInfo.exif.flipHorizontal);
		}
		return decodedBitmap;
	}

  第5行,下载模块BaseImageDownloader根据scheme获得图片的输入流
  第14行,把当前图片流根据Options的参数设置来进行解码,返回Bitmap

  1. 显示模块
    当图片经过下载,然后被解码生成新的bitmap之后,就需要通过显示模块显示在上层界面上了
    在这里插入图片描述

显示模块的基础接口是BitmapDisplayer,各个显示模块均实现了BitmapDisplayer接口,主要作用就是针对bitmap做修改,返回一个新的bitmap,这样就可以显示在上层界面上了,此处以FadeInBitmapDisplayer为例

  FadeInBitmapDisplayer主要作用
imageview显示图片的形式是淡入模式

  FadeInBitmapDisplayer核心代码

	@Override
	public void display(Bitmap bitmap, ImageAware imageAware, LoadedFrom loadedFrom) {
		imageAware.setImageBitmap(bitmap);

		if ((animateFromNetwork && loadedFrom == LoadedFrom.NETWORK) ||
				(animateFromDisk && loadedFrom == LoadedFrom.DISC_CACHE) ||
				(animateFromMemory && loadedFrom == LoadedFrom.MEMORY_CACHE)) {
			animate(imageAware.getWrappedView(), durationMillis);
		}
	}

	/**
	 * Animates {@link ImageView} with "fade-in" effect
	 *
	 * @param imageView      {@link ImageView} which display image in
	 * @param durationMillis The length of the animation in milliseconds
	 */
	public static void animate(View imageView, int durationMillis) {
		if (imageView != null) {
			AlphaAnimation fadeImage = new AlphaAnimation(0, 1);
			fadeImage.setDuration(durationMillis);
			fadeImage.setInterpolator(new DecelerateInterpolator());
			imageView.startAnimation(fadeImage);
		}
	}

代码比较简单,就是设置imageView的显示图片,并展示一个AlphaAnimation动画

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值