简体   繁体   中英

Android gallery images from server for social networking app

hi guys i am in search of how to load the images from server into my gallery efficiently. Right now i am using lazy loading technique explain in this url

But still it happens to be slower when the number of gallery images increases. Can anybody found or used any other technique for the same. Also i don't understand how some social networking apps like POF and match.com etc have implemented them where the images is displayed as blurred initially and get to good quality. Hope you people could understand my question.. Hoping for better responses. Thanks in Advance.

Edit #1:

Sorry Guys i just have pasted different url above... This is the one which i have followed for my implementation

Also went through the first url and found they also have used the same logic...

Edit #2:

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

And the ImageLoader class as follows:

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

}

As far as I understand you're using my implementation https://github.com/thest1/LazyList . If you get the latest code you can see that I modified it to use thread pool. So now it downloads several images simultaneously. Try the demo, it's really fast now.

You also say about blurred images. It usually happens when you have a thumbnail available and you can display it blurred while full-size image is being downloaded. If you don't have thumbnail there's nothing to blur.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM