[douban] 03_我读-ListView优化2-ListView中的图片优化(异步加载,内存缓存图片-软引用)

Android 4.0

ListView中的图片优化(异步加载,内存缓存图片-软引用)
软引用-SoftReference

1、定义软引用 
/**
 * key:图片的名字
 * value:软引用的bitmap
 */
private Map<String, SoftReference<Bitmap>> iconCacheMap;
2、初始化 
iconCacheMap = new HashMap<String, SoftReference<Bitmap>>();
3、使用 
/**
 * listview数据填充类
 */
private class MyReadAdapter extends BaseAdapter {
    private final List<Book> books;
    public MyReadAdapter(List<Book> books) {
        this.books = books;
    }
    @Override
    public int getCount() {
        return books.size();
    }
    @Override
    public Object getItem(int position) {
        return books.get(position);
    }
    @Override
    public long getItemId(int position) {
        return position;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (convertView != null && convertView instanceof LinearLayout) {
            holder = (ViewHolder) convertView.getTag();
        } else {
            holder = new ViewHolder();
            convertView = View.inflate(MyReadActivity.this,R.layout.book_itemnull);
            //holder.ivBbook = (ImageView) convertView.findViewById(R.id.book_img);
            holder.tvTitle = (TextView) convertView.findViewById(R.id.book_title);
            holder.tvDescription = (TextView) convertView.findViewById(R.id.book_description);
            holder.rbRate =  (RatingBar) convertView.findViewById(R.id.ratingbar);
            convertView.setTag(holder);
        }
        Book book = books.get(position);
        // 书名
        holder.tvTitle.setText(book.getName());
        // 书的描述
        holder.tvDescription.setText(book.getDescription());
        // 书的评价
        if (book.getRating() != 0) {
            holder.rbRate.setRating(book.getRating());
        } else {
            holder.rbRate.setVisibility(View.INVISIBLE);
        }
        
        // 书的图片-图片的异步加载
        final ImageView ivBbook = (ImageView) convertView.findViewById(R.id.book_img);
        
        String filePath = book.getBookurl();
        // 获得文件名
        final String fileName = filePath.substring(filePath.lastIndexOf("/") + 1, filePath.length());
        
//            1、图片保存在sd卡上,从sd卡上获取            
//            // 判断是否在sd卡有该图片
//            String storageState = Environment.getExternalStorageState();
//            File file = null;
//            if (Environment.MEDIA_MOUNTED.equals(storageState)) {
//                 file = new File(Environment.getExternalStorageDirectory(),fileName);
//            }
//            if (file != null && file.exists()) {// /图片在sd卡有保存
//                ivBbook.setImageURI(Uri.fromFile(file));
//                Log.i(TAG, "从sd卡获取图片:" + fileName);
//            } else {// 图片文件不在sk卡保存
//                loadImage(ivBbook, filePath, fileName);
//            }
        
//            2、图片保存在内存中,从内存中获取            
        if (iconCacheMap.containsKey(fileName)) {
            SoftReference<Bitmap> reference = iconCacheMap.get(fileName);
            if (reference != null) {
                Bitmap bitmap = reference.get();
                if (bitmap != null) {// 内存中该bitmap的缓存还没有被gc回收,那么复用
                    ivBbook.setImageBitmap(bitmap);
                    Log.i(TAG"从内存中获取图片" + fileName);
                } else {
                    loadImage(ivBbook, filePath, fileName);
                }
            }
        } else {
            loadImage(ivBbook, filePath, fileName);
        }
        
        return convertView;
    }
    /**
     * 异步获取图片
     * 
     * @param ivBbook
     * @param filePath
     * @param fileName
     */
    private void loadImage(final ImageView ivBbook, String filePath,
            final String fileName) {
        new LoadImageAsynTask<String, Void, Bitmap>(new LoadImageAsynTaskCallback<Bitmap>() {
            
            @Override
            public void beforeLoadImage() {
                ivBbook.setImageResource(R.drawable.ic_launcher);
            }
            
            @Override
            public void afterLoadImage(Bitmap bitmap) {
                if (bitmap!=null) {
                    Log.i(TAG"从服务器上下载图片"+fileName);
                    ivBbook.setImageBitmap(bitmap);
//                        //1、保存bitmap到sd卡上                        
//                        try {
//
//                            //判断sd卡状态
//                            String storageState = Environment.getExternalStorageState();
//                            File file = null;
//                            if (Environment.MEDIA_MOUNTED.equals(storageState)) {
//                                file = new File(Environment.getExternalStorageDirectory(),fileName);
//                            }else {
//                                return;
//                            }
//                            CompressFormat format = CompressFormat.JPEG;
//                            int quality = 100;//100无损保存
//                            OutputStream stream = new FileOutputStream(file);
//                            boolean b = bitmap.compress(format , quality , stream );
//                            Log.i(TAG, "保存图片"+fileName+"到sd卡:"+b);
//                        } catch (FileNotFoundException e) {
//                            e.printStackTrace();
//                        }
                    //2、保存到内存-软引用
                    SoftReference<Bitmap> value = new SoftReference<Bitmap>(bitmap);
                    iconCacheMap.put(fileName, value);
                    Log.i(TAG"保存图片"+fileName+"到内存");
                }else {
                    ivBbook.setImageResource(R.drawable.ic_launcher);
                }
            }
        }){
            
            @Override
            protected Bitmap doInBackground(String... params) {
                try {
                    URL url = new URL(params[0]);
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    InputStream is = conn.getInputStream();
                    Bitmap bitmap = BitmapFactory.decodeStream(is);
                    return bitmap;
                } catch (Exception e) {
                    e.printStackTrace();
                    return null;
                }
            }
            
        }.execute(filePath);
    }
}
结果: