Theo
Theo

Reputation: 3139

RSS feed Null Pointer Exception

Basically I created a separated RSS which works. I used DOMParsing and a custom adapter for the listview appearance. But now I decided that I want to have that list under a Tab representing a specific category of an rss feed(ie breaking news,educational new and so on). Here is my code.

public class FragmentA extends ListFragment {

ListView listView;
ArrayList<RowItem> items;

@Override
public void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    // Inflate the layout for this fragment


    return inflater.inflate(R.layout.fragment_a, container, false);
}


@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onActivityCreated(savedInstanceState);

                    listView = (ListView)getView().findViewById(R.id.list_item);
                    //listView.setOnItemClickListener(this);

                    // create the RowItem list - used for storing one news feed
                    items = new ArrayList<RowItem>();

                    // start the background task to get the news feed
                    //new DownloadXMLTask(items).execute("http://feeds.bbci.co.uk/news/rss.xml");

    new DownloadXMLTask(items).execute("http://www.nasa.gov/rss/dyn/breaking_news.rss");
}


private class RowItem {
    String title = null;
    String description = null;
    String url = null;

    public RowItem(String title,String url,String description) {
        this.title = title;
        this.description = description;
        this.url = url;
    }




}

private class DownloadXMLTask extends AsyncTask<String, Void, String> {

    ArrayList<RowItem> items = null;

    public DownloadXMLTask(ArrayList<RowItem> items) {
        this.items = items;
    }

    // local helper method
    private String getNodeValue(Element entry, String tag) {
        Element tagElement = (Element) entry.getElementsByTagName(tag).item(0);
        return tagElement.getFirstChild().getNodeValue();
    }

    private String downloadAndParseXML(String url) {
        try {
            InputStream in = new java.net.URL(url).openStream();

            // build the XML parser
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            // parse and get XML elements
            Document dom = db.parse(in);
            Element documentElement = dom.getDocumentElement();

            // we want all XML children called 'item'
            NodeList nodes = documentElement.getElementsByTagName("item");

            // for each 'item' do the following
            for (int i = 0; i < nodes.getLength(); i++) {
                Element entry = (Element) nodes.item(i);

                // get the nodes from 'item' that you need
                String title = getNodeValue(entry, "title");
                //String description = getNodeValue(entry, "description");
                String link = getNodeValue(entry, "link");
                String description = getNodeValue(entry, "description");
                // add them to your list
                items.add(new RowItem(title,link,description));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    protected String doInBackground(String... urls) {
        if (urls.length <= 0)
            return null;
        return downloadAndParseXML(urls[0]);
    }

    protected void onPostExecute(String result) {
        updateList(items);
    }
}

public void updateList(ArrayList<RowItem> items) {
    CustomArrayAdapter adapter = new CustomArrayAdapter(getActivity(),
            R.layout.row, items);
    listView.setAdapter(adapter);
}

// class used to have custom view for the list item
private class CustomArrayAdapter extends ArrayAdapter<RowItem> {
    Context context;
    List<RowItem> items;

    private class ViewHolder {
        public TextView title;
        public TextView description;
    }

    public CustomArrayAdapter(Context context, int resource,
            List<RowItem> items) {
        super(context, resource, items);
        this.context = context;
        this.items = items;
    }

    @Override
    public View getView(int position, View rowView, ViewGroup parent) {
        // reuse the rowView if possible - for efficiency and less memory consumption
        if (rowView == null) {

            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            rowView = inflater.inflate(R.layout.row, null);
            // configure view holder
            ViewHolder viewHolder = new ViewHolder();
            viewHolder.title = (TextView) rowView.findViewById(R.id.title);
            viewHolder.description = (TextView) rowView.findViewById(R.id.desc);

            rowView.setTag(viewHolder);
        }
        // set the view
        ViewHolder holder = (ViewHolder) rowView.getTag();
        RowItem item = items.get(position);
        holder.title.setText(item.title);
        holder.description.setText(item.description);


        return rowView;
    }
 }
}   

I get a NullPointer Exception inside the updatelist method which used to update the list of the retrieved data(title,ulr,link)..Obviously they are not but I can't think anything at the moment how to fix it.

    09-21 16:07:41.310: E/AndroidRuntime(3678): FATAL EXCEPTION: main
    09-21 16:07:41.310: E/AndroidRuntime(3678): java.lang.NullPointerException
    09-21 16:07:41.310: E/AndroidRuntime(3678): at
    com.example.tabstesting.FragmentA.updateList(FragmentA.java:159)
    09-21 16:07:41.310: E/AndroidRuntime(3678):at    

    com.example.tabstesting.FragmentA$DownloadXMLTask.onPostExecute(FragmentA.java:152)

    09-21 16:07:41.310: E/AndroidRuntime(3678):     at  
    com.example.tabstesting.FragmentA$DownloadXMLTask.onPostExecute(FragmentA.java:1)
    09-21 16:07:41.310: E/AndroidRuntime(3678):     at  
    android.os.AsyncTask.finish(AsyncTask.java:631)

    09-21 16:07:41.310: E/AndroidRuntime(3678):     at  
    android.os.AsyncTask.access$600(AsyncTask.java:177)

Thank you in advance and sorry for the long code.

Upvotes: 1

Views: 263

Answers (1)

nem035
nem035

Reputation: 35491

Ok, so I think I know what your problem is.

Inside fragment_a.xml, you are declaring the ListView as:

<ListView 
    android:id="@android:id/list"
    // ... rest of properties
</ListView>

The first problem is that you are saying:

android:id="@android:id/list" 

Which will use the ID "list" from the package android and not from your own resources. That is why it is not recognized in your code. Furthermore, you tried accessing element with id list_item which isn't even present in your layout so you get a NullPointerException because listView is null.

So, in your code where you are obtaining the ListView, you should change:

listView = (ListView)getView().findViewById(R.id.list_item);

To:

listView = (ListView)getView().findViewById(android.R.id.list);

Upvotes: 1

Related Questions