import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Collections;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.foodshare.activity.R;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.ImageView;public class ImageLoader { MemoryCache memoryCache = new MemoryCache();
FileCache fileCache;
private Map<ImageView, String> imageViews = Collections.synchronizedMap(new WeakHashMap<ImageView, String>());
//线程池
ExecutorService executorService; public ImageLoader(Context context) {
fileCache = new FileCache(context);
executorService = Executors.newFixedThreadPool(5);
} final int stub_id = R.drawable.no_image; 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);
// 先从文件缓存中查找是否有
Bitmap b = null;
if (f != null && f.exists()){
b = decodeFile(f);
}
if (b != null) {
return b;
}
// 从网络指定的URL中下载图片
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;
}
} // 解码图像并且按比例缩放用来减少内存消耗
private Bitmap decodeFile(File f) {
try {
// 解码图像大小
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f), null, o); // 找到正确的刻度值,它应该是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;
} BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (FileNotFoundException e) {
}
return null;
} // 任务队列
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() {
if (imageViewReused(photoToLoad)) {
return;
}
Bitmap bmp = getBitmap(photoToLoad.url);
memoryCache.put(photoToLoad.url, bmp);
if (imageViewReused(photoToLoad)) {
return;
}
BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad);
// 更新的操作放在UI线程中
Activity a = (Activity) photoToLoad.imageView.getContext();
a.runOnUiThread(bd);
}
} //防止图片错位
boolean imageViewReused(PhotoToLoad photoToLoad) {
String tag = imageViews.get(photoToLoad.imageView);
if (tag == null || !tag.equals(photoToLoad.url)) {
return true;
}
return false;
} // 用于显示位图在UI线程
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 void CopyStream(InputStream is, OutputStream os) {
final int buffer_size = 1024;
try {
byte[] bytes = new byte[buffer_size];
for (;;) {
int count = is.read(bytes, 0, buffer_size);
if (count == -1)
break;
os.write(bytes, 0, count);
}
is.close();
os.close();
} catch (Exception ex) {
}
}*/
}
下面是我的调用代码,但是报错
String url = “暂时随便写”;
ImageView imageView = (ImageView)findViewById(R.id.image);
Imageloader imageloader = new Imageloader(test.this);
imageloader.DisplayImage(url,imageloader);
最后这行报错,让我删去括号,但是我删了也没用。
eclipse本身是有提示的,但是我写最后一行没有提示,估计一开始就写错了。imageviewURLBitmap

解决方案 »

  1.   

    ImageView imageView = (ImageView)findViewById(R.id.image);
     Imageloader imageloader = new Imageloader(test.this);
    我只写了这两行的话,编译没报错,但是运行也强制退出了
      

  2.   

    imageloader.DisplayImage(url,imageloader);
    看好,第二个参数要传进去的是imageview
      

  3.   

    public FileCache(Context context){
            //Find the dir to save cached images
            if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
                cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"TTImages_cache");
            else
                cacheDir=context.getCacheDir();
            if(!cacheDir.exists())
                cacheDir.mkdirs();
        }这个有可能是要在sdcard创建文件的,程序需要添加权限android.permission.WRITE_EXTERNAL_STORAGE
      

  4.   

    还有,这些错误都会报出明显的提示log的,细心点查看