2011-11-21 21 views
1

こんにちは、私は、サーバーから自分のギャラリーに画像を効率的に読み込む方法を探しています。今、私は遅延読み込みテクニックを使っています。this urlソーシャルネットワーキングアプリのサーバーからのAndroidギャラリー画像

しかし、ギャラリー画像の数が増えると、まだ遅くなることがあります。誰もが同じもののために他の技術を見つけたり使用したりすることはできません。また、POFやmatch.comなどのソーシャルネットワーキングアプリケーションが、最初に画像がぼやけて表示され、良質になる場所を実装したことを私は理解していません。人々が私の質問を理解できるといいですね。前もって感謝します。

#1

編集:私はちょうど上の別のURLを貼り付けてきた男申し訳

が... 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

答えて

1

あなたが私の実装https://github.com/thest1/LazyListを使用していることを理解する限り、最新のコードを入手した場合は、スレッドプールを使用するように変更したことがわかります。今では複数の画像を同時にダウンロードしています。デモを試してみてください。本当に速いです。

また、ぼやけた画像についても言います。サムネイルが利用可能で、フルサイズの画像がダウンロードされている間にサムネイルをぼかすことができます。あなたがサムネイルを持っていなければ、ぼやけるものは何もありません。

+0

あなたの応答に感謝して、私はそれをチェックしてお知らせします.. – Dinash

+0

こんにちは、あなたのコードを使いましたが、まだ頻繁に私はこのエラーメッセージをlogcatこのプロセスのために796416バイトの外部割り当てが大きすぎると、イメージのいずれもロードされません。 – Dinash

関連する問題