How to best load images from URL in Android ListView









up vote
3
down vote

favorite












So I have been struggling with the best way to load images in a ListView in Android for a while.



The images come from a server, so can take some time to load. From what I understand there are only 2 ways to implement this:



1 - Load the images on the main thread - This leads to have the correct images display immediately when the view displays and scrolls, but gives poor scrolling performance and can lead to the app hanging and crashing.



2 - Load the images in an AsyncTask. This means the images will be blank when the list display or scroll, but eventually display. Because of caching done by the list, you can also get the wrong image for an item. But this gives good performance and scrolling, and does not hang/crash.



Seems like neither solution works correctly. There must be a solution that works?? I have seen other posts like this, but the answer seems to always be 1 or 2, but neither is a good solution...



My code for the list adapter is below.
The HttpGetImageAction.fetchImage() method either executes an async task, or fetches the image on the main thread depending on a flag I set. I also cache the images locally and on disk once they have been loaded, so the issue mainly occur the first time (but the cache is only for 100 images, and the list has 1000s)



public class ImageListAdapter extends ArrayAdapter<WebMediumConfig> 

Activity activity;

public ImageListAdapter(Activity activity, int resourceId, List<WebMediumConfig> items)
super(activity, resourceId, items);
this.activity = activity;


class ImageListViewHolder
ImageView imageView;
TextView nameView;
TextView descriptionView;
TextView statView;


public View getView(int position, View convertView, ViewGroup parent)
ImageListViewHolder holder = null;
WebMediumConfig config = getItem(position);

LayoutInflater mInflater = (LayoutInflater)this.activity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = mInflater.inflate(R.layout.image_list, null);
holder = new ImageListViewHolder();
holder.imageView = (ImageView)convertView.findViewById(R.id.imageView);
holder.nameView = (TextView) convertView.findViewById(R.id.nameView);
holder.descriptionView = (TextView)convertView.findViewById(R.id.descriptionView);
holder.statView = (TextView)convertView.findViewById(R.id.statView);
convertView.setTag(holder);
else
holder = (ImageListViewHolder) convertView.getTag();


holder.nameView.setText(Utils.stripTags(config.name));
holder.descriptionView.setText(Utils.stripTags(config.description));
holder.statView.setText(config.stats());
if (MainActivity.showImages)
HttpGetImageAction.fetchImage(this.activity, config.avatar, holder.imageView);
else
holder.imageView.setVisibility(View.GONE);


return convertView;











share|improve this question























  • Using a 3rd party library like Glide is not an option ? It loads images async, can cache them and many more, to avoid wrong image in the wrong place, you have to cancel image loading for that imageView. There are tons of tutorials on how to do this.
    – danypata
    Oct 12 at 14:51










  • is there any reason why youre not using a library for this?
    – Ogbe
    Oct 12 at 15:16










  • picasso is good
    – Igmer Rodriguez
    Oct 12 at 15:46










  • Not looking for a framework, it should not be complicated code. From my understanding the frameworks are doing async loading, so the list would display empty and slowly fill in, and does not help with having the wrong image in the wrong place. Unless there is some magic they are doing, in which case, what is this magic??
    – James
    Oct 13 at 15:46











  • FYI, if I load the images on the main thread they are there almost instantly, but if loaded async it takes several seconds for them to load.
    – James
    Oct 13 at 15:48














up vote
3
down vote

favorite












So I have been struggling with the best way to load images in a ListView in Android for a while.



The images come from a server, so can take some time to load. From what I understand there are only 2 ways to implement this:



1 - Load the images on the main thread - This leads to have the correct images display immediately when the view displays and scrolls, but gives poor scrolling performance and can lead to the app hanging and crashing.



2 - Load the images in an AsyncTask. This means the images will be blank when the list display or scroll, but eventually display. Because of caching done by the list, you can also get the wrong image for an item. But this gives good performance and scrolling, and does not hang/crash.



Seems like neither solution works correctly. There must be a solution that works?? I have seen other posts like this, but the answer seems to always be 1 or 2, but neither is a good solution...



My code for the list adapter is below.
The HttpGetImageAction.fetchImage() method either executes an async task, or fetches the image on the main thread depending on a flag I set. I also cache the images locally and on disk once they have been loaded, so the issue mainly occur the first time (but the cache is only for 100 images, and the list has 1000s)



public class ImageListAdapter extends ArrayAdapter<WebMediumConfig> 

Activity activity;

public ImageListAdapter(Activity activity, int resourceId, List<WebMediumConfig> items)
super(activity, resourceId, items);
this.activity = activity;


class ImageListViewHolder
ImageView imageView;
TextView nameView;
TextView descriptionView;
TextView statView;


public View getView(int position, View convertView, ViewGroup parent)
ImageListViewHolder holder = null;
WebMediumConfig config = getItem(position);

LayoutInflater mInflater = (LayoutInflater)this.activity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = mInflater.inflate(R.layout.image_list, null);
holder = new ImageListViewHolder();
holder.imageView = (ImageView)convertView.findViewById(R.id.imageView);
holder.nameView = (TextView) convertView.findViewById(R.id.nameView);
holder.descriptionView = (TextView)convertView.findViewById(R.id.descriptionView);
holder.statView = (TextView)convertView.findViewById(R.id.statView);
convertView.setTag(holder);
else
holder = (ImageListViewHolder) convertView.getTag();


holder.nameView.setText(Utils.stripTags(config.name));
holder.descriptionView.setText(Utils.stripTags(config.description));
holder.statView.setText(config.stats());
if (MainActivity.showImages)
HttpGetImageAction.fetchImage(this.activity, config.avatar, holder.imageView);
else
holder.imageView.setVisibility(View.GONE);


return convertView;











