J'ai une vue de liste qui affiche les données d'un flux RSS. Je reçois tout bien et il semble que je le veux. Le problème est la performance lors du défilement. Il est très lent avec beaucoup de décalage la plupart du temps et parfois l'application se bloque réellement parce qu'elle devient si mauvaise. Si j'enlève les images tout va bien et fonctionne bien. Que puis-je faire pour réparer cela et conserver les images?Problème de performances lors du chargement d'images à partir d'URL
Fragment:
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);
}
}
Adaptateur:
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;
}
}
Vous recherchez un chargement d'image asynchrone, un exemple: http://stackoverflow.com/questions/29080197/loading-image-using-picasso-inside-asynctask – user3802077
Sans objet, mais c'est faux: MarketUpdatesFragment.thumb [ position]! = "null" - il devrait être! "null" .equals (MarketUpdatesFragment.thumb [position]) – Francesc