RSS 提要 - 空对象引用

RSS feed - null object reference

我有一个 RSS 提要,当我更改提要源时它崩溃并出现错误:

Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference.

我查看了我的新 link 并且按照我的逻辑它应该仍然有效(所有节点都几乎相同等等)但由于某些原因它不能。

理想情况下,我想同时使用两个 link。这对我的代码来说是可能的,因为我之前一起使用过两个 link。

知道为什么这不起作用吗?

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

旧link: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);
        }
    }
}

我最好的猜测是你的 Getdata() 功能出了点问题。

这将 return 为 null,并且该 null 将通过几个创建您的 null 对象引用的函数静默传递,如所述。

当您像这样将一个 ArrayList 分配给另一个 ArrayList 时:

this.feedItems=feedItems;

它们都对数组列表有相同的引用,而不是直接分配,你应该将列表值从 feedItems 复制到 this.feedItems,例如:

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

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

该错误表明 feedItems.size() 方法是从空引用对象调用的

编辑:

你的适配器的构造函数必须是这样的:

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

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