share|improve this question























  • Using a 3rd party library like Glide is not an option ? It loads images async, can cache them and many more, to avoid wrong image in the wrong place, you have to cancel image loading for that imageView. There are tons of tutorials on how to do this.
    – danypata
    Oct 12 at 14:51










  • is there any reason why youre not using a library for this?
    – Ogbe
    Oct 12 at 15:16










  • picasso is good
    – Igmer Rodriguez
    Oct 12 at 15:46










  • Not looking for a framework, it should not be complicated code. From my understanding the frameworks are doing async loading, so the list would display empty and slowly fill in, and does not help with having the wrong image in the wrong place. Unless there is some magic they are doing, in which case, what is this magic??
    – James
    Oct 13 at 15:46











  • FYI, if I load the images on the main thread they are there almost instantly, but if loaded async it takes several seconds for them to load.
    – James
    Oct 13 at 15:48












up vote
3
down vote

favorite









up vote
3
down vote

favorite











So I have been struggling with the best way to load images in a ListView in Android for a while.



The images come from a server, so can take some time to load. From what I understand there are only 2 ways to implement this:



1 - Load the images on the main thread - This leads to have the correct images display immediately when the view displays and scrolls, but gives poor scrolling performance and can lead to the app hanging and crashing.



2 - Load the images in an AsyncTask. This means the images will be blank when the list display or scroll, but eventually display. Because of caching done by the list, you can also get the wrong image for an item. But this gives good performance and scrolling, and does not hang/crash.



Seems like neither solution works correctly. There must be a solution that works?? I have seen other posts like this, but the answer seems to always be 1 or 2, but neither is a good solution...



My code for the list adapter is below.
The HttpGetImageAction.fetchImage() method either executes an async task, or fetches the image on the main thread depending on a flag I set. I also cache the images locally and on disk once they have been loaded, so the issue mainly occur the first time (but the cache is only for 100 images, and the list has 1000s)



public class ImageListAdapter extends ArrayAdapter<WebMediumConfig> 

Activity activity;

public ImageListAdapter(Activity activity, int resourceId, List<WebMediumConfig> items)
super(activity, resourceId, items);
this.activity = activity;


class ImageListViewHolder
ImageView imageView;
TextView nameView;
TextView descriptionView;
TextView statView;


public View getView(int position, View convertView, ViewGroup parent)
ImageListViewHolder holder = null;
WebMediumConfig config = getItem(position);

LayoutInflater mInflater = (LayoutInflater)this.activity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = mInflater.inflate(R.layout.image_list, null);
holder = new ImageListViewHolder();
holder.imageView = (ImageView)convertView.findViewById(R.id.imageView);
holder.nameView = (TextView) convertView.findViewById(R.id.nameView);
holder.descriptionView = (TextView)convertView.findViewById(R.id.descriptionView);
holder.statView = (TextView)convertView.findViewById(R.id.statView);
convertView.setTag(holder);
else
holder = (ImageListViewHolder) convertView.getTag();


holder.nameView.setText(Utils.stripTags(config.name));
holder.descriptionView.setText(Utils.stripTags(config.description));
holder.statView.setText(config.stats());
if (MainActivity.showImages)
HttpGetImageAction.fetchImage(this.activity, config.avatar, holder.imageView);
else
holder.imageView.setVisibility(View.GONE);


return convertView;











share|improve this question















So I have been struggling with the best way to load images in a ListView in Android for a while.



The images come from a server, so can take some time to load. From what I understand there are only 2 ways to implement this:



1 - Load the images on the main thread - This leads to have the correct images display immediately when the view displays and scrolls, but gives poor scrolling performance and can lead to the app hanging and crashing.



2 - Load the images in an AsyncTask. This means the images will be blank when the list display or scroll, but eventually display. Because of caching done by the list, you can also get the wrong image for an item. But this gives good performance and scrolling, and does not hang/crash.



Seems like neither solution works correctly. There must be a solution that works?? I have seen other posts like this, but the answer seems to always be 1 or 2, but neither is a good solution...



My code for the list adapter is below.
The HttpGetImageAction.fetchImage() method either executes an async task, or fetches the image on the main thread depending on a flag I set. I also cache the images locally and on disk once they have been loaded, so the issue mainly occur the first time (but the cache is only for 100 images, and the list has 1000s)



public class ImageListAdapter extends ArrayAdapter<WebMediumConfig> 

Activity activity;

public ImageListAdapter(Activity activity, int resourceId, List<WebMediumConfig> items)
super(activity, resourceId, items);
this.activity = activity;


class ImageListViewHolder
ImageView imageView;
TextView nameView;
TextView descriptionView;
TextView statView;


public View getView(int position, View convertView, ViewGroup parent)
ImageListViewHolder holder = null;
WebMediumConfig config = getItem(position);

LayoutInflater mInflater = (LayoutInflater)this.activity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = mInflater.inflate(R.layout.image_list, null);
holder = new ImageListViewHolder();
holder.imageView = (ImageView)convertView.findViewById(R.id.imageView);
holder.nameView = (TextView) convertView.findViewById(R.id.nameView);
holder.descriptionView = (TextView)convertView.findViewById(R.id.descriptionView);
holder.statView = (TextView)convertView.findViewById(R.id.statView);
convertView.setTag(holder);
else
holder = (ImageListViewHolder) convertView.getTag();


holder.nameView.setText(Utils.stripTags(config.name));
holder.descriptionView.setText(Utils.stripTags(config.description));
holder.statView.setText(config.stats());
if (MainActivity.showImages)
HttpGetImageAction.fetchImage(this.activity, config.avatar, holder.imageView);
else
holder.imageView.setVisibility(View.GONE);


return convertView;








android listview






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 9 at 8:48









Ümañg ßürmån

2,9683829




2,9683829










asked Oct 12 at 14:46









James

20.4k75195




