Проблема с Retrofit и Simple — попытка сделать RSS Reader для Android

Я пытаюсь загрузить XML-данные с помощью Retrofit и проанализировать их с помощью Simple, а затем загрузить в ListView.

К сожалению, загруженные данные не отображаются на экране. Может кто-нибудь сказать мне, где проблема, пожалуйста?

Это моя модель:

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

Код для интерфейса:

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

Код фрагмента:

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

Я использую конвертер, найденный здесь — я скопировал его в свой проект модификация/конвертер/SimpleXMLConverter.java

Наконец, код для адаптера:

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

РЕДАКТИРОВАТЬ: я добавил error.printStackTrace(); в методе сбоя и нашел это в 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

person M. Underhill    schedule 06.01.2015    source источник
comment
Получаете ли вы успех от Retrofit с данными в ответе?   -  person Austin Musice    schedule 06.01.2015
comment
Да, я бы зарегистрировал вывод внутри метода успешного обратного вызова;   -  person Eenvincible    schedule 06.01.2015
comment
Я делаю успешное соединение и вижу необработанные данные в logcat, по какой-то причине он, кажется, загружает их дважды. Хотя он никогда не достигает переопределенного метода успеха - я поставил внутри точку останова, и код не сломался.   -  person M. Underhill    schedule 06.01.2015
comment
Обновленный вопрос с новыми данными.   -  person M. Underhill    schedule 06.01.2015
comment
Вы уверены, что ваши данные в формате XML? см. stackoverflow.com/questions/22004975/< /а>   -  person kelvincer    schedule 07.01.2015


Ответы (3)


Это ошибка модернизации. Пожалуйста, отправьте сообщение о проблеме на GitHub по проекту.

В качестве обходного пути на данный момент не используйте универсальный тип в качестве типа верхнего уровня.

public final class ArticleList extends ArrayList<Article> {
}

public interface Service {
  @GET("/rss/news")
  public void getArticle(Callback<ArticleList> callback);
}
person Jake Wharton    schedule 06.01.2015

Ответ Джейка Уортона в конечном итоге привел меня к окончательному решению, как показано ниже. Источник проблемы действительно находился внутри типа, который был отозван. Это было неправильно написано.

Некоторые люди могут найти это полезным, кстати; Преобразование XML или JSON в классы Java Pojo — онлайн.

По умолчанию Simple рассматривает элементы как обязательные поля и строго относится к определению корневого элемента. Об этом говорится в руководстве на официальном сайте.

RSS.java

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

    public Channel getChannel() {
        return 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;

Статья.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;
person M. Underhill    schedule 10.01.2015
comment
в моем случае синтаксический анализ отлично работает с minifyEnabled=false, но не работает с minifyEnabled=true. - person Usman Rana; 17.05.2017

Я думаю, что на веб-сайте RetroFit следует четко указать: Переменные типов запрещено использовать в типах ответов.

Источник: Ошибка № 807 на GitHub.

person naXa    schedule 08.07.2015