Android - 加载图像Url并在ImageView中显示

标签 android android-imageview android-image

我有这段代码来加载图像。服务器是安全的。 我得到的答复是:200,这意味着可以。然后还要加载正确的网址。 问题是当我运行我的应用程序时,图像不会被加载。

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

在我的 logcat 中..有一次它应该 SKImageDecoder::Factory 返回 null

但是,也许我做了一些事情......这就是我在 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

我猜我的图像自从我记录图像大小?后就被解码了:然后它记录了我想要加载的图像的正确图像大小。

问题出在ImageLoader还是渲染部分?

请提供任何见解。谢谢。

最佳答案

尝试使用这个类,它在后台下载图像并存储在缓存中:

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

易于使用,只需声明:

 DrawableBackgroundDownloader drawableDownloader = new DrawableBackgroundDownloader();

您想在哪里使用:

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

其中drawable是在图像下载期间显示的Drawable。

关于Android - 加载图像Url并在ImageView中显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16055375/

相关文章:

android - 如何将 TimeZone 打印为 IST 或 EST 取决于 Android 中的 TimeZone?

java - 动态设置图像在旋转时丢失

android - 在 Android Activity 中添加多个动态微调器 View ,而不是在第二个微调器中加载选定的微调器数据

php - Android - 在 GridView 中使用 PHP 显示服务器文件夹中的所有图像

java - 一旦我退出应用程序,生成的 QR 图像就会消失

Android ListView 滚动延迟由于 ImageView 绘制

android - 如何在android中安全地存储图像和视频以便其他应用程序无法使用?

java - Android在Eclipse中添加操作栏时出现问题

android - 在 Android 上使用 "no picture"联系人的系统镜像

android - Android 中相机图像返回缩略图