In my application, I am using the last.fm api, picasso, and "artist" & "album" strings to fetch album art images for a listview feed. When I scroll through the feed, it is super laggy and I'm not sure why. If there is new data, a button appears on the screen to update, and it scrolls to the top of the listview. When I use picasso to fetch images, the auto scroll is incredibly laggy. If I am using a stored png or something, it works fine.
Here is my getView() method in custom adapter class--this particular layout is "playcut" in the switch case:
case PLAYCUT_LAYOUT: //Playcut
convertView = mInflater.inflate(R.layout.listview_cell, null);
convertView.findViewById(R.id.play).setVisibility(View.GONE);
holder.cell_image = (ImageView) convertView.findViewById(R.id.cell_image);
holder.cell_image.setImageResource(R.drawable.no_album_art);
StringBuilder stringBuilder = new StringBuilder("http://ws.audioscrobbler.com/2.0/");
stringBuilder.append("?method=album.getinfo");
stringBuilder.append("&api_key=");
stringBuilder.append("2ead17554acf667f27cf7dfd4c368f15");
String albumURL;
try{
stringBuilder.append("&artist=" + URLEncoder.encode(oslist.get(position).get("artistName"), "UTF-8"));
stringBuilder.append("&album=" + URLEncoder.encode(oslist.get(position).get("releaseTitle"), "UTF-8"));
albumURL = new RetrieveAlbumArtUrlTask().execute(stringBuilder.toString()).get();
Picasso.with(context).load(albumURL).error(R.drawable.no_album_art).into(holder.cell_image);
}catch(UnsupportedEncodingException e){
} catch(InterruptedException e){
} catch(ExecutionException e){
} catch(IllegalArgumentException e){
Log.v("TEST","SUP");
holder.cell_image.setImageResource(R.drawable.no_album_art);
}
holder.song = (TextView) convertView.findViewById(R.id.song);
holder.artist = (TextView) convertView.findViewById(R.id.artist);
holder.song.setText(oslist.get(position).get("songTitle"));
holder.artist.setText(oslist.get(position).get("artistName"));
final RelativeLayout playcutLayout = (RelativeLayout) convertView.findViewById(R.id.playcut);
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
updateView(position);
}
});
convertView.setTag(holder);
break;
case NULL_LAYOUT:
And here is a relevant AsyncTask method in that same class:
public class RetrieveAlbumArtUrlTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... urls) {
String albumArtUrl = null;
try {
XMLParser parser = new XMLParser();
String xml = parser.getXmlFromUrl(urls[0]); // getting XML from URL
Document doc = parser.getDomElement(xml);
NodeList nl = doc.getElementsByTagName("image");
for (int i = 0; i < nl.getLength(); i++) {
Element e = (Element) nl.item(i);
if(e.getAttribute("size").contentEquals("extralarge")){
albumArtUrl = parser.getElementValue(e);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return albumArtUrl;
}
}
I think it is because of the retrieve
RetrieveAlbumArtUrlTask
and the String concatenation that occurs there (however fast it might be).Each time your view is created (when scrolled) :
getView()
method will go through theswitch
statementcase
On the
PlayCut
case
This stringBuilder operation can be replaced
Old
New
I think String operations during
getView()
is costly, therefore I'd like to keep it minimum.Also, can you try doing the picasso loading without
RetrieveAlbumArtUrlTask
? If it is indeed faster, then the Background task is the culprit