Android 图像加载程序不加载图像

Android 图像加载程序不加载图像,android,image,Android,Image,嗨,我有一个图像加载器类,从网络上加载图像,并在手机上缓存。问题是 手机上没有sd卡(外部存储器)图像未从网络加载如何修复 下面是图像加载器类代码 public class ImageLoader { final int stub_id = R.drawable.ic_thumbnail; MemoryCache memoryCache = new MemoryCache(); FileCache fileCache; ExecutorService executorServ

嗨,我有一个图像加载器类,从网络上加载图像,并在手机上缓存。问题是 手机上没有sd卡(外部存储器)图像未从网络加载如何修复 下面是图像加载器类代码

 public class ImageLoader {

  final int stub_id = R.drawable.ic_thumbnail;
  MemoryCache memoryCache = new MemoryCache();
  FileCache fileCache;
  ExecutorService executorService;
  private Map<ImageView, String> imageViews = Collections.synchronizedMap(new WeakHashMap<ImageView, String>());

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

  public void DisplayImage(String url, ImageView imageView) {
  imageViews.put(imageView, url);
  Bitmap bitmap = memoryCache.get(url);
  if (bitmap != null)
  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;

  //from web
  try {
  Bitmap bitmap = null;
  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();
  bitmap = decodeFile(f);
  return bitmap;
  } catch (Exception ex) {
  ex.printStackTrace();
  return null;
  }
  }

  //decodes image and scales it to reduce memory consumption
  private Bitmap decodeFile(File f) {
  try {
  //decode image size
  BitmapFactory.Options o = new BitmapFactory.Options();
  o.inJustDecodeBounds = true;
  BitmapFactory.decodeStream(new FileInputStream(f), null, o);

  //Find the correct scale value. It should be the power of 2.
  final int REQUIRED_SIZE = 150;
  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;
  return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
  } catch (FileNotFoundException e) {
  }
  return null;
  }

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

  public void clearCache() {
  memoryCache.clear();
  fileCache.clear();
  }

  //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;
  }

  public void run() {
  if (imageViewReused(photoToLoad))
  return;
  Bitmap bmp = getBitmap(photoToLoad.url);
  memoryCache.put(photoToLoad.url, bmp);
  if (imageViewReused(photoToLoad))
  return;
  BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad);
  Activity a = (Activity) photoToLoad.imageView.getContext();
  a.runOnUiThread(bd);
  }
  }

  //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);
  }
  }

  }
