您的位置:首页 > 移动开发 > Android开发

Android分析加载图片

2014-08-26 23:41 141 查看

一、ListView加载图片

1)Android加载图片的几种方式
缓存、SDCard、网络

二、ListView自身优化

1》当快速滑动时不去加载图片。

方案一:
异步下载图片,我每页有20条,也就是20张图片,会导致listview滑动卡顿!
了解 public void onScrollStateChanged(AbsListView view, int scrollState)
方法////list停止滚动时加载图片

pageImgLoad(_start_index, _end_index);
//分页
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount)
方案二:

通过listview中传入的参数去判断滑动的速度。
如果速度达到一个临界值,是不需要去加载图片的;如果没有则需要去加载图片。

方案三:

慢的话:
有个延迟加载数据的方法,在API的demo中。

要是让ListView滚动速度快的话,你可以这样告诉他:

让他的手指在屏幕上迅速的上下滑动,当他的手指移动速度达到100px/0.1秒后,就可以看到快速滑动的效果了!~

方案四:

ListView的右边滚动滑块启用方法?                      很多开发者不知道ListView列表控件的快速滚动滑块是如何启用的,其实辅助滚动滑块只需要一行代码就可以搞定,如果你使用XML布局只需要在ListView节点中加入  android:fastScrollEnabled="true" 这个属性即可,而对于Java代码可以通过myListView.setFastScrollEnabled(true); 来控制启用,参数false为隐藏。                      还有一点就是当你的滚动内容较小,不到当前ListView的3个屏幕高度时则不会出现这个快速滚动滑块,该方法是AbsListView的基础方法,可以在ListView或GridView等子类中使用快速滚动辅助。


三、加载的图片优化

简单的查看listview中的自带的缓存机制,当我们把第一屏显示的条目加载完成以后,listview中getView方法会缓存一些条目。同时我们在getView方法中尽量减少
findViewById()的次数,findViewById()是一个耗时的操作,因为这个操作需要每次到布局文件中查找文件。一般我们使用holder来达到软引用的效果,同时复用View信息。
在一般的系统应用源码中在首次加载应用的时候就开始把主要的程序先启动或者先获得对象并进行布局。
我们自己一般喜欢把数据加载到内存里面,在处理数据的时候,直接从内存中取出。

系统应用有一个Gallery,Gallery对图片的大小进行了优化.

方法一、

①在加载图片之前使用BitmapFactory.Options options = new BitmapFactory.Options();

//将options.inJustDecodeBounds设置为true;这样不会去解析图片,只解析边界,即宽高

②BitmapFactory.decodeFile(jpgPath,
options);

③读出图片的真实高度

④如果图片的真实宽高都小于设置的临界值,则需要使用真实的宽高

方法二、

方法一在一定程度上牺牲的图片的质量,但可以避免OOM Error。

当Android设备中较大图片时,可以创建一个临时空间,将载入的资源放到临时空间。

bfOptions.inTempStorage=newbyte[
12
*
1024
];//创建了一个12kbde临时空间


一般我们喜欢在静态方法中
static {

mOptions.inDither = false;// 设置为false,将不考虑图片的抖动值,这会减少图片的内存占用

mOptions.inPurgeable = true;// 设置为ture,表示允许系统在内存不足时,删除bitmap的数组。

mOptions.inInputShareable = true;// 和inPurgeable配合使用,如果inPurgeable是false,那么该参数将被忽略,表示是否对bitmap的数组进行共享

}

方法三、
我们可以再getView方法中给ImageView设置图片时,使用LruCache先到imageUrl存入缓存,同时在listview中设置bitmap,如果通过imageCache取不到bitmap
就从新从网络获取图片。
Android提供的LruCache类简介

LRUCache
当ListView加载了某些图片被系统回收以后,用户再次滑入屏幕这种情况。这时重新去加载一遍刚刚加载
过的图片无疑使性能的瓶颈,这时我们可以使用LRUCache对图片进行缓存或者其他优化。
LruCache类在Android-support-v4的包中提供,这个类非常适合缓存图片,他的主要算法原理是把最近使用的对象
用强引用存储在LinkedHashMap中,并且把最近最少使用的对象在缓存值达到设定值之前从内存中移除。

如何选择合适的缓存大小给LruCache?
1》你的设备可以为每一个应用程序分配多大的内存?
2》设备屏幕上一次最多能显示多少张图片?有多少图片需要进行预加载,因为
有可能很快也会显示在屏幕上?
3》图片的尺寸和大小,还有每张图片占据多少内存空间?
4》图片被访问的频率有多高?

对LruCache的使用案例:
//获取到可用内存的最大值,使用内存超出这个值会引起OutOfMemory异常。
//LruCache通过构造函数传入缓存值,以kb为单位
int maxMemory = (int) (Runtime.getRuntime.maxMemory()/1024);
//使用最大可用内存值的1/8作为缓存的大小。
//复写LruCache中的sizeOf()方法 默认返回图片数量
//当向 ImageView 中加载一张图片时,首先会在 LruCache 的缓存中进行检查。如果找到了相应的键值,则会立刻更新ImageView ,否则开启一个后台线程来加载这张图片。

四、特殊复杂布局的特殊处理

五、ImageLoad加载

1)加载图片
①先判断view是否为null,同时url不能为null
②先判断view是否为null,把控件和图片的url进行绑定,因为加载是一个耗时的操作,等加载完毕了需要判定该控件是否和url匹配.
③从内存加载图片(loadFromMemory(url))
/*内存加载图片*/
public static  Drawable  loadFromMemory(String url){
Drawable  drawable = mDrawableCache.get(url);
if(drawable!=null){
//从内存中获取到了,需要重新放到内存队列的最后,以便满足LRC
//一般缓存算法有两种,第一是LFU,按使用次数判定删除优先级,使用次数最少的最先删除
//还有一个就是LRC,就是按最后使用时间来判定删除的优先级,最后使用时间越早最先删除
mKeyCache.remove(url);
mDrawableCache.remove(url);
//如果大于等于100张,或者图片的总大小大于应用总内存的四分之一先删除前面的
}
}


// mKeyCache.add(url);//添加 mDrawableCache.put(url,drawable); mTotalSize += DrawableUtils.getDrawableSize(drawable); }}

④从内存读取到了Drawable后;如果内存中加载到了,直接设置图片
⑤从内存中没有读取到;(设置默认图片)从网络加载,并异步加载.
⑥异步加载
//创建一个Runnable封装执行过程
//先从本地设备中加载
一、根据路径采取流程的形式读取进来,
二、把读取到图片放入缓冲中
//从网络加载图片
一、把网络下载保存到本地
二、关闭网络
三、进行改名
四、从本地加载

六、处理实际开发遇到的问题

一、图标错位了
①在load图片是把url设置到tag中
②保存到缓存中时,取出ImageView中的tag,然后判断tag中的url和传入的url是否一致
③因为第一次加载图片的时候,我们设置了url,在我们滑动listView的时候,
复用image时候,传入的url有可能是复用的url,导致这两个url不相同。----》同时出现了图片的错位的现象

总结的思维导图
http://download.csdn.net/detail/javamov/7853751
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: