当前位置:编程学习 > wap >>

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、

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;
    }
}
Android 图片缓存 --------------------编程问答-------------------- 4、

/**
 * 这是一个封装好的异步加载图片类,缓存了两份,
 * 一份是使用软引用缓存到内存中,
 * 一份是缓存到本地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" />
    <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里面解大图片经常溢出,可以通过先判断图片大小,再设置Options.inSampleSize解决,developer.android.com上面有介绍 --------------------编程问答-------------------- 可以我发现经常是分辨率比较小的图片没有显示出来啊,大的都显示出来了 --------------------编程问答--------------------
引用 4 楼 youngc527 的回复:
代码太长没细看,从你的描述来看,你可以看看是不是内存溢出了。在android里面解大图片经常溢出,可以通过先判断图片大小,再设置Options.inSampleSize解决,developer.android.com上面有介绍

可以我发现经常是分辨率比较小的图片没有显示出来啊,大的都显示出来了 --------------------编程问答-------------------- 除 --------------------编程问答-------------------- 你给图片换个位置 不就知道 和分辨率有没有关系了
补充:移动开发 ,  Android
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,