Glide-渐进式加载初尝试
来源:互联网 发布:2009年网络歌曲排行榜 编辑:程序博客网 时间:2024/05/21 09:01
前言
前面我们讲解了渐进式加载的基础,接下来我们就讲一下在app中具体如何实现渐进式加载
1.基础
关于渐进式加载的基础知识,我们已经在前面讲解过了,这里就不重复讲解了,但是不代表不重要.
渐进式加载-基础讲解
http://blog.csdn.net/yulyu/article/details/61915471
2.背景
Android图片加载主要有四大框架,但是只有Fresco框架是可以支持渐进式加载(需要设置)
笔者是由于项目已经使用Glide,且跟换框架成本太大,所以才尝试用Glide实现渐进式加载,但是Glide本身框架目前是不适合做渐进式加载,里面的请求是将整个InputStream转化为bitmap后才通过回调设置给ImageView,这个过程只能走一次.笔者做了很多尝试来让Glide实现渐进式加载,虽然最后实现了这个功能,但是会破坏Glide的结构,影响内部的一些优化和设置,比如缓存和防止错位等,所以这里就不介绍这个实现过程了,但是在这个过程中,使用到一些实现渐进式加载的操作,可以介绍一下.
3.实现
首先我们定义一个类,来通过网络请求来获取InputStream
(HttpUrlFetcher是glide里面的一个实现类,这里将里面的代码简化一下,拿来使用)
//HttpUrlFetcher.javapublic class HttpUrlFetcher { private static final String TAG = "HttpUrlFetcher"; private HttpURLConnection urlConnection; private int size; public int getSize() { return size; } public InputStream loadData(URL url) throws IOException { urlConnection = (HttpURLConnection) url.openConnection(); urlConnection.setConnectTimeout(2500); urlConnection.setReadTimeout(2500); urlConnection.setUseCaches(false); urlConnection.setDoInput(true); size = urlConnection.getContentLength(); final int statusCode = urlConnection.getResponseCode(); if (statusCode / 100 == 2) { return urlConnection.getInputStream(); } return null; }}
找到控件和设置图片链接(此链接的图片是支持渐进式加载的JPEG图片)
//MainActivity url = "http://www.reasoft.com/tutorials/web/img/progress.jpg"; iv1 = (ImageView) findViewById(R.id.iv1);
在子线程中请求网络并实现渐进式加载
//MainActivity.javapublic void show(View v) { isCancel = false; new Thread(new Runnable() { @Override public void run() { try { //网络请求 InputStream inputStream = httpUrl.loadData(new URL(url)); //创建一个和总数据一样大的数组来当容器 byte[] bytes = new byte[httpUrl.getSize()]; byte lastOne = 0; byte lastTwo = 0; int offest = 0; while (!isCancel) { //本次读取的字节 byte[] get = getBytes(inputStream); //放入本次读取的数据 System.arraycopy(get, 0, bytes, offest, get.length); offest = offest + get.length; //记录最后两位字符 lastOne = bytes[offest - 1]; lastTwo = bytes[offest - 2]; //替换掉最后两个字节为FFD9,否则无法转化成bitmap bytes[offest - 2] = -1; bytes[offest - 1] = -39; //生成bitmap Bitmap result = BitmapFactory.decodeByteArray(bytes, 0, offest); //还原最后两个字节 bytes[offest - 2] = lastTwo; bytes[offest - 1] = lastOne; Message obtain = Message.obtain(); Bundle bundle = new Bundle(); bundle.putParcelable(BITMAP, result); obtain.setData(bundle); handler.sendMessage(obtain); } } catch (IOException e) { e.printStackTrace(); } } }).start();}
//MainActivity.javaprivate Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); Bitmap bitmap = msg.getData().getParcelable(BITMAP); if (bitmap != null) { iv1.setImageBitmap(bitmap); } }};
//MainActivity.javapublic static byte[] getBytes(InputStream is) throws IOException { ByteArrayOutputStream outstream = new ByteArrayOutputStream(); //这里设置每次读取的数量,设置小一点是为了让效果更明显 byte[] buffer = new byte[10]; // 用数据装 int len = -1; //要实现比较理想的渐进式加载效果,其实不应该写死每次读取量,应该是根据FFDA来判断读到第几帧了,然后决定是否需要显示了 if ((len = is.read(buffer)) != -1) { outstream.write(buffer, 0, len); } else { is.close(); } outstream.close(); // 关闭流一定要记得。 return outstream.toByteArray();}
这里有几个地方要注意的 :
- 1.BitmapFactory.decodeByteArray方法读取的字节数组,jpg文件开头得是FFD8,结尾得是FFD9,不然的话会返回null,所以这边在每次解析的时候都将最后两位临时换成FFD9
- 2.这里 FF D9是十六进制的,需要转换为二进制,并且取补码,最后的字节是 -1,-39
- 3.记得增加网络权限
4.其他
本节代码很多地方写得不严禁,效率也不高,目的主要是介绍如何实现渐进式加载.但是笔者认为java在处理这类情况时,其实本身效率并不高,在实际项目使用中,如果对性能要求比较高的话,这类操作还是用C语言等底层来写,Android只是通过JNI来调用,这样更加合理和高效.
5.0 Demo源码
Demo
https://github.com/yulyu2008/ProgressiveDemo
热门文章
- Glide-源码详解
- 渐进式加载-基础讲解
- 活用productFlavors
- onTouch事件传递
- 那些年我们解决滑动冲突时遇过的坑
- 进程间通信–AIDL
- 序列化–Serializable与Parcelable
- 如何解决内存溢出以及内存泄漏
- Okhttputils终极封装
- FaceBook推出的调试神器
- Android代码优化工具
- Glide-入门教程
- Glide-图片预处理(圆角,高斯模糊等)
- Glide-图片的压缩
- Glide-内存缓存与磁盘缓存
- Glide-自定义缓存
- Glide-渐进式加载初尝试
- 渐进式的脚本加载
- 渐进式加载-基础讲解
- 渐进式加载-基础讲解
- Glide初体验,加载网络图片
- imageIO完成渐进加载图片
- imageIO完成渐进加载图片
- imageIO完成渐进加载图片
- imageIO---完成渐进加载图片
- 图片加载库Glide
- Android Glide 图片加载
- Glide加载图片
- 图片加载库Glide
- 图片加载库Glide
- Glide动画加载
- glide 加载大图
- 图片加载框架Glide
- Glide图片加载
- 访问HBase遇到java.lang.OutOfMemoryError: unable to create new native thread的解决方法
- genymotion导入虚拟机镜像
- 什么是面向对象
- jquery-ui中div拖动出现辅助线方便对齐
- OpenCV_(Using GrabCut extract the foreground object) 使用 GrabCut 算法提取前景物体
- Glide-渐进式加载初尝试
- Q86:镜面反射(Mirror Reflection)
- Android测试(一)
- BZOJ 1857:[scoi2010] 传送带
- 零基础学习JAVA—GPS数据处理
- 正则表达式 ?= 、?!
- android arr和jar的区别
- ServiceStack.Redis的使用以及Redis的数据类型
- crontab简易入门