【问题标题】:Can't load an image from within a thread in Android无法从 Android 的线程中加载图像
【发布时间】:2013-02-01 20:52:08
【问题描述】:

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

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

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

【问题讨论】:

    标签: android multithreading image


    【解决方案1】:

    您不能以这种方式更改线程内的 UI。您应该使用asyncTaskrunOnUiThread 方法来正确更改用户界面。 或者更好,handler 像这样post

    【讨论】:

      【解决方案2】:

      您需要使用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) {
      
          }
      

      【讨论】:

        【解决方案3】:

        作为尝试像这样手动处理线程的替代方法(在这种情况下,您会遇到无法从另一个线程更新 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);
             }
         }
        

        【讨论】:

          【解决方案4】:

          这是一个简单的 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");
          

          【讨论】:

            猜你喜欢
            • 2011-02-26
            • 1970-01-01
            • 2017-12-31
            • 1970-01-01
            • 2013-08-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多