Androidデバイスで利用可能な曲の画像ImageLoader
を取得するために使用しています。音楽アプリのいくつかのメソッドからAlbumArt
を取得できることも知っていますが、代わりに でロードするのが好きです。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
コードの何が問題なのですか?