我正在使用延迟加载(fedorvlasov/lazylist)方法从服务器下载图像,但我的问题是,一旦我从服务器获取图像,我想将其保存在数据库中,但有些图像只保存在数据库中.请让我知道正确的方法。如果我实现了队列,问题就解决了。
public class ImageLoader {
private Map<ImageView, String> imageViews=Collections.synchronizedMap(new WeakHashMap<ImageView, String>());
ExecutorService executorService;
public ImageLoader(Context context){
// fileCache=new FileCache(context);
executorService=Executors.newFixedThreadPool(0);
}
// final int stub_id=R.drawable.stub;
public void DisplayImage(String url, ImageView imageView)
{
imageViews.put(imageView, url);
Bitmap bitmap=null;//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);*/
DefaultHttpClient mHttpClient = new DefaultHttpClient();
HttpGet mHttpGet = new HttpGet(url);
HttpResponse mHttpResponse = mHttpClient.execute(mHttpGet);
// if (mHttpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
{
HttpEntity entity = mHttpResponse.getEntity();
if ( entity != null)
{
// String String=EntityUtils.toByteArray(entity).toString();
// String=convertResizedImage(String);
InputStream inputStream = null;
inputStream = entity.getContent();
// byte[] imgarrbyte = new byte[inputStream.available()];
//inputStream.read(imgarrbyte);
bitmap = BitmapFactory.decodeStream(inputStream);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.PNG, 100, bos);
String cardimage = Base64.encodeToString(bos.toByteArray(),
Base64.DEFAULT);
byte[] imgarrbyte = null;
try {
if (cardimage!= null) {
// Utils.writetoFile(, String.valueOf(position));
byte[] tempByArr = cardimage.getBytes();
imgarrbyte = Base64.decode(tempByArr,Base64.DEFAULT);
}
if (imgarrbyte != null && imgarrbyte.length > 0) {
bitmap = BitmapFactory.decodeByteArray(imgarrbyte, 0,
imgarrbyte.length);
}
}catch(OutOfMemoryError oome)
{
oome.printStackTrace();
}
}
}
return bitmap;
} catch (Exception ex){
ex.printStackTrace();
return null;
}
}
public String convertResizedImage(String imagedata) {
try {
// Step 1 : Image decoded
byte[] imageAsBytes = new byte[imagedata.length()];
imageAsBytes = Base64.decode(imagedata.getBytes("UTF8"),
Base64.DEFAULT);
BitmapFactory.Options opts = new BitmapFactory.Options();
int IMAGE_MAX_SIZE = 240, scale = 1;
if (opts.outHeight > IMAGE_MAX_SIZE
|| opts.outWidth > IMAGE_MAX_SIZE) {
scale = (int) Math.pow(2, (int) Math.round(Math
.log(IMAGE_MAX_SIZE
/ (double) Math.max(opts.outHeight,
opts.outWidth))
/ Math.log(0.5)));
}
// Step 2 : Compress the BITMAP
opts.inSampleSize = scale;
opts.inPurgeable = true;
opts.inPreferredConfig = Bitmap.Config.ARGB_4444;
// Decode with inSampleSize
opts.inJustDecodeBounds = false;
opts.inDither = false;
opts.inScaled = false;
// STEP 3 :
Bitmap bitMapimage = BitmapFactory.decodeByteArray(imageAsBytes, 0,
imageAsBytes.length, opts);
String tempstr = new String();
if (bitMapimage != null) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitMapimage.compress(CompressFormat.JPEG, 100, bos);
tempstr = Base64.encodeToString(bos.toByteArray(),
Base64.DEFAULT);
}
return tempstr;
} catch (Exception e) {
// TODO Auto-generated catch block
e.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=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;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (FileNotFoundException e) {}
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;
}
}
public void getImageSize(byte[] imgarrbyte, String fileName) {
File file = new File("/mnt/sdcard/", fileName);
FileOutputStream fos;
try {
fos = new FileOutputStream(file);
fos.write(imgarrbyte);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
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);
if(imageViewReused(photoToLoad))
return;
addBitmapTodb(photoToLoad.url,bmp); //saving in database works sometimes.
BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad);
Activity a=(Activity)photoToLoad.imageView.getContext();
a.runOnUiThread(bd);
}
}
private void addBitmapTodb(String url, Bitmap bitmap) {
if (bitmap != null) {
Log.i("Bitmap", "addBitmapTodb==========");
Dao updateimage=new Dao();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.PNG, 100, bos);
String cardimage = Base64.encodeToString(bos.toByteArray(),
Base64.DEFAULT);
updateimage.updateimageindb(url,cardimage);
}
}
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);
}
}
}
感谢您再次回复:) 是的,如果您在上面的代码中检查函数 addBitmapTodb,我目前正在做同样的事情。问题在这里,我使用 cursoradapater 并通过传递 imageurl 从 getview 函数调用 imageloader,我观察到一些问题,如 1.if我在 listview 上滚动,相同的图像 url 请求被发送到 imageloader 以下载图像 2.一些图像只保存在数据库中(可能是因为同步问题),我想避免这样的问题,所以我需要一些帮助这个。