1

我正在使用ImageLoader获取AlbumArtAndroid 设备中可用歌曲的图像。我知道我也可以AlbumArt从音乐应用程序的某些方法中获取,OpenSource但我不喜欢用ImageLoader.

这是我的 ImageLoader 类的代码:

public class ImageLoader {
    MemoryCache memoryCache=new MemoryCache();
    FileCache fileCache;
    private Map<ImageView, String> imageViews=Collections.synchronizedMap(new WeakHashMap<ImageView, String>());
    ExecutorService executorService;
    Handler handler=new Handler();//handler to display images in UI thread
    private Context mContext;
    private static final Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");

    public ImageLoader(Context context){
        fileCache=new FileCache(context);
        executorService=Executors.newFixedThreadPool(5);
        this.mContext = context;
    }

    final int stub_id = R.drawable.ic_launcher;
    public void DisplayImage(String url, ImageView imageView)
    {
        imageViews.put(imageView, url);
        Bitmap bitmap=memoryCache.get(url);
        System.out.println("CATCH url is:"+ url);
        if(bitmap!=null){
            System.out.println("GOT IMAGE FROM CATCH..............");
            imageView.setImageBitmap(bitmap);
        }
        else
        {
            queuePhoto(url, imageView);
            imageView.setImageResource(stub_id);
        }
    }

    private void queuePhoto(String url, ImageView imageView)
    {
        PhotoToLoad p=new PhotoToLoad(url, imageView);
        executorService.submit(new PhotosLoader(p));
    }

    private Bitmap getBitmap(String url) 
    {
        File f=fileCache.getFile(url);

        //from SD cache
        Bitmap b = decodeFile(f);
        if(b!=null)
            return b;
        System.out.println("bitmap is: "+b);
        //from web
        try {
            Bitmap bitmap=null;

            //URI u = new URI(url);

            Uri uri = ContentUris.withAppendedId(sArtworkUri, Long.valueOf(url));
            ParcelFileDescriptor pfd = mContext.getContentResolver().openFileDescriptor(uri, "r");
            if (pfd != null) {
                FileDescriptor fd = pfd.getFileDescriptor();
                bitmap = BitmapFactory.decodeFileDescriptor(fd);
            }else{
                System.out.println("IN ELSE PART...");
                bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.ic_launcher);
            }

           /* Uri u = Uri.parse("content://media/external/audio/albumart/"+url);
            String imagePath = u.getPath();
            System.out.println("Hello..."+ imagePath);
            bitmap = decodeSampledBitmapFromResource(imagePath, 100, 100); */
            //targetImage.setImageBitmap(bitmap);  


           /* URL imageUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
            conn.setConnectTimeout(30000);
            conn.setReadTimeout(30000);
            conn.setInstanceFollowRedirects(true);
            InputStream is=conn.getInputStream();
            OutputStream os = new FileOutputStream(f);
            Utils.CopyStream(is, os);
            os.close();
            conn.disconnect();
            bitmap = decodeFile(f);*/
            return bitmap;
        } catch (Throwable ex){
           //ex.printStackTrace();
           //System.out.println("NOT GETTING IMAGE");
           if(ex instanceof OutOfMemoryError)
               memoryCache.clear();
           return null;
        }
    }

    //decodes image and scales it to reduce memory consumption
    private Bitmap decodeFile(File f){


        try {
            System.out.println("DECODING FILE");
            //decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            FileInputStream stream1=new FileInputStream(f);
            BitmapFactory.decodeStream(stream1,null,o);
            stream1.close();

            //Find the correct scale value. It should be the power of 2.
            final int REQUIRED_SIZE=70;
            int width_tmp=o.outWidth, height_tmp=o.outHeight;
            int scale=1;
            while(true){
                if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE)
                    break;
                width_tmp/=2;
                height_tmp/=2;
                scale*=2;
            }

            //decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize=scale;
            FileInputStream stream2=new FileInputStream(f);
            Bitmap bitmap=BitmapFactory.decodeStream(stream2, null, o2);
            stream2.close();
            return bitmap;
        } catch (FileNotFoundException e) {
        } 
        catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    //Task for the queue
    private class PhotoToLoad
    {
        public String url;
        public ImageView imageView;
        public PhotoToLoad(String u, ImageView i){
            url=u; 
            imageView=i;
        }
    }

    class PhotosLoader implements Runnable {
        PhotoToLoad photoToLoad;
        PhotosLoader(PhotoToLoad photoToLoad){
            this.photoToLoad=photoToLoad;
        }

        @Override
        public void run() {
            try{
                if(imageViewReused(photoToLoad))
                    return;
                Bitmap bmp=getBitmap(photoToLoad.url); // here it is made in to Bitmap
                memoryCache.put(photoToLoad.url, bmp);
                if(imageViewReused(photoToLoad))
                    return;
                BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad);
                handler.post(bd);
            }catch(Throwable th){
                th.printStackTrace();
            }
        }
    }

    boolean imageViewReused(PhotoToLoad photoToLoad){
        String tag=imageViews.get(photoToLoad.imageView);
        if(tag==null || !tag.equals(photoToLoad.url))
            return true;
        return false;
    }

    //Used to display bitmap in the UI thread
    class BitmapDisplayer implements Runnable
    {
        Bitmap bitmap;
        PhotoToLoad photoToLoad;
        public BitmapDisplayer(Bitmap b, PhotoToLoad p){bitmap=b;photoToLoad=p;}
        public void run()
        {
            if(imageViewReused(photoToLoad))
                return;
            if(bitmap!=null)
                photoToLoad.imageView.setImageBitmap(bitmap);
            else
                photoToLoad.imageView.setImageResource(stub_id);
        }
    }

    public void clearCache() {
        memoryCache.clear();
        fileCache.clear();
    }
    public static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            // Calculate ratios of height and width to requested height and width
            final int heightRatio = Math.round((float) height / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);

            // Choose the smallest ratio as inSampleSize value, this will guarantee
            // a final image with both dimensions larger than or equal to the
            // requested height and width.
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }
        return inSampleSize;
    }

    public static Bitmap decodeSampledBitmapFromResource(String pathName,
            int reqWidth, int reqHeight) {

        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        //BitmapFactory.decodeResource(res, resId, options);
        System.out.println("Before Decode");
        BitmapFactory.decodeFile(pathName, options);
        System.out.println("After Decode");

        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;


        //return BitmapFactory.decodeResource(res, resId, options);
        return BitmapFactory.decodeFile(pathName, options);

    }
    public String getRealPathFromURI(Uri contentUri) {
        String[] proj = { MediaStore.Images.Media.DATA };
        Cursor cursor = mContext.getContentResolver().query(contentUri, proj, null, null, null);

        if (cursor == null)
            return null;

        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);

        cursor.moveToFirst();

        return cursor.getString(column_index);
    }
}

