Problema con Retrofit y simple – intento de hacer un lector de RSS para Android

Estoy tratando de descargar datos XML con Retrofit y analizarlo con Simple y luego cargarlo en un ListView.

Lamentablemente, los datos descargados no aparecerán en la pantalla. ¿Podría alguien decirme dónde está el problema, por favor?

Este es mi modelo:

@Root(name = "item") public class Article { @Element(name = "title") private String title; @Element(name = "author") private String author; @Element(name = "description") private String description; 

El código para la interfaz:

 public interface Service { @GET("/rss/news") public void getArticle(Callback<List<Article>> callback); } 

El código para el fragmento:

 public class ArticlePreviewFragment extends Fragment { protected ArticlePreviewAdapter adapter; protected List<Article> previewList; private ListView listView; public ArticlePreviewFragment() {} @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); previewList = new ArrayList<>(); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_article_preview, container, false); listView = (ListView) view.findViewById(R.id.previewList); return view; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); adapter = new ArticlePreviewAdapter(getActivity(), previewList); listView.setAdapter(adapter); RestAdapter restAdapter = new RestAdapter.Builder() .setLogLevel(RestAdapter.LogLevel.FULL) .setEndpoint("http://muse.mu") .setConverter(new SimpleXMLConverter()) .build(); Service service = restAdapter.create(Service.class); Callback<List<Article>> callback = new Callback<List<Article>>() { @Override public void success(List<Article> articles, Response response) { adapter.clear(); adapter.addAll(articles); adapter.notifyDataSetChanged(); } @Override public void failure(RetrofitError error) }; service.getArticle(callback); } } 

Estoy usando el convertidor encontrado aquí – Lo he copiado en mi proyecto retrofit / converter / SimpleXMLConverter.java

Por último, el código para el adaptador:

 public class ArticlePreviewAdapter extends ArrayAdapter<Article> { List<Article> articlePreviewItems; public ArticlePreviewAdapter(Activity activity, List<Article> articlePreviewItems) { super(activity, R.layout.item_article_preview, articlePreviewItems); this.articlePreviewItems = articlePreviewItems; } private static class ViewHolder { TextView articlePreviewTitle; TextView articlePreviewAuthor; TextView articlePreviewDescription; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder; Article articlePreviewItem = getItem(position); if (convertView == null) { viewHolder = new ViewHolder(); LayoutInflater inflater = LayoutInflater.from(getContext()); convertView = inflater.inflate(R.layout.item_article_preview, parent, false); viewHolder.articlePreviewTitle = (TextView) convertView.findViewById(R.id.articleTitle); viewHolder.articlePreviewAuthor = (TextView) convertView.findViewById(R.id.articleAuthor); viewHolder.articlePreviewDescription = (TextView) convertView.findViewById(R.id.articleDescription); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } viewHolder.articlePreviewTitle.setText(articlePreviewItem.getTitle()); viewHolder.articlePreviewAuthor.setText(articlePreviewItem.getAuthor()); viewHolder.articlePreviewDescription.setText(articlePreviewItem.getDescription()); return convertView; } } 

