2012-05-24 52 views
0

我有一个名为tab1的ImageView。我的代码看起来这样。从互联网获取图像并设置为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中显示我在那里设置的图像。

+0

最好的方法是先下载图像并保存,然后将图像路径设置为图像视图。通过这种方式,你会在日志中遇到什么错误? –

+0

图像每2-3变化一次。多次下载它是否好?或者你是什么意思?不,我没有得到任何的错误。 – MikkoP

+0

是的,如果您没有网络连接,可以显示上次下载的图像。但是,这取决于你的用例。 –

回答

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(); 
+0

没有任何反应。它不会产生任何错误。 – MikkoP

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

}

+0

你也剥去了很多可以使它工作的代码。 – MikkoP

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) 
    { 
    } 
} 
+0

也许有点复杂吗? – MikkoP

+0

它可能有点复杂,但这会阻止UI线程被下载阻止,并允许占位符图像在无法下载的情况下发生。 –

+0

你可以发布Utilities.CopyStream(InputStream,OutputStream)方法吗? – Adam