android 在进行图片缓存过程中部分图片无法显示!!!
项目运行结果:MainActivity中的前两图能够显示,后面两图不能显示!!!
搞了很久搞不明白,不知道跟图片分辨率有没有关系
下面贴出项目主要代码,跪求大拿给个解决方案~~~
1、缓存主要代码
public class AsyncBitmapLoader
{
/**
*内存图片软引用缓冲
*/
private HashMap<String, SoftReference<Bitmap>> imageCache = null;
/**
* 图片缓存时间
*/
private static final int DELETE_TIME_INTERVAL = 1000 * 60/* * 60 * 24 * 10*/;
private static File cacheDir;
public AsyncBitmapLoader()
{
imageCache = new HashMap<String, SoftReference<Bitmap>>();
}
public void clear()
{
cacheDir = null;
if (imageCache != null)
{
try
{
releaseBitmapCache();
}
catch (Exception e)
{
}
imageCache.clear();
System.gc();
}
}
public void releaseBitmapCache()
{
if (imageCache != null)
{
for (Entry<String, SoftReference<Bitmap>> entry : imageCache
.entrySet())
{
Bitmap bitmap = entry.getValue().get();
if (bitmap != null)
{
// System.out.println(" bitmap.recycle() "+bitmap);
// bitmap.recycle();// 释放bitmap对象
bitmap = null;
}
}
// System.out.println(" >>>>>>>>>>>>>> size " + imageCache.size());
// Set set = imageCache.entrySet();
// Iterator it = set.iterator();
// while (it.hasNext())
// {
// SoftReference<Bitmap> reference = (SoftReference<Bitmap>) it.next();
//
// System.out.println(" >>>>>>>>>>>>>> " + reference.get());
//// reference.get().recycle();
// }
}
}
//判断是否有缓存的图片,有则取缓存,没就开启线程下载
public Bitmap loadBitmap(final ImageView imageView, final String imageURL,
final ImageCallBack imageCallBack)
{
//有缓存
if (imageCache.containsKey(imageURL))
{
SoftReference<Bitmap> reference = imageCache.get(imageURL);
Bitmap bitmap = reference.get();
if (bitmap != null)
{
return bitmap;
}
}
else
{
/**
*加上一个对本地缓存的查找
*/
String bitmapName = imageURL
.substring(imageURL.lastIndexOf("/") + 1);
File cacheDir = new File("/mnt/sdcard/LoadImgTest/");
File[] cacheFiles = cacheDir.listFiles();
int i = 0;
if (null != cacheFiles)
{
for (; i < cacheFiles.length; i++)
{
if (bitmapName.equals(cacheFiles[i].getName()))
{
break;
}
}
if (i < cacheFiles.length)
{
Bitmap bitmap = BitmapFactory
.decodeFile("/mnt/sdcard/LoadImgTest/"
+ bitmapName);
return bitmap;
}
}
}
final Handler handler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
imageCallBack.imageLoad(imageView, (Bitmap) msg.obj);
}
};
//如果不在内存缓存中,也不在本地(被jvm回收掉),则开启线程下载图片
new Thread()
{
@Override
public void run()
{
InputStream bitmapIs = HttpUtils.getStreamFromURL(imageURL);
Bitmap bitmap = BitmapFactory.decodeStream(bitmapIs);
if (bitmap == null)
{
return;
}
imageCache.put(imageURL, new SoftReference<Bitmap>(bitmap));
Message msg = handler.obtainMessage(0, bitmap);
handler.sendMessage(msg);
// File dir = new File("/mnt/sdcard/ShidaokeImageCash/");
// if (!dir.exists())
// {
// dir.mkdirs();
// }
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED))
{ //sdcard
cacheDir = new File(
Environment.getExternalStorageDirectory(),
"LoadImgTest");
}
if (cacheDir != null && !cacheDir.exists())
{
cacheDir.mkdirs();
}
// if (!dir.exists())
// {
// dir.mkdirs();
// }
File bitmapFile = new File("/mnt/sdcard/LoadImgTest/"
+ imageURL.substring(imageURL.lastIndexOf("/") + 1));
if (!bitmapFile.exists())
{
try
{
bitmapFile.createNewFile();
}
catch (Exception e)
{
System.out.println(" loadBitmap e" + e.toString());
}
}
FileOutputStream fos;
try
{
fos = new FileOutputStream(bitmapFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.close();
}
catch (Exception e)
{
System.out.println(" loadBitmap exc " + e.toString());
}
}
}.start();
return null;
}
public interface ImageCallBack
{
public void imageLoad(ImageView imageView, Bitmap bitmap);
}
public void checkImageCache()
{
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED))
{ //sdcard
cacheDir = new File(Environment.getExternalStorageDirectory(),
"LoadImgTest");
}
if (cacheDir.isDirectory())
{
clearSdcardCache();//清除缓存数据
}
}
/**
* 清除图片
*/
private static void clearSdcardCache()
{
File[] files = cacheDir.listFiles();
long currentTime = System.currentTimeMillis();
if (files == null)
{
return;
}
for (File file : files)
{
if (currentTime - file.lastModified() > DELETE_TIME_INTERVAL)
{
file.delete();
continue;
}
}
}
}
2、activity
public class MainActivity extends Activity
{
private ListView listView;
private List<String> imgs=new ArrayList<String>();
private ImgAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initListview();
}
private void initListview()
{
String[] img = {
"http://b.tengw.cn/upload/min/137/137223191334818540.jpg",
"http://b.tengw.cn/upload/min/193/13726011398415954.jpg",
"http://b.tengw.cn/upload/min/158/137271814094517154.jpg",
"http://b.tengw.cn/upload/min/190/137271767475117154.jpg",
};
for (int i = 0; i < img.length; i++)
{
imgs.add(img[i]);
}
listView = (ListView) findViewById(R.id.listview);
adapter = new ImgAdapter(getApplication(), imgs);
listView.setAdapter(adapter);
}
}
3、
Android 图片缓存 --------------------编程问答-------------------- 4、
public class ImgAdapter extends BaseAdapter
{
private Context context;
private List<String> imgs;
private LayoutInflater inflater;
private Bitmap bitmap;
public ImgAdapter(Context context, List<String> imgs)
{
super();
this.context = context;
this.imgs = imgs;
inflater = LayoutInflater.from(context);
}
@Override
public int getCount()
{
return imgs.size();
}
@Override
public Object getItem(int position)
{
return imgs.get(position);
}
@Override
public long getItemId(int position)
{
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder vh;
if (convertView == null)
{
vh = new ViewHolder();
convertView = inflater.inflate(R.layout.item, null);
vh.img = (ImageView) convertView.findViewById(R.id.img);
convertView.setTag(vh);
}
else
{
vh = (ViewHolder) convertView.getTag();
}
bitmap = new AsyncBitmapLoader().loadBitmap(vh.img, imgs.get(position),
new ImageCallBack()
{
@Override
public void imageLoad(ImageView imageView, Bitmap bitmap)
{
imageView.setImageBitmap(bitmap);
}
});
if (bitmap == null)
{
vh.img.setImageBitmap(null);
}
else
{
vh.img.setImageBitmap(bitmap);
}
return convertView;
}
private class ViewHolder
{
ImageView img;
}
}
/**
* 这是一个封装好的异步加载图片类,缓存了两份,
* 一份是使用软引用缓存到内存中,
* 一份是缓存到本地sd卡,
* 如果内存中没有,则从本地查找,如果本地没有则从网络获取图片。
* @author tengwang-sl
*
*/
public class HttpUtils
{
public static InputStream getStreamFromURL(String imageURL)
{
InputStream in = null;
try
{
URL url = new URL(imageURL);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
in = connection.getInputStream();
}
catch (Exception e)
{
}
return in;
}
}
5、布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/img_bg"
android:orientation="vertical" >
<ImageView
android:id="@+id/img"
android:layout_width="200dp"
android:layout_height="200dp"/>
</LinearLayout>
--------------------编程问答-------------------- 6、权限
<uses-permission android:name="android.permission.INTERNET" />--------------------编程问答-------------------- 自己顶一个,没人恢复吗 --------------------编程问答-------------------- 代码太长没细看,从你的描述来看,你可以看看是不是内存溢出了。在android里面解大图片经常溢出,可以通过先判断图片大小,再设置Options.inSampleSize解决,developer.android.com上面有介绍 --------------------编程问答-------------------- 可以我发现经常是分辨率比较小的图片没有显示出来啊,大的都显示出来了 --------------------编程问答--------------------
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
可以我发现经常是分辨率比较小的图片没有显示出来啊,大的都显示出来了 --------------------编程问答-------------------- 除 --------------------编程问答-------------------- 你给图片换个位置 不就知道 和分辨率有没有关系了
补充:移动开发 , Android