从Internet获取图像并设置为ImageView

时间:2012-05-24 16:51:51

标签: java android url imageview

我有一个名为tab1的ImageView。我的代码看起来像这样。

import java.io.InputStream;
import java.net.URL;

import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.TabHost;
import android.widget.Toast;

public class Paikallissaa extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    TabHost tabs = (TabHost) findViewById(R.id.tabhost);
    tabs.setup();   
    TabHost.TabSpec spec = tabs.newTabSpec("tag1");

    try {
        ImageView iv = (ImageView) findViewById(R.id.tab1);

        URL url = new URL("http://cdn.fmi.fi/weather-observations/products/finland/finland-weather-observations-map.png");
        InputStream content = (InputStream) url.getContent();
        Drawable d = Drawable.createFromStream(content, "src");

        iv.setImageDrawable(d);
    } catch (Exception e) {
        Toast.makeText(this, "Error getting image: " + e, Toast.LENGTH_SHORT);
    }

    spec.setContent(R.id.tab1);
    spec.setIndicator("Koko maa");
    tabs.addTab(spec);

    spec = tabs.newTabSpec("tag2");
    spec.setContent(R.id.tab2);
    spec.setIndicator("Raisio");
    tabs.addTab(spec);
}
}

(Ash我吮吸代码块的东西......)

它不会更新图像。怎么了?它一直显示我在main.xml中设置的图像。

3 个答案:

答案 0 :(得分:3)

要做到这一点,我一直在使用一个助手类,我在互联网上的某个地方找到并修改了一点点。它负责缓存图像并在后台线程上加载图像。

由于您的图像在服务器上发生了变化,您可能希望删除此代码的缓存部分。

用法:

ImageLoader loader = new ImageLoader(this);
loader.DisplayImage(String.format(headshotUrl, data.Id), this, headshot);

这里是:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Stack;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.widget.ImageView;

public class ImageLoader
{
    public static String TAG = "xxx";
    // the simplest in-memory cache implementation. This should be replaced with
    // something like SoftReference or BitmapOptions.inPurgeable(since 1.6)
    private HashMap<String, Bitmap> cache = new HashMap<String, Bitmap>();

    private File cacheDir;

    public ImageLoader(Context context)
    {
        photoLoaderThread.setPriority(Thread.NORM_PRIORITY - 1);
        cacheDir = Utilities.GetCacheDir(context);
    }

    final int stub_id = R.drawable.face_placeholder;

    public void DisplayImage(String url, Activity activity, ImageView imageView)
    {
        imageView.setTag(url);
        Log.i(TAG, url);
        if (cache.containsKey(url))
            imageView.setImageBitmap(cache.get(url));
        else
        {
            queuePhoto(url, activity, imageView);
            imageView.setImageResource(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)
    {
        // I identify images by hashcode. Not a perfect solution, good for the
        // demo.
        String filename = String.valueOf(url.hashCode());
        File f = new File(cacheDir, filename);

        // from SD cache
        Bitmap b = decodeFile(f);
        if (b != null)
            return b;

        // from web
        try
        {
            Bitmap bitmap = null;
            InputStream is = new URL(url).openStream();
            OutputStream os = new FileOutputStream(f);
            Utilities.CopyStream(is, os);
            os.close();
            bitmap = decodeFile(f);
            return bitmap;
        } catch (Exception ex)
        {
            ex.printStackTrace();
            return null;
        }
    }

    // decodes image and scales it to reduce memory consumption
    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;
            return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
        } catch (FileNotFoundException e)
        {
            e.printStackTrace();
        }
        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);
                        cache.put(photoToLoad.url, bmp);
                        Object tag = photoToLoad.imageView.getTag();
                        if (tag != null && ((String) 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)
            {
                e.printStackTrace();
            }
        }
    }

    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()
        {
            Log.i(TAG, "BitmapDisplayer run()");
            if (bitmap != null)
                imageView.setImageBitmap(bitmap);
            else
                imageView.setImageResource(stub_id);
        }
    }

    public void clearCache()
    {
        // clear memory cache
        cache.clear();

        // clear SD cache
        File[] files = cacheDir.listFiles();
        for (File f : files)
            f.delete();
    }

}

在实用程序类中,我有GetCacheDir(...)

public static File GetCacheDir(Context context)
{
    File cacheDir;
    if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
        cacheDir = new File(android.os.Environment.getExternalStorageDirectory(), "com.example.app");
    else
        cacheDir = context.getCacheDir();
    if (!cacheDir.exists())
        cacheDir.mkdirs();

    return cacheDir;
}

CopyStream功能:

public static void CopyStream(InputStream is, OutputStream os)
{
    final int buffer_size = 1024;
    try
    {
        byte[] bytes = new byte[buffer_size];
        for (;;)
        {
            int count = is.read(bytes, 0, buffer_size);
            if (count == -1)
                break;
            os.write(bytes, 0, count);
        }
    } catch (Exception ex)
    {
    }
}

答案 1 :(得分:0)

要从互联网上获取图像,请尝试以下操作

HttpGet httpRequest = new HttpGet(URI.create("http://cdn.fmi.fi/weather-observations/products/finland/finland-weather-observations-map.png") );
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = (HttpResponse) httpclient.execute(httpRequest);
HttpEntity entity = response.getEntity();
BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(entity);
bmp = BitmapFactory.decodeStream(bufHttpEntity.getContent());
ImageView iv = (ImageView) findViewById(R.id.tab1);
iv.setImageBitmat(bmp);
httpRequest.abort();

答案 2 :(得分:0)

这将下载图像并将其设置为图像视图,取自我帮助编写的应用程序。我删除了一些我正在使用的无用代码,但方法保持不变。

public void setImage(){
    imageView.setImageURI(DownloadImage);
}

public String DownloadImage(){
    string filepath = DownloadFromUrl("url","filename.png");

}

public String DownloadFromUrl(String imageURL, String fileName) {

    File file = new File(PATH + fileName);
    try {
        URL url = new URL(imageURL);

        long startTime = System.currentTimeMillis();
        Log.d("ImageManager", "download begining");
        Log.d("ImageManager", "download url:" + url);
        Log.d("ImageManager", "downloaded file name:" + fileName);
        /* Open a connection to that URL. */
        URLConnection ucon = url.openConnection();

        /*
         * Define InputStreams to read from the URLConnection.
         */
        InputStream is = ucon.getInputStream();
        BufferedInputStream bis = new BufferedInputStream(is);

        /*
         * Read bytes to the Buffer until there is nothing more to read(-1).
         */
        ByteArrayBuffer baf = new ByteArrayBuffer(50);
        int current = 0;
        while ((current = bis.read()) != -1) {
            baf.append((byte) current);
        }

        /* Convert the Bytes read to a String. */
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(baf.toByteArray());
        fos.close();
        Log.d("ImageManager",
                "download ready in"
                        + ((System.currentTimeMillis() - startTime) / 1000)
                        + " sec");

    } catch (IOException e) {
        Log.d("ImageManager", "Error: " + e);
    }
    return file.toString();

}