Изображение Пикассо загружается невероятно медленно в списке Android?

В своем приложении я использую строки api, picasso и «исполнитель» и «альбом» last.fm для получения изображений обложек альбомов для канала просмотра списка. Когда я прокручиваю ленту, она очень тормозит, и я не уверен, почему. Если есть новые данные, на экране появляется кнопка для обновления, и она прокручивается в верхнюю часть списка. Когда я использую Picasso для получения изображений, автоматическая прокрутка работает очень медленно. Если я использую сохраненный png или что-то еще, он работает нормально.

Вот мой метод getView () в пользовательском классе адаптера - этот конкретный макет является "playcut" в случае переключателя:

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:

И вот соответствующий метод AsyncTask в том же классе:

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

person Community    schedule 16.06.2015    source источник


Ответы (1)


Я думаю, это из-за того, что там происходит извлечение RetrieveAlbumArtUrlTask и конкатенация строк (как бы быстро это ни было).

Каждый раз, когда ваше представление создается (при прокрутке):

  1. Метод getView() выполнит инструкцию switch
  2. Вид будет отображаться по запросу каждого case
  3. На PlayCut case

    Эту операцию stringBuilder можно заменить

    Старый

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

    Новое

        //make a constant field with value 
        //"http://ws.audioscrobbler.com/2.0/?method=album.getinfo&api_key=2ead17554acf667f27cf7dfd4c368f15&artist=%s&album=%s"
        //maybe like 
    
        private static final String APIURL = "http://ws.audioscrobbler.com/2.0/?method=album.getinfo&api_key=2ead17554acf667f27cf7dfd4c368f15&artist=%s&album=%s";
    
        //then use 
    
        String artistName =  URLEncoder.encode(oslist.get(position).get("artistName"), "UTF-8");
        String albumName = URLEncoder.encode(oslist.get(position).get("albumName"), "UTF-8");
        String albumURL = new RetrieveAlbumArtUrlTask().execute(String.format(APIURL, artistName, albumName)).get();
    
        //then use picasso as usual
    

Я считаю, что операции со строками во время getView() являются дорогостоящими, поэтому я хотел бы свести их к минимуму.

Кроме того, можно попробовать выполнить загрузку Picasso без RetrieveAlbumArtUrlTask? Если это действительно быстрее, то виновата Фоновая задача.

person reidzeibel    schedule 17.06.2015