这是我的 SimpleCursorAdapter 的 bindView 方法

@Override
public void bindView(View v, final Context context, Cursor c) {

    // MediaStore.Audio.Albums.ALBUM ,MediaStore.Audio.Albums.ARTIST,
    // MediaStore.Audio.Albums.LAST_YEAR

    final ViewHolder holder = (ViewHolder) v.getTag();
    imageLoader = new ImageLoader(context);

    holder.titleName.setText(c.getString(c
            .getColumnIndex(MediaStore.Audio.Albums.ALBUM)));
    holder.artistName.setText(c.getString(c
            .getColumnIndex(MediaStore.Audio.Albums.ARTIST)));
    holder.year
            .setText("Total Songs: "
                    + c.getString(c
                            .getColumnIndex(MediaStore.Audio.Albums.NUMBER_OF_SONGS)));

    String name = c.getString(mAlbumIdx);
    String displayname = name;
    boolean unknown = name == null
            || name.equals(MediaStore.UNKNOWN_STRING);
    if (unknown) {
        displayname = mUnknownAlbum;
    }

    String art = c.getString(mAlbumArtIndex);
    final long aid = c.getLong(0);
    holder.trackImage.setImageDrawable(null);

    if (unknown || art == null || art.length() == 0) {
        // System.out.println();
        holder.trackImage.setImageResource(R.drawable.ic_launcher);
    } else {
        final long i = c.getLong(c
                .getColumnIndexOrThrow(MediaStore.Audio.Albums._ID));

        System.out.println("ALBUM ID IS: " + i);
        System.out.println("ALBUM NAME IS: " + displayname);

        new Handler().post(new Runnable() {
            @Override
            public void run() {
                 holder.trackImage.setTag(String.valueOf(i));
                 imageLoader.DisplayImage(String.valueOf(i) ,
                 holder.trackImage);
            }
        });
    }
}

但是我得到了位图,但是每次当用户滚动listview. 即使我无法在LazyList. 我有手动检查它。

所以,请帮助我。为什么我无法捕捉位图。这段ImageLoader代码有什么问题?

4

0 回答 0