ImageLoader加载图片问题:
UIL图片加载已经非常熟悉,已经知道的是采用的是两级缓存: 内存中和磁盘上
如果都没有则从网络下载.
缓存的依据: UIL根据图片的URI获取缓存在磁盘文件的MD5值,看起来一切都顺利成章.
然而,问题出现了:
当网络上同一路径下的图片换了内容而没有换名字的话就会出现问题了: 不管内容怎么换,还是加载之前的图片
从缓存的依据可以知道: 由于图片根据MD5已经在本地缓存,尽管换了内容,但是图片的路径没有变,自然MD5值亦不会变,
结果会被认为是同一样图片,进而从缓存中取图片而不是重新加载
同样的问题出现在对与本地图片的加载中:
loadImage(String uri,ImageWare imageware) 这个方法传入的参数为uri,一般情况下我们都是使用这个
方法来加载网络图片,然而他还可以加载本地的图片uri格式为: drawable://R.drawable.ic_launcher
实际上这个地方也会和网络加载一样出现同样的问题:
1. R.drawable的实际值是一个16进制的int值,这个值不是一成不变的,存在与R文件中,自动生成
2.当在res文件中添加新的元素时,对应的id就会有变化,如果之前做了缓存,那么这个时候可能会出错
假设之前图片image1根据id=0x0100做了缓存,又添加了一张图片image2,此时id发生变化,image1的id变为0x0101,image2的id变为0x0100,
在使用UIL加载图片的时候会发现,image2加载的也是image1,这个问题很好解释,因为md5值没有变,换了内容,但是缓存还在,因此会加载缓存中的图片
而由于image1的id发生了变化,所以缓存中还会再缓存一份image1的图片
此时缓存中缓存了两张图片,都是image1的缓存,只是名字不同而已.
android中的URI
一般情况下,直接通过setImageResource(int id)等来设置本地图片
也可以使用Uri来设置
以上三个scheme是在CP中定义的常量: 便是contentprovider中的uri的scheme的类型
在ImageView中有一个方法来设置图片setImageURI(Uri uri)
Uri localImageUri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE+"://"+
getResources().getResourcePackageName(R.drawable.icon)+"/"+
getResources().getResourceTypeName(R.drawable.icon)+"/"+
getResources().getResourceEntryName(R.drawable.icon));
ImageView image = (ImageView) findViewById(R.id.imageView1);
image.setImageURI(localImageUri);
URI文档介绍
A Uri object can be used to reference a resource in an APK file. The Uri should be one of the following formats:
android.resource://package_name/id_number
package_name
is your package name as listed in your AndroidManifest.xml. For examplecom.example.myapp
id_number
is the int form of the ID.Uri uri = Uri.parse("android.resource://com.example.myapp/" + R.raw.my_resource");
android.resource://package_name/type/name
package_name
is your package name as listed in your AndroidManifest.xml. For examplecom.example.myapp
type
is the string form of the resource type. For example, raw
or drawable
. name
is the string form of the resource name. That is, whatever the file name was in your res directory, without the type extension. The easiest way to construct this form is Uri uri = Uri.parse("android.resource://com.example.myapp/raw/my_resource");