20.4k75195











  • Using a 3rd party library like Glide is not an option ? It loads images async, can cache them and many more, to avoid wrong image in the wrong place, you have to cancel image loading for that imageView. There are tons of tutorials on how to do this.
    – danypata
    Oct 12 at 14:51










  • is there any reason why youre not using a library for this?
    – Ogbe
    Oct 12 at 15:16










  • picasso is good
    – Igmer Rodriguez
    Oct 12 at 15:46










  • Not looking for a framework, it should not be complicated code. From my understanding the frameworks are doing async loading, so the list would display empty and slowly fill in, and does not help with having the wrong image in the wrong place. Unless there is some magic they are doing, in which case, what is this magic??
    – James
    Oct 13 at 15:46











  • FYI, if I load the images on the main thread they are there almost instantly, but if loaded async it takes several seconds for them to load.
    – James
    Oct 13 at 15:48
















  • Using a 3rd party library like Glide is not an option ? It loads images async, can cache them and many more, to avoid wrong image in the wrong place, you have to cancel image loading for that imageView. There are tons of tutorials on how to do this.
    – danypata
    Oct 12 at 14:51










  • is there any reason why youre not using a library for this?
    – Ogbe
    Oct 12 at 15:16










  • picasso is good
    – Igmer Rodriguez
    Oct 12 at 15:46










  • Not looking for a framework, it should not be complicated code. From my understanding the frameworks are doing async loading, so the list would display empty and slowly fill in, and does not help with having the wrong image in the wrong place. Unless there is some magic they are doing, in which case, what is this magic??
    – James
    Oct 13 at 15:46











  • FYI, if I load the images on the main thread they are there almost instantly, but if loaded async it takes several seconds for them to load.
    – James
    Oct 13 at 15:48















Using a 3rd party library like Glide is not an option ? It loads images async, can cache them and many more, to avoid wrong image in the wrong place, you have to cancel image loading for that imageView. There are tons of tutorials on how to do this.
– danypata
Oct 12 at 14:51




Using a 3rd party library like Glide is not an option ? It loads images async, can cache them and many more, to avoid wrong image in the wrong place, you have to cancel image loading for that imageView. There are tons of tutorials on how to do this.
– danypata
Oct 12 at 14:51












is there any reason why youre not using a library for this?
– Ogbe
Oct 12 at 15:16




is there any reason why youre not using a library for this?
– Ogbe
Oct 12 at 15:16












picasso is good
– Igmer Rodriguez
Oct 12 at 15:46




picasso is good
– Igmer Rodriguez
Oct 12 at 15:46












Not looking for a framework, it should not be complicated code. From my understanding the frameworks are doing async loading, so the list would display empty and slowly fill in, and does not help with having the wrong image in the wrong place. Unless there is some magic they are doing, in which case, what is this magic??
– James
Oct 13 at 15:46





Not looking for a framework, it should not be complicated code. From my understanding the frameworks are doing async loading, so the list would display empty and slowly fill in, and does not help with having the wrong image in the wrong place. Unless there is some magic they are doing, in which case, what is this magic??
– James
Oct 13 at 15:46













FYI, if I load the images on the main thread they are there almost instantly, but if loaded async it takes several seconds for them to load.
– James
Oct 13 at 15:48




FYI, if I load the images on the main thread they are there almost instantly, but if loaded async it takes several seconds for them to load.
– James
Oct 13 at 15:48












10 Answers
10






active

oldest

votes

















up vote
4
down vote



+100










You should never load images on the main thread. Any network calls should be done asynchronously and should not be done on the main thread. Your images might load quickly (on the main thread) because you may have a good internet connection, have small images and/or have few images. But imagine what would happen if someone using your app has a slower internet and then one day your list grows to hundreds!



The approach below is a well accepted practice for loading scrollview content



  • a) load your text content as you load the scrollview. Again the loading should be done async but you can show a loading view until the download completes

  • b) Show image
    placeholders while the image loads on each cell

  • c) Load the images
    asynchronously

Using a library such as Picasso would help immensely because there is a lot of boilerplate code which you'd need to handle otherwise such as



  • cancelling image download when a cell is reused and

  • starting a new download for a reused cell

  • caching

  • retrying a failed download

Hope this helps.






share|improve this answer




















  • any link to simple sample code for this?
    – James
    Nov 13 at 15:18

















up vote
0
down vote













