从URL加载图像时的性能问题

时间:2016-04-14 15:27:51

标签: java android listview picasso image-loading

我有一个列表视图,显示来自RSS提要的数据。我把一切都搞定了,看起来我想要它。问题是滚动时的性能。它很慢,大部分时间都有很多延迟,有时应用程序实际崩溃,因为它变得如此糟糕。如果我带走图像,一切都很顺利,工作正常。我该怎么做才能解决这个问题并保留图像?

片段:

package kyfb.android.kyfb.com.kyfb;

import android.app.Fragment;
import android.app.ListFragment;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.media.Image;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import java.io.IOException;
import java.lang.reflect.Array;
import java.net.MalformedURLException;
import java.net.URL;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

/**
 * Created by KFB on 8/12/14.
 */
public class MarketUpdatesFragment extends Fragment {

    ListView listFeed;
    ProgressBar prgLoading;
    TextView txtAlert;

    MarketUpdatesAdapter la;

    static String[] title;
    static String[] pubDate;
    static String[] link;
    static String[] thumb;

    String URLFeed;

    URL Feed;
    DocumentBuilder db;
    Document doc;
    NodeList nodeList;
    Bundle rssBundle = new Bundle();

    public MarketUpdatesFragment(){}

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        super.onCreateView(inflater, container, savedInstanceState);
        View rootView = inflater.inflate(R.layout.fragment_marketupdates, null);

        URLFeed = "https://www.kyfb.com/index.cfm/_api/feed/v1/KYFB/?feedID=62BDAE63-9862-79EC-82AA7CE0C82E8B26";


        Context ctx = rootView.getContext();

        la = new MarketUpdatesAdapter(ctx);

        listFeed = (ListView) rootView.findViewById(R.id.listFeed);
        prgLoading = (ProgressBar) rootView.findViewById(R.id.prgLoading);
        txtAlert = (TextView) rootView.findViewById(R.id.txtAlert);

        ColorDrawable whiteColor = new ColorDrawable(Color.WHITE);
        ColorDrawable blackColor = new ColorDrawable(Color.BLACK);
        listFeed.setDivider(whiteColor);
        listFeed.setDividerHeight(3);

        new getDataTask().execute();

        listFeed.setOnItemClickListener(new OnItemClickListener() {

            public void onItemClick(AdapterView<?> arg0, View arg1, int position,
                                    long arg3) {
                // TODO Auto-generated method stub

                Intent web = new Intent(getActivity(), WebBrowser.class);
                rssBundle.putString("myURL", link[position]);
                web.putExtras(rssBundle);
                startActivity(web);
            }
        });

