-2

I'm downloading an image from sever using AsyncTask but when calling downloadImage() from activity onCreate() the activity freezes til AsyncTask finishes downloading the image.

I'm using this code:

  Bitmap downloadImage() {
        ImageDownloader task = new ImageDownloader();
        Bitmap myImage;

        try {
            myImage = task.execute("https://drive.google.com/uc?id=0B51TujFYa0RBUUYzSE15WHZRR3c").get();

            downloadedImg.setImageBitmap(myImage);

        } catch (Exception e) {
            e.printStackTrace();
        }
        Log.i("Interaction", "Button Tapped");

        return myImage
   }



    public class ImageDownloader extends AsyncTask<String, Void, Bitmap> {

        @Override
        protected Bitmap doInBackground(String... urls) {
            try {
                URL url = new URL(urls[0]);
                HttpURLConnection connection = (HttpsURLConnection) url.openConnection();
                connection.connect();

                InputStream inputStream = connection.getInputStream();
                //to convert Image from string data to bitmap
                Bitmap myBitmap = BitmapFactory.decodeStream(inputStream);

                return myBitmap;

            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    }
Abed
  • 3,999
  • 1
  • 17
  • 28

3 Answers3

3

You don't properly use the AysncTask class. By calling get(), you pause your main thread until the image is downloaded. That's why the UI feels slow.

Instead, you should set the image from the task's onPostExecute method:

private Toolbar toolbar;
private ImageView downloadedImg;

@Override
protected void onCreate(Bundle savedInstanceState) {

    // ... omitted ...

    ImageDownloader task = new ImageDownloader();    
    task.execute("https://drive.google.com/uc?id=0B51TujFYa0RBUUYzSE15WHZRR3c");

}

// ... omitted ...    

public class ImageDownloader extends AsyncTask<String, Void, Bitmap> {

    @Override
    protected Bitmap doInBackground(String... urls) {
        try {
            URL url = new URL(urls[0]);
            HttpURLConnection connection = (HttpsURLConnection) url.openConnection();
            connection.connect();

            InputStream inputStream = connection.getInputStream();
            //to convert Image from string data to bitmap
            Bitmap myBitmap = BitmapFactory.decodeStream(inputStream);

            return myBitmap;

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    protected void onPostExecute(Bitmap result) {

        downloadedImg.setImageBitmap(result);
    }
}
Codo
  • 75,595
  • 17
  • 168
  • 206
1

You've to do this asynchronously and NOT in the main activity, otherwise the page will be blocked until the download is complete. There is many options to do this. I think the best as indicated in the accepted answer of this question:

Android : Loading an image from the Web with Asynctask

Community
  • 1
  • 1
Davide
  • 131
  • 5
  • 18
1

If you look at the documentation for async task, you will find that get() has the following description

Waits if necessary for the computation to complete, and then retrieves its result.

Instead of calling get() you should implement onPostExecute in your AsyncTask subclass and deal with your image there. There is even an example on the android developer page.

public class ImageDownloader extends AsyncTask<String, Void, Bitmap> {
   <...>

   @Override
   protected void onPostExecute(Bitmap result) {
      downloadedImg.setImageBitmap(result);
   }
}
Mikael Ohlson
  • 3,074
  • 1
  • 22
  • 28