从服务器为社交网络应用程序的Android图库图像

问题描述:

嗨,大家好我是在寻找如何有效地从服务器加载图像到我的画廊。现在我正在使用延迟加载技术解释this url从服务器为社交网络应用程序的Android图库图像

但是,当图库图片数量增加时,它仍然会变慢。任何人都可以找到或使用任何其他技术。此外,我不明白一些社交网络应用程序如POF和match.com等如何实现他们的图像显示最初模糊,并获得良好的质量。希望你们能理解我的问题..希望能有更好的回应。提前致谢。

编辑#1:

对不起你们我只是上面贴上不同的网址... This is the one which i have followed for my implementation

还通过第一URL中去,发现他们也使用了相同的逻辑......

编辑#2:

gallery.setAdapter(new LazyGalleryBaseAdapter(this, mStrings)); 
imageLoader.DisplayImage(data[position], activity, image);// called from the getview method of LazyGalleryBaseAdapter class 

而且ImageLoader的类,如下所示:

package com.sdi.lazyimageloader; 

import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.IOException; 
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.Stack; 
import java.util.WeakHashMap; 

import android.app.Activity; 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.widget.ImageView; 

import com.sdi.videodate.R; 

public class ImageLoader { 

MemoryCache memoryCache = new MemoryCache(); 
FileCache fileCache; 
private Map<ImageView, String> imageViews = Collections 
     .synchronizedMap(new WeakHashMap<ImageView, String>()); 
Context ctx; 

public ImageLoader(Context context) { 
    // Make the background thead low priority. This way it will not affect 
    // the UI performance 
    photoLoaderThread.setPriority(Thread.NORM_PRIORITY - 1); 
    ctx = context; 
    fileCache = new FileCache(context); 
} 

final int stub_id = R.drawable.stub; 

public void DisplayImage(String url, Activity activity, ImageView imageView) { 
    imageViews.put(imageView, url); 
    Bitmap bitmap = memoryCache.get(url); 
    System.err.println("bitmap ??????"+bitmap); 
    System.out.println("imageView ===> "+imageView); 
    if (bitmap != null) { 
     // call the below line to get the rounded corner image 
//   Bitmap bitmap1 = LazyAdapter.getRoundedCornerBitmap(ctx, bitmap, 
//     7f, 7f, 7f, 7f, 85, 85);    

     imageView.setImageBitmap(bitmap); 
    } else { 
     queuePhoto(url, activity, imageView); 
     imageView.setImageResource(stub_id); 
     System.err.println("bitmap stub_id??????"+stub_id); 
    } 
} 

private void queuePhoto(String url, Activity activity, ImageView imageView) { 
    // This ImageView may be used for other images before. So there may be 
    // some old tasks in the queue. We need to discard them. 
    photosQueue.Clean(imageView); 
    PhotoToLoad p = new PhotoToLoad(url, imageView); 
    synchronized (photosQueue.photosToLoad) { 
     photosQueue.photosToLoad.push(p); 
     photosQueue.photosToLoad.notifyAll(); 
    } 

    // start thread if it's not started yet 
    if (photoLoaderThread.getState() == Thread.State.NEW) 
     photoLoaderThread.start(); 
} 

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); 
     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 static Bitmap decodeFiles(File f) { 
    Bitmap b = null; 
    try { 
     // Decode image size 
     int IMAGE_MAX_SIZE = 80; 
     BitmapFactory.Options o = new BitmapFactory.Options(); 
     o.inJustDecodeBounds = true; 

     FileInputStream fis = new FileInputStream(f); 
     BitmapFactory.decodeStream(fis, null, o); 
     try { 
      fis.close(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     int scale = 1; 
     if (o.outHeight <= 1300 && o.outWidth <= 1000) { 
      scale = 1; 
     } else if (o.outHeight >= 1280 && o.outWidth >= 960) { 
      scale = 6; 
     } else if (o.outHeight > IMAGE_MAX_SIZE 
       || o.outWidth > IMAGE_MAX_SIZE) { 

      // scale = (int) Math.pow(2,(int) 
      // Math.round(Math.log(IMAGE_MAX_SIZE/(double) 
      // Math.max(o.outHeight, o.outWidth))/ Math.log(0.5))); 
      scale = 5; 
     } 
     /* 
     * else if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > 
     * IMAGE_MAX_SIZE) { // scale = (int) Math.pow(2,(int) // 
     * Math.round(Math.log(IMAGE_MAX_SIZE/(double) // 
     * Math.max(o.outHeight, o.outWidth))/ Math.log(0.5))); scale = 8; } 
     */ 

     System.err.println(scale 
       + "---Scale Value ((((((((((((((((((((((((((((((" 
       + o.outHeight + "---" + o.outWidth); 

     // Decode with inSampleSize 
     BitmapFactory.Options o2 = new BitmapFactory.Options(); 
     o2.inSampleSize = scale; 
     fis = new FileInputStream(f); 
     try{ 
     b = BitmapFactory.decodeStream(fis, null, o2); 
     } 
     catch (OutOfMemoryError e) { 
      // TODO: handle exception 
     } 
     try { 
      fis.close(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } 

    return b; 
} 

// decodes image and scales it to reduce memory consumption 
/* 
* rename by dinash from decodeFile to decodeFiles 
*/ 
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; 
     try{ 
     return BitmapFactory.decodeStream(new FileInputStream(f), null, o2); 
     } 
     catch (OutOfMemoryError e) { 
      // TODO: handle exception 
     } 
    } 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; 
    } 
} 

PhotosQueue photosQueue = new PhotosQueue(); 

public void stopThread() { 
    photoLoaderThread.interrupt(); 
} 

// stores list of photos to download 
class PhotosQueue { 
    private Stack<PhotoToLoad> photosToLoad = new Stack<PhotoToLoad>(); 

    // removes all instances of this ImageView 
    public void Clean(ImageView image) { 
     for (int j = 0; j < photosToLoad.size();) { 
      if (photosToLoad.get(j).imageView == image) 
       photosToLoad.remove(j); 
      else 
       ++j; 
     } 
    } 
} 

class PhotosLoader extends Thread { 
    public void run() { 
     try { 
      while (true) { 
       // thread waits until there are any images to load in the 
       // queue 
       if (photosQueue.photosToLoad.size() == 0) 
        synchronized (photosQueue.photosToLoad) { 
         photosQueue.photosToLoad.wait(); 
        } 
       if (photosQueue.photosToLoad.size() != 0) { 
        PhotoToLoad photoToLoad; 
        synchronized (photosQueue.photosToLoad) { 
         photoToLoad = photosQueue.photosToLoad.pop(); 
        } 
        Bitmap bmp = getBitmap(photoToLoad.url); 
        memoryCache.put(photoToLoad.url, bmp); 
        String tag = imageViews.get(photoToLoad.imageView); 
        if (tag != null && tag.equals(photoToLoad.url)) { 
         BitmapDisplayer bd = new BitmapDisplayer(bmp, 
           photoToLoad.imageView); 
         Activity a = (Activity) photoToLoad.imageView 
           .getContext(); 
         a.runOnUiThread(bd); 
        } 
       } 
       if (Thread.interrupted()) 
        break; 
      } 
     } catch (InterruptedException e) { 
      // allow thread to exit 
     } 
    } 
} 

PhotosLoader photoLoaderThread = new PhotosLoader(); 

// Used to display bitmap in the UI thread 
class BitmapDisplayer implements Runnable { 
    Bitmap bitmap; 
    ImageView imageView; 

    public BitmapDisplayer(Bitmap b, ImageView i) { 
     bitmap = b; 
     imageView = i; 
    } 

    public void run() { 
     System.out.println("imageView ===> "+imageView); 
     if (bitmap != null) 
      imageView.setImageBitmap(bitmap); 
     else 
      imageView.setImageResource(stub_id); 
    } 
} 

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

} 
+0

将您的代码发布到您要拖动图像的位置。 – AedonEtLIRA

+0

@AedonEtLIRA我已经发布我的代码,我拉图像 – Dinash

据我了解,您正在使用我的实施https://github.com/thest1/LazyList。如果你得到最新的代码,你可以看到我修改它来使用线程池。所以现在它同时下载几个图像。尝试演示,现在速度非常快。

你也说模糊的图像。它通常发生在缩略图可用时,并且在下载全尺寸图像时可以使其显示模糊。如果你没有缩略图,没有什么可以模糊。

+0

感谢您的答复,我会检查它,让你知道.. – Dinash

+0

嗨用你的代码和它的工作正常,但仍然频繁我得到这个错误消息在logcat和'796416字节的外部分配对于这个过程来说太大了'之后没有任何图像被加载。' – Dinash