        return rootView;
    }

    /** this class is used to handle thread */
    public class getDataTask extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
        }

        @Override
        protected Void doInBackground(Void... arg0) {
            // TODO Auto-generated method stub
            getDataFromFeed();

            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            // TODO Auto-generated method stub
            //dialog.dismiss();
            prgLoading.setVisibility(8);
            if(title != null){
                listFeed.setVisibility(0);
                listFeed.setAdapter(la);
            }else{
                txtAlert.setVisibility(0);
            }
        }
    }

    /*
     * This code is used to get data from feed and store them
     * to array attributes
     */
    public void getDataFromFeed(){

        try {
            Feed = new URL(URLFeed);
            DocumentBuilderFactory dbf= DocumentBuilderFactory.newInstance();
            db = dbf.newDocumentBuilder();
            doc = db.parse(new InputSource(Feed.openStream()));
            doc.getDocumentElement().normalize();
            nodeList = doc.getElementsByTagName("item");

            title = new String[nodeList.getLength()];
            pubDate = new String[nodeList.getLength()];
            link = new String[nodeList.getLength()];
            thumb = new String[nodeList.getLength()];

            for(int i = 0; i < nodeList.getLength(); i++) {
                Node node = nodeList.item(i);

                Element fstElmnt = (Element) node;

                NodeList titleList = fstElmnt.getElementsByTagName("title");
                Element titleElement = (Element) titleList.item(0);
                titleList = titleElement.getChildNodes();
                title[i] = ((Node) titleList.item(0)).getNodeValue();

                NodeList pubDateList = fstElmnt.getElementsByTagName("pubDate");
                Element pubDateElement = (Element) pubDateList.item(0);
                pubDateList = pubDateElement.getChildNodes();
                pubDate[i] = ((Node) pubDateList.item(0)).getNodeValue();
                // chops off the " +0000" on date
                pubDate[i] = pubDate[i].substring(0, pubDate[i].length()-14);

                NodeList linkList = fstElmnt.getElementsByTagName("link");
                Element linkElement = (Element) linkList.item(0);
                linkList = linkElement.getChildNodes();
                link[i] = ((Node) linkList.item(0)).getNodeValue();
            }

            NodeList nodes = doc.getElementsByTagName("enclosure");
            for (int i = 0; i < nodes.getLength(); i++) {
                Element thumbElement = (Element)nodes.item(i);
                String thumbURL = thumbElement.getAttribute("url");
                if (thumbURL.equals("")) {
                    thumb[i] = "null";
                } else {
                    String httpURL = thumbURL;
                    String httpsURL = httpURL.toString().replace("http", "https");
                    thumb[i] = httpsURL;
                }

                // System.out.println(thumb[i]);
            }

        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }catch (ParserConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @Override
    public void onConfigurationChanged(final Configuration newConfig)
    {
        // Ignore orientation change to keep activity from restarting
        super.onConfigurationChanged(newConfig);
    }
}

适配器:

package kyfb.android.kyfb.com.kyfb;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Path;
import android.graphics.Rect;
import android.media.Image;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.squareup.picasso.Picasso;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * Created by KFB on 8/12/14.
 */
class MarketUpdatesAdapter extends BaseAdapter {
    private LayoutInflater inflater;

    public MarketUpdatesAdapter(Context context) {

        inflater = LayoutInflater.from(context);
    }

    public int getCount() {
        // TODO Auto-generated method stub

        return MarketUpdatesFragment.title.length;
    }

    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
        ViewHolder holder;

        if(convertView == null){
            convertView = inflater.inflate(R.layout.item_feed, null);
            holder = new ViewHolder();
            holder.lytItemFeed = (RelativeLayout) convertView.findViewById(R.id.lytItemFeed);
            holder.txtTitle= (TextView) convertView.findViewById(R.id.txtTitle);
            holder.txtPubDate = (TextView) convertView.findViewById(R.id.txtPubDate);
            holder.thumbnail = (ImageView) convertView.findViewById(R.id.thumbnail);

            convertView.setTag(holder);
        }else{
            holder = (ViewHolder) convertView.getTag();
        }

        holder.lytItemFeed.setBackgroundColor(Color.TRANSPARENT);

        holder.txtTitle.setText(MarketUpdatesFragment.title[position]);
        holder.txtPubDate.setText(MarketUpdatesFragment.pubDate[position]);

        Context context = parent.getContext();
        if (MarketUpdatesFragment.thumb[position] != "null") {

            Picasso.with(context)
                    .load(MarketUpdatesFragment.thumb[position])
                    .placeholder(R.drawable.placeholder)
                    .error(R.drawable.placeholder)
                    .into(holder.thumbnail);
        } else {
            holder.thumbnail.setImageResource(R.drawable.placeholder);
        }

        holder.txtTitle.setTextColor(Color.WHITE);
        holder.txtPubDate.setTextColor(Color.WHITE);

        return convertView;
    }

    static class ViewHolder {
        TextView txtTitle, txtPubDate;
        ImageView thumbnail;
        RelativeLayout lytItemFeed;
    }
}

1 个答案:

答案 0 :(得分:1)

这已成为毕加索的一个问题。有关讨论,请参阅this链接。

滚动时,您需要阻止Picasso加载图像。我认为这个功能已经集成到Picasso库中。

尝试此代码有帮助,

listFeed.setOnScrollListener(new PicassoScrollListener(context));

另请参阅this SO主题以获取更多信息。