无法从Android中的线程中加载图像

时间:2013-02-01 20:52:09

标签: android multithreading image

我正在尝试使用以下代码从服务器加载远程图像:

imageViewClient = (ImageView) findViewById(R.id.imageViewClient);
try 
{
    URL thumb_u = new URL(c.getImage());
    Drawable thumb_d = Drawable.createFromStream(thumb_u.openStream(), "src");
    imageViewClient.setImageDrawable(thumb_d);                      

}
catch (Exception e) 
{

}

图像显示正常,但是当我将代码放入新线程时,图像未加载。

代码是:

new Thread() 
{
    @Override
    public void run()
    {
            //** Set imageview url
            try {
                URL thumb_u = new URL(c.getImage());
                Drawable thumb_d = Drawable.createFromStream(
                    thumb_u.openStream(), "src");

                imageViewClient.setImageDrawable(thumb_d);                      

            }
            catch (Exception e) {

            }

    }
}.start();

图片无法加载,为什么不加载?

4 个答案:

答案 0 :(得分:3)

您无法以这种方式更改线程中的UI。您应该使用asyncTask或方法runOnUiThread来正确更改用户界面。 或者更好,handler喜欢post

答案 1 :(得分:1)

您需要使用Activity.runOnUiThread从后台主题更改为:

 @Override
  public void run() {
     //** Set imageview url
     try {
        URL thumb_u = new URL(c.getImage());
         Drawable thumb_d = Drawable.createFromStream(
                              thumb_u.openStream(), "src");                      

        Your_current_Activity.this.runOnUiThread(new Runnable() {
        public void run() {
         // Chnage imageView bg here
        imageViewClient.setImageDrawable(thumb_d); 
        }
    });
       }
     catch (Exception e) {

    }

答案 2 :(得分:0)

作为尝试手动处理线程的替代方法(在这种情况下你会遇到无法从其他线程更新UI的问题),请查看this article并考虑使用像AsyncTask这样的东西已经有了一些这样的基础设施,实际上有一个例子用于你的用例:

public void onClick(View v) {
  new DownloadImageTask().execute("http://example.com/image.png");
}

private class DownloadImageTask extends AsyncTask {
     protected Bitmap doInBackground(String... urls) {
         return loadImageFromNetwork(urls[0]);
     }

     protected void onPostExecute(Bitmap result) {
         mImageView.setImageBitmap(result);
     }
 }

答案 3 :(得分:0)

这是一个简单的AsyncTask,可以从网上下载和缓存图像:

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;
import android.widget.ImageView;

/**
 * Downloads an image from a URL and saves it to disk, to be referenced if the
 * same URL is requested again
 */
public class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {

    private static final String LOG = DownloadImageTask.class.getSimpleName();

    ImageView mImageView;

    public static final String IMAGE_CACHE_DIRECTORY = YourApplication
            .getContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES)
            .getAbsolutePath();

    public DownloadImageTask(ImageView bmImage) {
        this.mImageView = bmImage;

        // TODO set to default "loading" drawable
        mImageView.setImageBitmap(null);
    }

    @Override
    protected Bitmap doInBackground(String... urls) {

        String url = urls[0];

        Log.v(LOG, "url: " + url);

        String filename = url.substring(url.lastIndexOf("/") + 1, url.length());

        Log.v(LOG, "filename: " + filename);

        Bitmap bmp = getBitmapFromDisk(filename);

        if (bmp == null) {
            try {
                InputStream in = new java.net.URL(url).openStream();
                bmp = BitmapFactory.decodeStream(in);
                writeBitmapToDisk(filename, bmp);
            } catch (Exception e) {
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }
        }

        return bmp;
    }

    @Override
    protected void onPostExecute(Bitmap result) {
        mImageView.setImageBitmap(result);
    }

    public boolean writeBitmapToDisk(String imageid, Bitmap bmp) {
        boolean saved = false;

        File path = new File(IMAGE_CACHE_DIRECTORY);
        path.mkdirs();
        File imageFile = new File(path, imageid);
        FileOutputStream imageOS = null;
        try {
            imageOS = new FileOutputStream(imageFile);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        saved = bmp.compress(Bitmap.CompressFormat.JPEG, 95, imageOS);
        return saved;
    }

    public Bitmap getBitmapFromDisk(String imageid) {
        Bitmap bmp = BitmapFactory.decodeFile(IMAGE_CACHE_DIRECTORY + "/"
                + imageid);
        return bmp;
    }

}

这样实现:

new DownloadImageTask(mImageView).execute("https://www.google.com/images/srpr/logo3w.png");