0

I'm trying to load a remote image from the server using the following code:

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) 
{

}

The image is showing fine but when I put the code into a new thread, the image is not loaded.

The code is:

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

The image does not load, why not?

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
Ernesto Rodriguez
  • 257
  • 2
  • 9
  • 26

4 Answers4

3

You can't change the UI within a thread in this way. You should use asyncTask or the method runOnUiThread to properly change the User interface. Or even better, handler like this post

Community
  • 1
  • 1
StarsSky
  • 6,721
  • 6
  • 38
  • 63
1

you will need to use Activity.runOnUiThread for changing from background thread as :

 @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) {

    }
ρяσѕρєя K
  • 132,198
  • 53
  • 198
  • 213
0

As an alternative to trying to deal with threading manually like this (where you'll run into problems like this where you can't update the UI from another thread), take a look at this article and consider using something like AsyncTask which already has some of this infrastructure in place and in fact has an example for your very use case:

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);
     }
 }
kabuko
  • 36,028
  • 10
  • 80
  • 93
0

Here is a simple AsyncTask to download and cache an image from the web:

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

}

Which is implemented like so:

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