公共类ImageLoader{
最终int stub_id=R.drawable.ic_缩略图;
MemoryCache MemoryCache=新的MemoryCache();
文件缓存文件缓存;
执行服务执行服务;
private Map ImageView=Collections.synchronizedMap(新的WeakHashMap());
公共图像加载器(上下文){
fileCache=新的fileCache(上下文);
executorService=Executors.newFixedThreadPool(5);
}
public void DisplayImage(字符串url,ImageView){
put(imageView,url);
位图位图=memoryCache.get(url);
if(位图!=null)
设置图像位图(位图);
否则{
队列照片(url、imageView);
setImageResource(存根id);
}
}
私有void队列照片(字符串url,ImageView){
PhotoToLoad p=新的PhotoToLoad(url,imageView);
executorService.submit(新的PhotoLoader(p));
}
私有位图getBitmap(字符串url){
文件f=fileCache.getFile(url);
//从SD缓存
位图b=解码文件(f);
如果(b!=null)
返回b;
//从网络
试一试{
位图=空;
URL imageUrl=新URL(URL);
HttpURLConnection conn=(HttpURLConnection)imageUrl.openConnection();
连接设置连接超时(30000);
连接设置读取超时(30000);
conn.setInstanceFollowRedirects(真);
InputStream is=conn.getInputStream();
OutputStream os=新文件OutputStream(f);
Utils.CopyStream(is,os);
os.close();
位图=解码文件(f);
返回位图;
}捕获(例外情况除外){
例如printStackTrace();
返回null;
}
}
//对图像进行解码和缩放以减少内存消耗
私有位图解码文件(文件f){
试一试{
//解码图像大小
BitmapFactory.Options o=新的BitmapFactory.Options();
o、 inJustDecodeBounds=true;
解码流(新的FileInputStream(f),null,o);
//找到正确的刻度值。它应该是2的幂。
所需的最终int_尺寸=150;
内部宽度=o.向外宽度,高度=o.向外高度;
int标度=1;
while(true){
如果(宽度\u tmp/2<所需尺寸| |高度\u tmp/2<所需尺寸)
打破
宽度_tmp/=2;
高度_tmp/=2;
比例*=2;
}
//用inSampleSize解码
BitmapFactory.Options o2=新的BitmapFactory.Options();
o2.inSampleSize=刻度;
返回BitmapFactory.decodeStream(新文件输入流(f),null,o2);
}catch(filenotfounde异常){
}
返回null;
}
布尔图像视图(PhotoToLoad PhotoToLoad){
String tag=imageViews.get(photoload.imageView);
if(tag==null | |!tag.equals(photoload.url))
返回true;
返回false;
}
公共void clearCache(){
memoryCache.clear();
fileCache.clear();
}
//队列的任务
私有类光电负载{
公共字符串url;
公共影像视图;
公共PhotoToLoad(字符串u,图像视图i){
url=u;
imageView=i;
}
}
类photoloader实现可运行{
光电负载光电负载;
PhotoLoader(PhotoToLoad PhotoToLoad){
this.photoToLoad=photoToLoad;
}
公开募捐{
if(图像视图重用(光电加载))
返回;
位图bmp=getBitmap(photoLoad.url);
memoryCache.put(photoload.url,bmp);
if(图像视图重用(光电加载))
返回;
BitmapDisplayer bd=新的BitmapDisplayer(bmp,photoToLoad);
活动a=(活动)photoToLoad.imageView.getContext();
a、 runOnUiThread(bd);
}
}
//用于在UI线程中显示位图
类BitmapDisplayer实现可运行{
位图;
光电负载光电负载;
公共位图显示器(位图b、PhotoToLoad p){
位图=b;
光电负载=p;
}
公开募捐{
if(图像视图重用(光电加载))
返回;
if(位图!=null){
photoToLoad.imageView.setImageBitmap(位图);
}//否则
//photoToLoad.imageView.setImageResource(存根id);
}
}
}

您可能希望使用LRU缓存,而且它的设置非常简单

final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);

// Use 1/8th of the available memory for this memory cache.
final int cacheSize = maxMemory / 8;

mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
   @Override
   protected int sizeOf(String key, Bitmap bitmap) {
      // The cache size will be measured in kilobytes rather than number of items.
      return bitmap.getByteCount() / 1024;
   }
};
public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
    if (getBitmapFromMemCache(key) == null) {
        mMemoryCache.put(key, bitmap);
    }
}

public Bitmap getBitmapFromMemCache(String key) {
    return mMemoryCache.get(key);
}
final int maxMemory=(int)(Runtime.getRuntime().maxMemory()/1024);
//将可用内存的1/8用于此内存缓存。
最终int cacheSize=maxMemory/8;
mMemoryCache=新的LruCache(缓存大小){
@凌驾
受保护的int-sizeOf(字符串键、位图){
//缓存大小将以KB为单位,而不是以项目数为单位。
返回bitmap.getByteCount()/1024;
}
};
public void addBitmapToMemoryCache(字符串键、位图){
if(getBitmapFromMemCache(key)==null){
mMemoryCache.put(键,位图);
}
}
公共位图getBitmapFromMemCache(字符串键){
返回mMemoryCache.get(key);
}
参考-


我强烈建议您使用像毕加索或glide这样的图像库,或像Volley这样的网络库,而不是编写自己的图像库。我使用了带有LRU缓存的Volley,效果很好。

谢谢,但我想编辑我的代码,不使用新库