Android - Loading Image Url and Displaying in ImageView

大兔子大兔子 提交于 2019-12-24 03:15:59

问题


I have this code to load an image. The server is secured. I got a response: 200 which means okay. Then also the right url is to be loaded. The problem is when i run my app, the image wont be loaded.

try {
        Bitmap bitmap=null;
        URL imageUrl = new URL(url);
        String userPass = username+":"+password;
        String encode = Base64.encodeToString(userPass.getBytes(), Base64.DEFAULT);
        HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
        conn.setRequestProperty("Authorization", "Basic " + encode);
        conn.setConnectTimeout(10000);
        conn.setReadTimeout(10000); 
        conn.setInstanceFollowRedirects(true);
        int res = conn.getResponseCode();

        System.out.println("Response: " + res);
        System.out.println("Image Loader URL: " + url);

        InputStream is=conn.getInputStream();
        OutputStream os = new FileOutputStream(f);
        Utils.CopyStream(is, os);
        os.close();
        bitmap = decodeFile(f);
        return bitmap;


    } catch (Throwable ex){
       ex.printStackTrace();
       if(ex instanceof OutOfMemoryError)
           memoryCache.clear();
       return null;
    }

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=360;
        int width_tmp=o.outWidth, height_tmp=o.outHeight;
        Log.d("IMAGE SIZE?  ", +width_tmp+ " x " + height_tmp);
        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;
}
/// . . . . . and so on...\

In my logcat..one time it should SKImageDecoder::Factory returned null

But then, maybe i did something..this now what i see in my logcat..

04-17 16:18:57.936: D/libEGL(5216): loaded /system/lib/egl/libGLES_android.so
04-17 16:18:57.940: D/libEGL(5216): loaded /vendor/lib/egl/libEGL_POWERVR_SGX540_120.so
04-17 16:18:57.952: D/libEGL(5216): loaded /vendor/lib/egl/libGLESv1_CM_POWERVR_SGX540_120.so
04-17 16:18:57.955: D/libEGL(5216): loaded /vendor/lib/egl/libGLESv2_POWERVR_SGX540_120.so
04-17 16:18:58.087: D/OpenGLRenderer(5216): Enabling debug mode 0

I guess my image was decoded since i logged IMAGE SIZE? : then it logged the right image size of the image i want to load.

Is the problem on the ImageLoader or the rendering part?

Any insights please. Thanks.


回答1:


try with this class, it download the image in background and store in cache:

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.widget.ImageView;




/**
 * This Class is for download images and assign the drawable to an ImageView.
 * 
 */
public class DrawableBackgroundDownloader {    

private final Map<String, Drawable> mCache = new HashMap<String, Drawable>();   
private final LinkedList <Drawable> mChacheController = new LinkedList <Drawable> ();
private ExecutorService mThreadPool;  
private final Map<ImageView, String> mImageViews = Collections.synchronizedMap(new WeakHashMap<ImageView, String>());  
public static int MAX_CACHE_SIZE = 80; 
public int THREAD_POOL_SIZE = 3;



/**
 * Constructor
 */
public DrawableBackgroundDownloader() {  
    mThreadPool = Executors.newFixedThreadPool(THREAD_POOL_SIZE);  
}  


/**
 * Clears all instance data and stops running threads
*/ 
public void Reset() {
    ExecutorService oldThreadPool = mThreadPool;
    mThreadPool = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
    oldThreadPool.shutdownNow();

    mChacheController.clear();
    mCache.clear();
    mImageViews.clear();
}  

/**
 * Load the drawable associated to a url and assign it to an image, you can set a placeholder to replace this drawable.
 * @param url Is the url of the image.
 * @param imageView The image to assign the drawable.
 * @param placeholder A drawable that is show during the image is downloading.
 */
public void loadDrawable(final String url, final ImageView imageView,Drawable placeholder) {  
    if(!mImageViews.containsKey(url))
        mImageViews.put(imageView, url);  
    Drawable drawable = getDrawableFromCache(url);  

    // check in UI thread, so no concurrency issues  
    if (drawable != null) {  
        //Log.d(null, "Item loaded from mCache: " + url);  
        imageView.setImageDrawable(drawable);  
    } else {  
        imageView.setImageDrawable(placeholder);  
        queueJob(url, imageView, placeholder);  
    }  
} 


/**
 * Return a drawable from the cache.
 * @param url url of the image.
 * @return a Drawable in case that the image exist in the cache, else returns null.
 */
public Drawable getDrawableFromCache(String url) {  
    if (mCache.containsKey(url)) {  
        return mCache.get(url);  
    }  

    return null;  
}


/**
 * Save the image to cache memory.
 * @param url The image url
 * @param drawable The drawable to save.
 */
private synchronized void putDrawableInCache(String url,Drawable drawable) {  
    int chacheControllerSize = mChacheController.size();
    if (chacheControllerSize > MAX_CACHE_SIZE) 
        mChacheController.subList(0, MAX_CACHE_SIZE/2).clear();

    mChacheController.addLast(drawable);
    mCache.put(url, drawable);

}  

/**
 * Queue the job to download the image.
 * @param url Image url.
 * @param imageView The ImageView where is assigned the drawable.
 * @param placeholder The drawable that is show during the image is downloading. 
 */
private void queueJob(final String url, final ImageView imageView,final Drawable placeholder) {  
    /* Create handler in UI thread.  */
    final Handler handler = new Handler() {  
        @Override  
        public void handleMessage(Message msg) {  
            String tag = mImageViews.get(imageView);  
            if (tag != null && tag.equals(url)) {
                if (imageView.isShown())
                    if (msg.obj != null) {
                        imageView.setImageDrawable((Drawable) msg.obj);  
                    } else {  
                        imageView.setImageDrawable(placeholder);  
                        //Log.d(null, "fail " + url);  
                    } 
            }  
        }  
    };  

    mThreadPool.submit(new Runnable() {  
        public void run() {  
            final Drawable bmp = downloadDrawable(url);
            // if the view is not visible anymore, the image will be ready for next time in cache
            if (imageView.isShown())
            {
                Message message = Message.obtain();  
                message.obj = bmp;
                //Log.d(null, "Item downloaded: " + url);  

                handler.sendMessage(message);
            }
        }  
    });  
}  


/**
 * Method that download the image
 * @param url The url image.
 * @return Returns the drawable associated to this image.
 */
private Drawable downloadDrawable(String url) {  
    try {  
        InputStream is = getInputStream(url);

        Drawable drawable = Drawable.createFromStream(is, url);
        putDrawableInCache(url,drawable);  
        return drawable;  

    } catch (MalformedURLException e) {  
        e.printStackTrace();  
    } catch (IOException e) {  
        e.printStackTrace();  
    }  

    return null;  
}  

/**
 * This method manage the connection to download the image.
 * @param urlString url of the image.
 * @return Returns an InputStream associated with the url image.
 * @throws MalformedURLException
 * @throws IOException
 */
private InputStream getInputStream(String urlString) throws MalformedURLException, IOException {
    URL url = new URL(urlString);
    URLConnection connection;
    connection = url.openConnection();
    connection.setUseCaches(true); 
    connection.connect();
    InputStream response = connection.getInputStream();

    return response;
}
}

is easy to use just declare:

 DrawableBackgroundDownloader drawableDownloader = new DrawableBackgroundDownloader();

and where do you want to use:

drawableDownloader.loadDrawable(String urlImage, ImageView iView,Drawable drawable);

where drawable is a Drawable that is showing during image download.



来源:https://stackoverflow.com/questions/16055375/android-loading-image-url-and-displaying-in-imageview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!