毕加索图像加载Android中的ListView令人难以置信的laggy? [英] Picasso image load incredibly laggy in android listview?

查看:194
本文介绍了毕加索图像加载Android中的ListView令人难以置信的laggy?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序,我使用的last.fm的API,毕加索和艺术家和安培; 专辑弦为一个ListView饲料获取专辑封面图片。当我通过进料滚动,它是超级laggy,我不知道为什么。如果有新的数据,一个按钮出现在屏幕上进行更新,并滚动到列表视图的顶部。当我使用毕加索获取图像,自动滚屏是令人难以置信的laggy。如果我使用的是存储PNG或东西,它工作正常。

下面是我的getView()定制适配器类方法 - 这种特殊的布局是playcut在开关壳体:

 情况下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的=新的StringBuilder(http://ws.audioscrobbler.com/2.0/);
            stringBuilder.append(法= album.getinfo?);
            stringBuilder.append(与& API_KEY =);
            stringBuilder.append(2ead17554acf667f27cf7dfd4c368f15);
            串albumURL;            尝试{
                stringBuilder.append(与&艺术家=+ URLEn coder.en code(oslist.get(位置)获得(ARTISTNAME),UTF-8));
                stringBuilder.append(与&专辑=+ URLEn coder.en code(oslist.get(位置)获得(releaseTitle),UTF-8));
                albumURL =新RetrieveAlbumArtUrlTask​​()执行(stringBuilder.toString())获得()。
                Picasso.with(上下文).load(albumURL).error(R.drawable.no_album_art).into(holder.cell_image);            }赶上(UnsupportedEncodingException五){            }赶上(InterruptedException的E){            }赶上(为ExecutionException E){            }赶上(抛出:IllegalArgumentException五){
                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(位置)获得(SONGTITLE));
            holder.artist.setText(oslist.get(位置)获得(ARTISTNAME));
            最终的RelativeLayout playcutLayout =(RelativeLayout的)convertView.findViewById(R.id.playcut);            convertView.setOnClickListener(新View.OnClickListener(){
                @覆盖
                公共无效的onClick(视图v){
                        更新视图(位置);                }
            });            convertView.setTag(保持器);
            打破;
        案例NULL_LAYOUT:

这是在同一类相关的AsyncTask方法:

 公共类RetrieveAlbumArtUrlTask​​扩展的AsyncTask<弦乐,太虚,字符串> {    保护字符串doInBackground(字符串的URL ...){
        字符串albumArtUrl = NULL;
        尝试{            XMLParser的解析器=新XMLParser的();
            字符串XML = parser.getXmlFromUrl(网址[0]); // URL从XML获得
            文档的文档= parser.getDomElement(XML);
            节点列表NL = doc.getElementsByTagName(图像);
            的for(int i = 0; I< nl.getLength();我++){
                元素e =(元)nl.item(I)                如果(e.getAttribute(大小)。contentEquals(海)){
                    albumArtUrl = parser.getElementValue(E);
                }
            }
        }赶上(例外五){
            e.printStackTrace();
        }
        返回albumArtUrl;
    }
}


解决方案

我想这是因为检索 RetrieveAlbumArtUrlTask​​ 和发生在那里(但很快它的字符串拼接可能)。

每个创建视图的时间(滚动时):


  1. getView()方法将通过开关语句

  2. 查看将由每个情况的要求绘制

  3. PlayCut 情况

    这StringBuilder的操作可以替换

     的StringBuilder的StringBuilder =新的StringBuilder(http://ws.audioscrobbler.com/2.0/);
        stringBuilder.append(法= album.getinfo?);
        stringBuilder.append(与& API_KEY =);
        stringBuilder.append(2ead17554acf667f27cf7dfd4c368f15);    串albumURL;    尝试{
            stringBuilder.append(与&艺术家=+ URLEn coder.en code(oslist.get(位置)获得(ARTISTNAME),UTF-8));
            stringBuilder.append(与&专辑=+ URLEn coder.en code(oslist.get(位置)获得(releaseTitle),UTF-8));
            albumURL =新RetrieveAlbumArtUrlTask​​()执行(stringBuilder.toString())获得()。
            Picasso.with(上下文).load(albumURL).error(R.drawable.no_album_art).into(holder.cell_image);    }赶上(UnsupportedEncodingException五){    }赶上(InterruptedException的E){    }赶上(为ExecutionException E){    }赶上(抛出:IllegalArgumentException五){
            Log.v(TEST,SUP);
            holder.cell_image.setImageResource(R.drawable.no_album_art);
        }

      //使值为恒定的场
        //\"http://ws.audioscrobbler.com/2.0/?method=album.getinfo&api_key=2ead17554acf667f27cf7dfd4c368f15&artist=%s&album=%s\"
        //也许像    私有静态最后弦乐APIURL = \"http://ws.audioscrobbler.com/2.0/?method=album.getinfo&api_key=2ead17554acf667f27cf7dfd4c368f15&artist=%s&album=%s\";    //然后使用    字符串ARTISTNAME = URLEn coder.en code(oslist.get(位置)获得(ARTISTNAME),UTF-8);
        字符串ALBUMNAME = URLEn coder.en code(oslist.get(位置)获得(ALBUMNAME),UTF-8);
        字符串albumURL =新RetrieveAlbumArtUrlTask​​()执行(的String.format(APIURL,ARTISTNAME,ALBUMNAME))得到()。    //然后用毕加索如常


我觉得在 getView字符串操作()是昂贵的,所以我想保持最低限度。

另外,你能尝试做毕加索没有加载 RetrieveAlbumArtUrlTask​​ ?如果它确实是快,然后后台任务是罪魁祸首

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

  1. The getView() method will go through the switch statement
  2. View will be drawn as requested by each case
  3. On the PlayCut case

    This stringBuilder operation can be replaced

    Old

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

    New

        //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
    

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

这篇关于毕加索图像加载Android中的ListView令人难以置信的laggy?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