Use Glide [https://github.com/bumptech/glide] or Picasso [http://square.github.io/picasso/] - both libraries are very similar, and easy to use, have caching, work in background, allow placeholders ets.
Usage is as simple as:



Picasso.get().load("http://i.imgur.com/DvpvklR.png").into(imageView);





share|improve this answer



























    up vote
    0
    down vote













    Simple Solution: Glide.




    Glide is a fast and efficient open source media management and image
    loading framework for Android that wraps media decoding, memory and
    disk caching, and resource pooling into a simple and easy to use
    interface. Glide supports fetching, decoding, and displaying video
    stills, images, and animated GIFs.




    You can load the image like:



    GlideApp.with(context)
    .load("http://via.placeholder.com/300.png")
    .into(imageView);


    Refer for more info:



    https://guides.codepath.com/android/Displaying-Images-with-the-Glide-Library
    https://github.com/bumptech/glide






    share|improve this answer



























      up vote
      0
      down vote













      Use Glide library.. Its recommended by Google.



      Step 1:



      Use latest Glide Version 4 dependency (https://github.com/bumptech/glide)




      implementation 'com.github.bumptech.glide:glide:4.8.0'



      annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'




      Step 2:



       Glide.with(MainActivity.this)
      .load(url)
      .apply(new RequestOptions().placeholder(R.drawable.placeholder).error(R.drawable.error_image))//this line optional - you can skip this line
      .into(imageview);





      share|improve this answer





























        up vote
        0
        down vote













        use picasso or Glide Library
        What these library do , is that they image url from u and download them and save it in cache so that whenever you open the same image another time it will load faster and it prevents the usage of the network



        Picasso
        http://square.github.io/picasso/



        Glide
        https://github.com/bumptech/glide






        share|improve this answer




















        • Careful, OP already said in comments he wasn't interested in Picasso
          – Ferdz
          Nov 13 at 20:29

















        up vote
        0
        down vote













        [1]. In your app level gradle implement below repository:



        implementation 'com.github.bumptech.glide:glide:3.7.0'


        [2]. Put below line where you want to load image :



        Glide.with(getApplicationContext()).load("image_url").asBitmap().centerCrop().into(new BitmapImageViewTarget(imageView)


        for more detail : https://github.com/bumptech/glide






        share|improve this answer



























          up vote
          0
          down vote













          You can try UnivarsalImageLoader which is quite Fast and Optimised.
          It supports Multithread image loading (async or sync) and high level of customization.



          https://github.com/nostra13/Android-Universal-Image-Loader






          share|improve this answer



























            up vote
            0
            down vote













            Here's how I do it



            First I always create the RecyclerView.ViewHolder to which I pass a Func<int, Bitmap> image_provider (or you can pass some sort of lamda?) which when called will retrieve the image for a specific Id, if it can't it will show the default loading image



            Everything is stored in a fragment (which I call a DataFragment) which has retainstate set to true.



            First load a list of json objects that tell me which images I must show, this happens inside the data fragment so it will go on if there is a configuration change



            I send that info to the adapter using a method like SetItems(MyImages)



            Then I start a new thread that will load the images (while allowing the user to work)



            I do this with the TPL library, the closest approximation for Android is Anko Async but you can also do it with AsyncTask, the problem is that I send a lot of messages to the main thread, so to do it with AsyncTask you have to give it a handler to the main thread which will send messages.



            In the thread I loop through all the images I have to download, and download them and send a message to the DataFragment which sends it to the currently attached Activity which triggers the NotifyItemChanged method in the adapter



            The adapter on creation receives a Func<int, Bitmap> image_provider which it invokes and retrieves the image from memory



            I know it sounds a bit messy, so if you want code examples I can give them , but they are in C#






            share|improve this answer



























              up vote
              0
              down vote













              In your app level gradle implement below repository:



              implementation 'com.squareup.picasso:picasso:2.5.2'


              Put below line where you want to load image



               Picasso.with(getApplicationContext()).load(config.avatar).into(imageview);





              share|improve this answer



























                up vote
                0
                down vote













                just use Picasso.get().load("http://i.imgur.com/DvpvklR.png").into(imageView); or
                Glide.with(getApplicationContext()).load("image_url").asBitmap().centerCrop().into(new BitmapImageViewTarget(imageView)



                in adapter like any view and done no extra efforts required






                share|improve this answer




















                  Your Answer






                  StackExchange.ifUsing("editor", function ()
                  StackExchange.using("externalEditor", function ()
                  StackExchange.using("snippets", function ()
                  StackExchange.snippets.init();
                  );
                  );
                  , "code-snippets");

                  StackExchange.ready(function()
                  var channelOptions =
                  tags: "".split(" "),
                  id: "1"
                  ;
                  initTagRenderer("".split(" "), "".split(" "), channelOptions);

                  StackExchange.using("externalEditor", function()
                  // Have to fire editor after snippets, if snippets enabled
                  if (StackExchange.settings.snippets.snippetsEnabled)
                  StackExchange.using("snippets", function()
                  createEditor();
                  );

                  else
                  createEditor();

                  );

                  function createEditor()
                  StackExchange.prepareEditor(
                  heartbeatType: 'answer',
                  convertImagesToLinks: true,
                  noModals: true,
                  showLowRepImageUploadWarning: true,
                  reputationToPostImages: 10,
                  bindNavPrevention: true,
                  postfix: "",
                  imageUploader:
                  brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
                  contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
                  allowUrls: true
                  ,
                  onDemand: true,
                  discardSelector: ".discard-answer"
                  ,immediatelyShowMarkdownHelp:true
                  );



                  );













                   

                  draft saved


                  draft discarded


















                  StackExchange.ready(
                  function ()
                  StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52781996%2fhow-to-best-load-images-from-url-in-android-listview%23new-answer', 'question_page');

                  );

                  Post as a guest















                  Required, but never shown

























                  10 Answers
                  10






                  active

                  oldest

                  votes








                  10 Answers
                  10






                  active

                  oldest

                  votes









                  active

                  oldest

                  votes






                  active

                  oldest

                  votes








                  up vote
                  4
                  down vote



                  +100










                  You should never load images on the main thread. Any network calls should be done asynchronously and should not be done on the main thread. Your images might load quickly (on the main thread) because you may have a good internet connection, have small images and/or have few images. But imagine what would happen if someone using your app has a slower internet and then one day your list grows to hundreds!



                  The approach below is a well accepted practice for loading scrollview content



                  • a) load your text content as you load the scrollview. Again the loading should be done async but you can show a loading view until the download completes

                  • b) Show image
                    placeholders while the image loads on each cell

                  • c) Load the images
                    asynchronously

                  Using a library such as Picasso would help immensely because there is a lot of boilerplate code which you'd need to handle otherwise such as



                  • cancelling image download when a cell is reused and

                  • starting a new download for a reused cell

                  • caching

                  • retrying a failed download

                  Hope this helps.






                  share|improve this answer




















                  • any link to simple sample code for this?
                    – James
                    Nov 13 at 15:18














                  up vote
                  4
                  down vote



                  +100










                  You should never load images on the main thread. Any network calls should be done asynchronously and should not be done on the main thread. Your images might load quickly (on the main thread) because you may have a good internet connection, have small images and/or have few images. But imagine what would happen if someone using your app has a slower internet and then one day your list grows to hundreds!



                  The approach below is a well accepted practice for loading scrollview content



                  • a) load your text content as you load the scrollview. Again the loading should be done async but you can show a loading view until the download completes

                  • b) Show image
                    placeholders while the image loads on each cell

                  • c) Load the images
                    asynchronously

                  Using a library such as Picasso would help immensely because there is a lot of boilerplate code which you'd need to handle otherwise such as



                  • cancelling image download when a cell is reused and

                  • starting a new download for a reused cell

                  • caching

                  • retrying a failed download

                  Hope this helps.






                  share|improve this answer




















                  • any link to simple sample code for this?
                    – James
                    Nov 13 at 15:18












                  up vote
                  4
                  down vote



                  +100







                  up vote
                  4
                  down vote



                  +100




                  +100




                  You should never load images on the main thread. Any network calls should be done asynchronously and should not be done on the main thread. Your images might load quickly (on the main thread) because you may have a good internet connection, have small images and/or have few images. But imagine what would happen if someone using your app has a slower internet and then one day your list grows to hundreds!



                  The approach below is a well accepted practice for loading scrollview content



                  • a) load your text content as you load the scrollview. Again the loading should be done async but you can show a loading view until the download completes

                  • b) Show image
                    placeholders while the image loads on each cell

                  • c) Load the images
                    asynchronously

                  Using a library such as Picasso would help immensely because there is a lot of boilerplate code which you'd need to handle otherwise such as



                  • cancelling image download when a cell is reused and

                  • starting a new download for a reused cell

                  • caching

                  • retrying a failed download

                  Hope this helps.






                  share|improve this answer












                  You should never load images on the main thread. Any network calls should be done asynchronously and should not be done on the main thread. Your images might load quickly (on the main thread) because you may have a good internet connection, have small images and/or have few images. But imagine what would happen if someone using your app has a slower internet and then one day your list grows to hundreds!



                  The approach below is a well accepted practice for loading scrollview content



                  • a) load your text content as you load the scrollview. Again the loading should be done async but you can show a loading view until the download completes

                  • b) Show image
                    placeholders while the image loads on each cell

                  • c) Load the images
                    asynchronously

                  Using a library such as Picasso would help immensely because there is a lot of boilerplate code which you'd need to handle otherwise such as



                  • cancelling image download when a cell is reused and

                  • starting a new download for a reused cell

                  • caching

                  • retrying a failed download

                  Hope this helps.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 9 at 4:43









                  Ruchira Randana

                  2,58811820




                  2,58811820











                  • any link to simple sample code for this?
                    – James
                    Nov 13 at 15:18
















                  • any link to simple sample code for this?
                    – James
                    Nov 13 at 15:18















                  any link to simple sample code for this?
                  – James
                  Nov 13 at 15:18




                  any link to simple sample code for this?
                  – James
                  Nov 13 at 15:18












                  up vote
                  0
                  down vote













                  Use Glide [https://github.com/bumptech/glide] or Picasso [http://square.github.io/picasso/] - both libraries are very similar, and easy to use, have caching, work in background, allow placeholders ets.
                  Usage is as simple as:



                  Picasso.get().load("http://i.imgur.com/DvpvklR.png").into(imageView);





                  share|improve this answer
























                    up vote
                    0
                    down vote













                    Use Glide [https://github.com/bumptech/glide] or Picasso [http://square.github.io/picasso/] - both libraries are very similar, and easy to use, have caching, work in background, allow placeholders ets.
                    Usage is as simple as:



                    Picasso.get().load("http://i.imgur.com/DvpvklR.png").into(imageView);





                    share|improve this answer






















                      up vote
                      0
                      down vote










                      up vote
                      0
                      down vote









                      Use Glide [https://github.com/bumptech/glide] or Picasso [http://square.github.io/picasso/] - both libraries are very similar, and easy to use, have caching, work in background, allow placeholders ets.
                      Usage is as simple as:



                      Picasso.get().load("http://i.imgur.com/DvpvklR.png").into(imageView);





                      share|improve this answer












                      Use Glide [https://github.com/bumptech/glide] or Picasso [http://square.github.io/picasso/] - both libraries are very similar, and easy to use, have caching, work in background, allow placeholders ets.
                      Usage is as simple as:



                      Picasso.get().load("http://i.imgur.com/DvpvklR.png").into(imageView);






                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Oct 12 at 14:53









                      thorin86

                      454717




                      454717




















                          up vote
                          0
                          down vote













                          Simple Solution: Glide.




                          Glide is a fast and efficient open source media management and image
                          loading framework for Android that wraps media decoding, memory and
                          disk caching, and resource pooling into a simple and easy to use
                          interface. Glide supports fetching, decoding, and displaying video
                          stills, images, and animated GIFs.




                          You can load the image like:



                          GlideApp.with(context)
                          .load("http://via.placeholder.com/300.png")
                          .into(imageView);


                          Refer for more info:



                          https://guides.codepath.com/android/Displaying-Images-with-the-Glide-Library
                          https://github.com/bumptech/glide






                          share|improve this answer
























                            up vote
                            0
                            down vote













                            Simple Solution: Glide.




                            Glide is a fast and efficient open source media management and image
                            loading framework for Android that wraps media decoding, memory and
                            disk caching, and resource pooling into a simple and easy to use
                            interface. Glide supports fetching, decoding, and displaying video
                            stills, images, and animated GIFs.




                            You can load the image like:



                            GlideApp.with(context)
                            .load("http://via.placeholder.com/300.png")
                            .into(imageView);


                            Refer for more info:



                            https://guides.codepath.com/android/Displaying-Images-with-the-Glide-Library
                            https://github.com/bumptech/glide






                            share|improve this answer






















                              up vote
                              0
                              down vote










                              up vote
                              0
                              down vote









                              Simple Solution: Glide.




                              Glide is a fast and efficient open source media management and image
                              loading framework for Android that wraps media decoding, memory and
                              disk caching, and resource pooling into a simple and easy to use
                              interface. Glide supports fetching, decoding, and displaying video
                              stills, images, and animated GIFs.




                              You can load the image like:



                              GlideApp.with(context)
                              .load("http://via.placeholder.com/300.png")
                              .into(imageView);


                              Refer for more info:



                              https://guides.codepath.com/android/Displaying-Images-with-the-Glide-Library
                              https://github.com/bumptech/glide






                              share|improve this answer












                              Simple Solution: Glide.




                              Glide is a fast and efficient open source media management and image
                              loading framework for Android that wraps media decoding, memory and
                              disk caching, and resource pooling into a simple and easy to use
                              interface. Glide supports fetching, decoding, and displaying video
                              stills, images, and animated GIFs.




                              You can load the image like:



                              GlideApp.with(context)
                              .load("http://via.placeholder.com/300.png")
                              .into(imageView);


                              Refer for more info:



                              https://guides.codepath.com/android/Displaying-Images-with-the-Glide-Library
                              https://github.com/bumptech/glide







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Nov 9 at 3:50









                              jitesh mohite

                              3,37411332




                              3,37411332




















                                  up vote
                                  0
                                  down vote













                                  Use Glide library.. Its recommended by Google.



                                  Step 1:



                                  Use latest Glide Version 4 dependency (https://github.com/bumptech/glide)




                                  implementation 'com.github.bumptech.glide:glide:4.8.0'



                                  annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'




                                  Step 2:



                                   Glide.with(MainActivity.this)
                                  .load(url)
                                  .apply(new RequestOptions().placeholder(R.drawable.placeholder).error(R.drawable.error_image))//this line optional - you can skip this line
                                  .into(imageview);





                                  share|improve this answer


























                                    up vote
                                    0
                                    down vote













                                    Use Glide library.. Its recommended by Google.



                                    Step 1:



                                    Use latest Glide Version 4 dependency (https://github.com/bumptech/glide)




                                    implementation 'com.github.bumptech.glide:glide:4.8.0'



                                    annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'




                                    Step 2:



                                     Glide.with(MainActivity.this)
                                    .load(url)
                                    .apply(new RequestOptions().placeholder(R.drawable.placeholder).error(R.drawable.error_image))//this line optional - you can skip this line
                                    .into(imageview);





                                    share|improve this answer
























                                      up vote
                                      0
                                      down vote










                                      up vote
                                      0
                                      down vote









                                      Use Glide library.. Its recommended by Google.



                                      Step 1:



                                      Use latest Glide Version 4 dependency (https://github.com/bumptech/glide)




                                      implementation 'com.github.bumptech.glide:glide:4.8.0'



                                      annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'




                                      Step 2:



                                       Glide.with(MainActivity.this)
                                      .load(url)
                                      .apply(new RequestOptions().placeholder(R.drawable.placeholder).error(R.drawable.error_image))//this line optional - you can skip this line
                                      .into(imageview);





                                      share|improve this answer














                                      Use Glide library.. Its recommended by Google.



                                      Step 1:



                                      Use latest Glide Version 4 dependency (https://github.com/bumptech/glide)




                                      implementation 'com.github.bumptech.glide:glide:4.8.0'



                                      annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'




                                      Step 2:



                                       Glide.with(MainActivity.this)
                                      .load(url)
                                      .apply(new RequestOptions().placeholder(R.drawable.placeholder).error(R.drawable.error_image))//this line optional - you can skip this line
                                      .into(imageview);






                                      share|improve this answer














                                      share|improve this answer



                                      share|improve this answer








                                      edited Nov 9 at 8:58

























                                      answered Nov 9 at 8:04









                                      Ranjith Kumar

                                      8,38856891




                                      8,38856891




















                                          up vote
                                          0
                                          down vote













                                          use picasso or Glide Library
                                          What these library do , is that they image url from u and download them and save it in cache so that whenever you open the same image another time it will load faster and it prevents the usage of the network



                                          Picasso
                                          http://square.github.io/picasso/



                                          Glide
                                          https://github.com/bumptech/glide






                                          share|improve this answer




















                                          • Careful, OP already said in comments he wasn't interested in Picasso
                                            – Ferdz
                                            Nov 13 at 20:29














                                          up vote
                                          0
                                          down vote













                                          use picasso or Glide Library
                                          What these library do , is that they image url from u and download them and save it in cache so that whenever you open the same image another time it will load faster and it prevents the usage of the network



                                          Picasso
                                          http://square.github.io/picasso/



                                          Glide
                                          https://github.com/bumptech/glide






                                          share|improve this answer




















                                          • Careful, OP already said in comments he wasn't interested in Picasso
                                            – Ferdz
                                            Nov 13 at 20:29












                                          up vote
                                          0
                                          down vote










                                          up vote
                                          0
                                          down vote









                                          use picasso or Glide Library
                                          What these library do , is that they image url from u and download them and save it in cache so that whenever you open the same image another time it will load faster and it prevents the usage of the network



                                          Picasso
                                          http://square.github.io/picasso/



                                          Glide
                                          https://github.com/bumptech/glide






                                          share|improve this answer












                                          use picasso or Glide Library
                                          What these library do , is that they image url from u and download them and save it in cache so that whenever you open the same image another time it will load faster and it prevents the usage of the network



                                          Picasso
                                          http://square.github.io/picasso/



                                          Glide
                                          https://github.com/bumptech/glide







                                          share|improve this answer












                                          share|improve this answer



                                          share|improve this answer










                                          answered Nov 13 at 19:57









                                          Rajat Negi

                                          1113




                                          1113











                                          • Careful, OP already said in comments he wasn't interested in Picasso
                                            – Ferdz
                                            Nov 13 at 20:29
















                                          • Careful, OP already said in comments he wasn't interested in Picasso
                                            – Ferdz
                                            Nov 13 at 20:29















                                          Careful, OP already said in comments he wasn't interested in Picasso
                                          – Ferdz
                                          Nov 13 at 20:29




                                          Careful, OP already said in comments he wasn't interested in Picasso
                                          – Ferdz
                                          Nov 13 at 20:29










                                          up vote
                                          0
                                          down vote













                                          [1]. In your app level gradle implement below repository:



                                          implementation 'com.github.bumptech.glide:glide:3.7.0'


                                          [2]. Put below line where you want to load image :



                                          Glide.with(getApplicationContext()).load("image_url").asBitmap().centerCrop().into(new BitmapImageViewTarget(imageView)


                                          for more detail : https://github.com/bumptech/glide






                                          share|improve this answer
























                                            up vote
                                            0
                                            down vote













                                            [1]. In your app level gradle implement below repository:



                                            implementation 'com.github.bumptech.glide:glide:3.7.0'


                                            [2]. Put below line where you want to load image :



                                            Glide.with(getApplicationContext()).load("image_url").asBitmap().centerCrop().into(new BitmapImageViewTarget(imageView)


                                            for more detail : https://github.com/bumptech/glide






                                            share|improve this answer






















                                              up vote
                                              0
                                              down vote










                                              up vote
                                              0
                                              down vote









                                              [1]. In your app level gradle implement below repository:



                                              implementation 'com.github.bumptech.glide:glide:3.7.0'


                                              [2]. Put below line where you want to load image :



                                              Glide.with(getApplicationContext()).load("image_url").asBitmap().centerCrop().into(new BitmapImageViewTarget(imageView)


                                              for more detail : https://github.com/bumptech/glide






                                              share|improve this answer












                                              [1]. In your app level gradle implement below repository:



                                              implementation 'com.github.bumptech.glide:glide:3.7.0'


                                              [2]. Put below line where you want to load image :



                                              Glide.with(getApplicationContext()).load("image_url").asBitmap().centerCrop().into(new BitmapImageViewTarget(imageView)


                                              for more detail : https://github.com/bumptech/glide







                                              share|improve this answer












                                              share|improve this answer



                                              share|improve this answer










                                              answered Nov 14 at 3:50









                                              Mahendra Gohil

                                              487




                                              487




















                                                  up vote
                                                  0
                                                  down vote













                                                  You can try UnivarsalImageLoader which is quite Fast and Optimised.
                                                  It supports Multithread image loading (async or sync) and high level of customization.



                                                  https://github.com/nostra13/Android-Universal-Image-Loader






                                                  share|improve this answer
























                                                    up vote
                                                    0
                                                    down vote













                                                    You can try UnivarsalImageLoader which is quite Fast and Optimised.
                                                    It supports Multithread image loading (async or sync) and high level of customization.



                                                    https://github.com/nostra13/Android-Universal-Image-Loader






                                                    share|improve this answer






















                                                      up vote
                                                      0
                                                      down vote










                                                      up vote
                                                      0
                                                      down vote









                                                      You can try UnivarsalImageLoader which is quite Fast and Optimised.
                                                      It supports Multithread image loading (async or sync) and high level of customization.



                                                      https://github.com/nostra13/Android-Universal-Image-Loader






                                                      share|improve this answer












                                                      You can try UnivarsalImageLoader which is quite Fast and Optimised.
                                                      It supports Multithread image loading (async or sync) and high level of customization.



                                                      https://github.com/nostra13/Android-Universal-Image-Loader







                                                      share|improve this answer












                                                      share|improve this answer



                                                      share|improve this answer










                                                      answered Nov 14 at 7:57









                                                      Shamsul

                                                      204210




                                                      204210




















                                                          up vote
                                                          0
                                                          down vote













                                                          Here's how I do it



                                                          First I always create the RecyclerView.ViewHolder to which I pass a Func<int, Bitmap> image_provider (or you can pass some sort of lamda?) which when called will retrieve the image for a specific Id, if it can't it will show the default loading image



                                                          Everything is stored in a fragment (which I call a DataFragment) which has retainstate set to true.



                                                          First load a list of json objects that tell me which images I must show, this happens inside the data fragment so it will go on if there is a configuration change



                                                          I send that info to the adapter using a method like SetItems(MyImages)



                                                          Then I start a new thread that will load the images (while allowing the user to work)



                                                          I do this with the TPL library, the closest approximation for Android is Anko Async but you can also do it with AsyncTask, the problem is that I send a lot of messages to the main thread, so to do it with AsyncTask you have to give it a handler to the main thread which will send messages.



                                                          In the thread I loop through all the images I have to download, and download them and send a message to the DataFragment which sends it to the currently attached Activity which triggers the NotifyItemChanged method in the adapter



                                                          The adapter on creation receives a Func<int, Bitmap> image_provider which it invokes and retrieves the image from memory



                                                          I know it sounds a bit messy, so if you want code examples I can give them , but they are in C#






                                                          share|improve this answer
























                                                            up vote
                                                            0
                                                            down vote













                                                            Here's how I do it



                                                            First I always create the RecyclerView.ViewHolder to which I pass a Func<int, Bitmap> image_provider (or you can pass some sort of lamda?) which when called will retrieve the image for a specific Id, if it can't it will show the default loading image



                                                            Everything is stored in a fragment (which I call a DataFragment) which has retainstate set to true.



                                                            First load a list of json objects that tell me which images I must show, this happens inside the data fragment so it will go on if there is a configuration change



                                                            I send that info to the adapter using a method like SetItems(MyImages)



                                                            Then I start a new thread that will load the images (while allowing the user to work)



                                                            I do this with the TPL library, the closest approximation for Android is Anko Async but you can also do it with AsyncTask, the problem is that I send a lot of messages to the main thread, so to do it with AsyncTask you have to give it a handler to the main thread which will send messages.



                                                            In the thread I loop through all the images I have to download, and download them and send a message to the DataFragment which sends it to the currently attached Activity which triggers the NotifyItemChanged method in the adapter



                                                            The adapter on creation receives a Func<int, Bitmap> image_provider which it invokes and retrieves the image from memory



                                                            I know it sounds a bit messy, so if you want code examples I can give them , but they are in C#






                                                            share|improve this answer






















                                                              up vote
                                                              0
                                                              down vote










                                                              up vote
                                                              0
                                                              down vote









                                                              Here's how I do it



                                                              First I always create the RecyclerView.ViewHolder to which I pass a Func<int, Bitmap> image_provider (or you can pass some sort of lamda?) which when called will retrieve the image for a specific Id, if it can't it will show the default loading image



                                                              Everything is stored in a fragment (which I call a DataFragment) which has retainstate set to true.



                                                              First load a list of json objects that tell me which images I must show, this happens inside the data fragment so it will go on if there is a configuration change



                                                              I send that info to the adapter using a method like SetItems(MyImages)



                                                              Then I start a new thread that will load the images (while allowing the user to work)



                                                              I do this with the TPL library, the closest approximation for Android is Anko Async but you can also do it with AsyncTask, the problem is that I send a lot of messages to the main thread, so to do it with AsyncTask you have to give it a handler to the main thread which will send messages.



                                                              In the thread I loop through all the images I have to download, and download them and send a message to the DataFragment which sends it to the currently attached Activity which triggers the NotifyItemChanged method in the adapter



                                                              The adapter on creation receives a Func<int, Bitmap> image_provider which it invokes and retrieves the image from memory



                                                              I know it sounds a bit messy, so if you want code examples I can give them , but they are in C#






                                                              share|improve this answer












                                                              Here's how I do it



                                                              First I always create the RecyclerView.ViewHolder to which I pass a Func<int, Bitmap> image_provider (or you can pass some sort of lamda?) which when called will retrieve the image for a specific Id, if it can't it will show the default loading image



                                                              Everything is stored in a fragment (which I call a DataFragment) which has retainstate set to true.



                                                              First load a list of json objects that tell me which images I must show, this happens inside the data fragment so it will go on if there is a configuration change



                                                              I send that info to the adapter using a method like SetItems(MyImages)



                                                              Then I start a new thread that will load the images (while allowing the user to work)



                                                              I do this with the TPL library, the closest approximation for Android is Anko Async but you can also do it with AsyncTask, the problem is that I send a lot of messages to the main thread, so to do it with AsyncTask you have to give it a handler to the main thread which will send messages.



                                                              In the thread I loop through all the images I have to download, and download them and send a message to the DataFragment which sends it to the currently attached Activity which triggers the NotifyItemChanged method in the adapter



                                                              The adapter on creation receives a Func<int, Bitmap> image_provider which it invokes and retrieves the image from memory



                                                              I know it sounds a bit messy, so if you want code examples I can give them , but they are in C#







                                                              share|improve this answer












                                                              share|improve this answer



                                                              share|improve this answer










                                                              answered Nov 14 at 15:38









                                                              Cruces

                                                              739619




                                                              739619




















                                                                  up vote
                                                                  0
                                                                  down vote













                                                                  In your app level gradle implement below repository:



                                                                  implementation 'com.squareup.picasso:picasso:2.5.2'


                                                                  Put below line where you want to load image



                                                                   Picasso.with(getApplicationContext()).load(config.avatar).into(imageview);





                                                                  share|improve this answer
























                                                                    up vote
                                                                    0
                                                                    down vote













                                                                    In your app level gradle implement below repository:



                                                                    implementation 'com.squareup.picasso:picasso:2.5.2'


                                                                    Put below line where you want to load image



                                                                     Picasso.with(getApplicationContext()).load(config.avatar).into(imageview);





                                                                    share|improve this answer






















                                                                      up vote
                                                                      0
                                                                      down vote










                                                                      up vote
                                                                      0
                                                                      down vote









                                                                      In your app level gradle implement below repository:



                                                                      implementation 'com.squareup.picasso:picasso:2.5.2'


                                                                      Put below line where you want to load image



                                                                       Picasso.with(getApplicationContext()).load(config.avatar).into(imageview);





                                                                      share|improve this answer












                                                                      In your app level gradle implement below repository:



                                                                      implementation 'com.squareup.picasso:picasso:2.5.2'


                                                                      Put below line where you want to load image



                                                                       Picasso.with(getApplicationContext()).load(config.avatar).into(imageview);






                                                                      share|improve this answer












                                                                      share|improve this answer



                                                                      share|improve this answer










                                                                      answered Nov 15 at 11:11









                                                                      suresh madaparthi

                                                                      24219




                                                                      24219




















                                                                          up vote
                                                                          0
                                                                          down vote













                                                                          just use Picasso.get().load("http://i.imgur.com/DvpvklR.png").into(imageView); or
                                                                          Glide.with(getApplicationContext()).load("image_url").asBitmap().centerCrop().into(new BitmapImageViewTarget(imageView)



                                                                          in adapter like any view and done no extra efforts required






                                                                          share|improve this answer
























                                                                            up vote
                                                                            0
                                                                            down vote













                                                                            just use Picasso.get().load("http://i.imgur.com/DvpvklR.png").into(imageView); or
                                                                            Glide.with(getApplicationContext()).load("image_url").asBitmap().centerCrop().into(new BitmapImageViewTarget(imageView)



                                                                            in adapter like any view and done no extra efforts required






                                                                            share|improve this answer






















                                                                              up vote
                                                                              0
                                                                              down vote










                                                                              up vote
                                                                              0
                                                                              down vote









                                                                              just use Picasso.get().load("http://i.imgur.com/DvpvklR.png").into(imageView); or
                                                                              Glide.with(getApplicationContext()).load("image_url").asBitmap().centerCrop().into(new BitmapImageViewTarget(imageView)



                                                                              in adapter like any view and done no extra efforts required






                                                                              share|improve this answer












                                                                              just use Picasso.get().load("http://i.imgur.com/DvpvklR.png").into(imageView); or
                                                                              Glide.with(getApplicationContext()).load("image_url").asBitmap().centerCrop().into(new BitmapImageViewTarget(imageView)



                                                                              in adapter like any view and done no extra efforts required







                                                                              share|improve this answer












                                                                              share|improve this answer



                                                                              share|improve this answer










                                                                              answered Nov 15 at 11:14









                                                                              Ashish Chaugule

                                                                              1,17958




                                                                              1,17958



























                                                                                   

                                                                                  draft saved


                                                                                  draft discarded















































                                                                                   


                                                                                  draft saved


                                                                                  draft discarded














                                                                                  StackExchange.ready(
                                                                                  function ()
                                                                                  StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52781996%2fhow-to-best-load-images-from-url-in-android-listview%23new-answer', 'question_page');

                                                                                  );

                                                                                  Post as a guest















                                                                                  Required, but never shown





















































                                                                                  Required, but never shown














                                                                                  Required, but never shown












                                                                                  Required, but never shown







                                                                                  Required, but never shown

































                                                                                  Required, but never shown














                                                                                  Required, but never shown












                                                                                  Required, but never shown







                                                                                  Required, but never shown







                                                                                  Popular posts from this blog

                                                                                  𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

                                                                                  Edmonton

                                                                                  Crossroads (UK TV series)