0

我有一个名为 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);
}
}

(灰,我对代码块的东西很烂......)

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

4

3 回答 3

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

复制流功能:

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)
    {
    }
}
于 2012-05-24T17:34:37.503 回答
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();
于 2012-05-24T17:23:20.243 回答
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();

}

于 2012-05-24T17:28:17.820 回答