RSS提要 - null对象引用

时间:2017-04-23 21:51:52

标签: java android xml nullpointerexception rss

我有一个RSS Feed,当我更改了Feed的来源时,它会因错误而崩溃:

  

尝试在空对象引用上调用虚方法'int java.util.ArrayList.size()'。

我查看了我的新链接和我的逻辑它应该仍然有效(所有节点几乎相同等)但由于某种原因它没有。

理想情况下,我想将两个链接一起使用。我的代码可以实现,因为之前我曾使用过两个链接。

为什么这不起作用?

新链接(我正在尝试使用):https://feeds.finance.yahoo.com/rss/2.0/headline?s=yhoo,msft,tivo&region=US&lang=en-US

旧链接:https://www.bloomberg.com/politics/feeds/site.xml

RSSFeed.java:

public class ReadRss extends AsyncTask<Void,Void,Void>{
ArrayList<FeedItem>feedItems;
RecyclerView recyclerView;
Context context;
static ArrayList<String>address;

static {
    address=new ArrayList<>();
   address.add("http://finance.yahoo.com/rss/headline?s=yhoo,msft,tivo");
   //address.add("https://www.bloomberg.com/politics/feeds/site.xml");
    //address.add("https://www.bloomberg.com/feeds/podcasts/etf_report.xml");
}

ProgressDialog progressDialog;
URL url;
public ReadRss(Context context, RecyclerView recyclerView){
    this.recyclerView=recyclerView;
    this.context=context;
    progressDialog=new ProgressDialog(context);
    progressDialog.setMessage("Loading...");
}

@Override
protected void onPreExecute() {
    progressDialog.show();
    super.onPreExecute();
}

@Override
protected void onPostExecute(Void aVoid) {

    super.onPostExecute(aVoid);
    progressDialog.dismiss();
    MyAdapter adapter=new MyAdapter(context,feedItems);
    recyclerView.setLayoutManager(new LinearLayoutManager(context));
    recyclerView.addItemDecoration(new VerticalSpace(50));
    recyclerView.setAdapter(adapter);
}

@Override
protected Void doInBackground(Void... params) {
    ProcessXml(Getdata());
    return null;
}

private void ProcessXml(ArrayList<Document> data) {
    if (data != null) {
        feedItems = new ArrayList<>();
        for (Document doc : data) {
            Element root = doc.getDocumentElement();
            Node channel = root.getChildNodes().item(0);
            NodeList items = channel.getChildNodes();
            for (int i = 0; i < items.getLength(); i++) {
                Node currentchild = items.item(i);
                if (currentchild.getNodeName().equalsIgnoreCase("item")) {
                    FeedItem item = new FeedItem();
                    NodeList itemchilds = currentchild.getChildNodes();
                    for (int j = 0; j < itemchilds.getLength(); j++) {
                        Node current = itemchilds.item(j);
                        if (current.getNodeName().equalsIgnoreCase("title")) {
                            item.setTitle(current.getTextContent());
                        } else if (current.getNodeName().equalsIgnoreCase("description")) {
                            item.setDescription(current.getTextContent());
                        } else if (current.getNodeName().equalsIgnoreCase("pubDate")) {
                            item.setPubDate(current.getTextContent());
                        } else if (current.getNodeName().equalsIgnoreCase("link")) {
                            item.setLink(current.getTextContent());
                        }

                    }
                    feedItems.add(item);
                    Log.d("itemTitle", item.getTitle());
                    Log.d("itemDescription", item.getTitle());
                    Log.d("itemLink", item.getTitle());
                    Log.d("itemPubDate", item.getTitle());
                }
            }
        }
    }
}

public ArrayList<Document> Getdata(){
    ArrayList<Document> documents = new ArrayList<>();
    for (String addr: address) {
        try {
            url = new URL(addr);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            InputStream inputStream = connection.getInputStream();
            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = builderFactory.newDocumentBuilder();
            Document xmlDoc = builder.parse(inputStream);
            documents.add(xmlDoc);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    return documents;
}

}

MyAdapter.java:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder>{
    ArrayList<FeedItem>feedItems;
    Context context;
     public MyAdapter(Context context,ArrayList<FeedItem>afeedItems){
        this.feedItems= new ArrayList<FeedItem>(afeedItems);
        this.context=context;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view= LayoutInflater.from(context).inflate(R.layout.custum_row_news_item,parent,false);
        MyViewHolder holder=new MyViewHolder(view);
        return holder;

    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        YoYo.with(Techniques.FadeIn).playOn(holder.cardView);
        final FeedItem current=feedItems.get(position);
        holder.Title.setText(current.getTitle());
        holder.Description.setText(current.getDescription());
        holder.Date.setText(current.getPubDate());
        holder.cardView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(context, NewsDetails.class);
                intent.putExtra("Link", current.getLink());
                context.startActivity(intent);
            }
        });

    }

    @Override
    public int getItemCount() {
        return feedItems.size();
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {
        TextView Title,Description,Date;
        CardView cardView;
        public MyViewHolder(View itemView) {
            super(itemView);
            Title= (TextView) itemView.findViewById(R.id.title_text);
            Description=(TextView) itemView.findViewById(R.id.description_text);
            Date=(TextView) itemView.findViewById(R.id.date_text);
            cardView= (CardView) itemView.findViewById(R.id.cardview);
        }
    }
}

2 个答案:

答案 0 :(得分:2)

将ArrayList分配给另一个时,如下所示:

this.feedItems=feedItems;

他们对arraylist都有相同的参考,而不是直接分配,你应该将列表值从feedItems复制到this.feedItems,例如:

ArrayList<FeedItem> newFeedItems = new ArrayList<FeedItem>(oldFeedItems);

执行asynctask完成后,将释放asynctask类的对象feedItems,然后您的适配器类的feedItems也将被引用为空值

该错误表示从空引用对象

调用feedItems.size()方法

编辑:

适配器的构造函数必须如下:

public MyAdapter(Context context,ArrayList<FeedItem>afeedItems){
    this.feedItems= new ArrayList<FeedItem>(afeedItems);
    this.context=context;
}

另一个建议是不要对多个变量使用完全相同的名称

答案 1 :(得分:0)

我最好的猜测是Getdata()函数出现了问题。

这将返回null,并且null将通过几个函数以无提示方式传递,如上所述创建空对象引用。