【问题标题】:Android gallery images from server for social networking app来自服务器的 Android 画廊图像用于社交网络应用程序
【发布时间】:2012-02-23 03:20:37
【问题描述】:

大家好,我正在寻找如何有效地将图像从服务器加载到我的画廊。现在我正在使用延迟加载技术在this url

中解释

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

编辑#1:

对不起,我刚刚在上面粘贴了不同的网址... This is the one which i have followed for my implementation

也浏览了第一个网址,发现他们也使用了相同的逻辑......

编辑#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();
}

}

【问题讨论】:

  • 将您的代码发布到您拉取图像的位置。
  • @AedonEtLIRA 我已将我的代码发布到我要拉取图像的位置

标签: android image gallery lazy-loading


【解决方案1】:

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

您还说图像模糊。当您有可用的缩略图并且您可以在下载全尺寸图像时将其显示为模糊时,通常会发生这种情况。如果您没有缩略图,则没有什么可以模糊的。

【讨论】:

  • hi 使用了您的代码并且它工作正常,但我仍然经常在 logcat 中收到此错误消息,并且在“796416 字节外部分配对于此过程来说太大”之后没有加载任何图像。跨度>
猜你喜欢
  • 1970-01-01
  • 2014-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多