EDIT: He añadido error.printStackTrace (); en el método de fallo y encontró esto en logcat:

 rss.reader W/System.err﹕ retrofit.RetrofitError: java.lang.ClassCastException: libcore.reflect.ParameterizedTypeImpl cannot be cast to java.lang.Class rss.reader W/System.err﹕ at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:378) rss.reader W/System.err﹕ at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220) rss.reader W/System.err﹕ at retrofit.RestAdapter$RestHandler$2.obtainResponse(RestAdapter.java:278) rss.reader W/System.err﹕ at retrofit.CallbackRunnable.run(CallbackRunnable.java:42) rss.reader W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) rss.reader W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) rss.reader W/System.err﹕ at retrofit.Platform$Android$2$1.run(Platform.java:142) rss.reader W/System.err﹕ at java.lang.Thread.run(Thread.java:818) rss.reader W/System.err﹕ Caused by: retrofit.converter.ConversionException: java.lang.ClassCastException: libcore.reflect.ParameterizedTypeImpl cannot be cast to java.lang.Class rss.reader W/System.err﹕ at rss.reader.SimpleXMLConverter.fromBody(SimpleXMLConverter.java:39) rss.reader W/System.err﹕ at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:362) rss.reader W/System.err﹕ ... 7 more rss.reader W/System.err﹕ Caused by: java.lang.ClassCastException: libcore.reflect.ParameterizedTypeImpl cannot be cast to java.lang.Class rss.reader W/System.err﹕ at rss.reader.SimpleXMLConverter.fromBody(SimpleXMLConverter.java:37) rss.reader W/System.err﹕ ... 8 more rss.reader W/System.err﹕ retrofit.RetrofitError: java.lang.ClassCastException: libcore.reflect.ParameterizedTypeImpl cannot be cast to java.lang.Class rss.reader W/System.err﹕ at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:378) rss.reader W/System.err﹕ at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220) rss.reader W/System.err﹕ at retrofit.RestAdapter$RestHandler$2.obtainResponse(RestAdapter.java:278) rss.reader W/System.err﹕ at retrofit.CallbackRunnable.run(CallbackRunnable.java:42) rss.reader W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) rss.reader W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) rss.reader W/System.err﹕ at retrofit.Platform$Android$2$1.run(Platform.java:142) rss.reader W/System.err﹕ at java.lang.Thread.run(Thread.java:818) rss.reader W/System.err﹕ Caused by: retrofit.converter.ConversionException: java.lang.ClassCastException: libcore.reflect.ParameterizedTypeImpl cannot be cast to java.lang.Class rss.reader W/System.err﹕ at rss.reader.SimpleXMLConverter.fromBody(SimpleXMLConverter.java:39) rss.reader W/System.err﹕ at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:362) rss.reader W/System.err﹕ ... 7 more rss.reader W/System.err﹕ Caused by: java.lang.ClassCastException: libcore.reflect.ParameterizedTypeImpl cannot be cast to java.lang.Class rss.reader W/System.err﹕ at rss.reader.SimpleXMLConverter.fromBody(SimpleXMLConverter.java:37) rss.reader W/System.err﹕ ... 8 more 

Este es un error de Retrofit. Por favor archive un problema de GitHub en el proyecto.

Como solución, por el momento, no utilice un tipo genérico como el tipo de nivel superior.

 public final class ArticleList extends ArrayList<Article> { } public interface Service { @GET("/rss/news") public void getArticle(Callback<ArticleList> callback); } 

La respuesta de Jake Wharton finalmente me llevó a la solución final como se muestra a continuación. La fuente del problema de hecho mintió dentro del tipo que se llamó de nuevo. Estaba mal escrito.

Algunas personas pueden encontrar esta btw útil; Convertir XML o JSON a Java Pojo Classes – en línea .

Por defecto, Simple trata los elementos como campos obligatorios y es estricto cuando se trata de la definición del elemento raíz. Esto se menciona en el tutorial en el sitio oficial.

RSS.java

 @Root(name = "rss", strict = false) public class RSS { @Element private Channel channel; @Attribute private String version; public Channel getChannel() { return channel; } } 

Channel.java

 @Root(name = "channel", strict = false) public class Channel { @ElementList(name = "item", inline = true) List<Article> articleList; @Element private String title; @Element private String link; @Element private String description; 

Artículo.java

 @Root(name = "item", strict = false) public class Article { @Element private String title; @Element private String description; @Element private String link; @Element(required = false) private String author; @Element(required = false) private String pubDate; 

Creo que se debe señalar claramente en el sitio web de RetroFit: Las variables de tipo se prohíben usar en tipos de respuesta .

Fuente: Edición # 807 en GitHub.

  • XML con la biblioteca SimpleXML - Rendimiento en Android
  • Uso conveniente de Android XmlResourceParser?
  • Retrofit2 + SimpleXML en Kotlin: MethodException: La anotación debe marcar un método set o get
  • Cómo port jaxb anotación a la biblioteca simpleXml?
  • Cómo generar simple-xml java objeto anotado desde el esquema xsd
  • No se puede crear un conversor para mi clase en Android Retrofit2 converter-simplexml library
  • Problema de velocidad de Android con la deserialización mediante SimpleXML
  • La ofuscación de Proguard está rompiendo simplexml
  • SimpleXML falla en Lenovo P90
  • Android: error que incluye / reempaque las dependencias que hacen referencia a las clases principales de javax
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.