RSS Reader NullPointerException

≯℡__Kan透↙ 提交于 2019-12-12 03:49:20

问题


I have create an RSS Reader as in the following tutorial: http://techiedreams.com/android-rss-reader-part-3-action-bar-with-animated-item/

My problem is: when i load the list (with ListActivity.java), i sometimes get a NullPointerException, and i can see only the text in some listitems and the image in some other.

The logCat is:

04-07 22:01:26.900: W/System.err(22141): java.lang.NullPointerException
04-07 22:01:26.900: W/System.err(22141):    at com.td.rssreader.parser.DOMParser.parseXml(DOMParser.java:56)
04-07 22:01:26.900: W/System.err(22141):    at com.td.rssreader.ListActivity$2.run(ListActivity.java:115)
04-07 22:01:26.900: W/System.err(22141):    at java.lang.Thread.run(Thread.java:856)
04-07 22:01:26.945: D/dalvikvm(22141): GC_CONCURRENT freed 887K, 10% free 13642K/15111K, paused 2ms+13ms, total 34ms
04-07 22:01:56.425: W/IInputConnectionWrapper(22141): getSelectedText on inactive InputConnection
04-07 22:01:56.425: W/IInputConnectionWrapper(22141): setComposingText on inactive InputConnection
04-07 22:01:56.425: W/IInputConnectionWrapper(22141): getExtractedText on inactive InputConnection
04-07 22:02:03.165: W/IInputConnectionWrapper(22141): showStatusIcon on inactive InputConnection

The DOMParser class line 56 is :

theString = nchild.item(j).getFirstChild().getNodeValue();

and the ListActivity line 115 is:

        feed = tmpDOMParser.parseXml(feedLink);

What i have to do in order to make it work..?i really can't find my error here :(

edit:

ListActivity.java

public class ListActivity extends Activity {

    RSSFeed feed;
    ListView lv;
    CustomListAdapter adapter;
    String feedLink;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.feed_list);

        // set the feed link for refresh
        feedLink = new SplashActivity().RSSFEEDURL;

        // Get feed form the file
        feed = (RSSFeed) getIntent().getExtras().get("feed");

        // Initialize the variables:
        lv = (ListView) findViewById(R.id.listView);
        lv.setVerticalFadingEdgeEnabled(true);

        // Set an Adapter to the ListView
        adapter = new CustomListAdapter(this);
        lv.setAdapter(adapter);

        // Set on item click listener to the ListView
        lv.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                    long arg3) {
                // actions to be performed when a list item clicked
                int pos = arg2;

                Bundle bundle = new Bundle();
                bundle.putSerializable("feed", feed);
                Intent intent = new Intent(ListActivity.this,
                        DetailActivity.class);
                intent.putExtras(bundle);
                intent.putExtra("pos", pos);
                startActivity(intent);

            }
        });

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        new MenuInflater(this).inflate(R.menu.activity_main, menu);
        return (super.onCreateOptionsMenu(menu));
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.refresh_option:
            refreshList(item);
            return (true);

        case R.id.about_option:
            Toast.makeText(this, "RSS Reader!", Toast.LENGTH_SHORT).show();
            return (true);

        }
        return super.onOptionsItemSelected(item);
    }

    public void refreshList(final MenuItem item) {
        /* Attach a rotating ImageView to the refresh item as an ActionView */
        LayoutInflater inflater = (LayoutInflater) getApplication()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        ImageView iv = (ImageView) inflater.inflate(R.layout.action_refresh,
                null);

        Animation rotation = AnimationUtils.loadAnimation(getApplication(),
                R.anim.refresh_rotate);
        rotation.setRepeatCount(Animation.INFINITE);
        iv.startAnimation(rotation);

        item.setActionView(iv);

        // trigger feed refresh:
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                DOMParser tmpDOMParser = new DOMParser();
                feed = tmpDOMParser.parseXml(feedLink);

                ListActivity.this.runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        if (feed != null && feed.getItemCount() > 0) {
                            adapter.notifyDataSetChanged();
                            // lv.setAdapter(adapter);
                            item.getActionView().clearAnimation();
                            item.setActionView(null);
                        }
                    }
                });
            }
        });
        thread.start();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        adapter.imageLoader.clearCache();
        adapter.notifyDataSetChanged();
    }

    // List adapter class
    class CustomListAdapter extends BaseAdapter {

        private LayoutInflater layoutInflater;
        public ImageLoader imageLoader;

        public CustomListAdapter(ListActivity activity) {

            layoutInflater = (LayoutInflater) activity
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            imageLoader = new ImageLoader(activity.getApplicationContext());
        }

        @Override
        public int getCount() {

            // Set the total list item count
            return feed.getItemCount();
        }

        @Override
        public Object getItem(int position) {
            return position;
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            // Inflate the item layout and set the views
            View listItem = convertView;
            int pos = position;
            if (listItem == null) {
                listItem = layoutInflater.inflate(R.layout.list_item, null);
            }

            // Initialize the views in the layout
            ImageView iv = (ImageView) listItem.findViewById(R.id.thumb);
            TextView tvTitle = (TextView) listItem.findViewById(R.id.title);
            TextView tvDate = (TextView) listItem.findViewById(R.id.date);

            // Set the views in the layout
            imageLoader.DisplayImage(feed.getItem(pos).getImage(), iv);
            tvTitle.setText(feed.getItem(pos).getTitle());
            tvDate.setText(feed.getItem(pos).getDate());

            return listItem;
        }

    }

}

DOMParser.java

public class DOMParser {

    private RSSFeed _feed = new RSSFeed();

    public RSSFeed parseXml(String xml) {

        // _feed.clearList();

        URL url = null;
        try {
            url = new URL(xml);
        } catch (MalformedURLException e1) {
            e1.printStackTrace();
        }

        try {
            // Create required instances
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();

            // Parse the xml
            Document doc = db.parse(new InputSource(url.openStream()));
            doc.getDocumentElement().normalize();

            // Get all <item> tags.
            NodeList nl = doc.getElementsByTagName("item");
            int length = nl.getLength();

            for (int i = 0; i < length; i++) {
                Node currentNode = nl.item(i);
                RSSItem _item = new RSSItem();

                NodeList nchild = currentNode.getChildNodes();
                int clength = nchild.getLength();

                // Get the required elements from each Item
                for (int j = 1; j < clength; j = j + 2) {

                    Node thisNode = nchild.item(j);
                    String theString = null;
                    String nodeName = thisNode.getNodeName();

                    theString = nchild.item(j).getFirstChild().getNodeValue();

                    if (theString != null) {
                        if ("title".equals(nodeName)) {
                            // Node name is equals to 'title' so set the Node
                            // value to the Title in the RSSItem.
                            _item.setTitle(theString);
                        }

                        else if ("description".equals(nodeName)) {
                            _item.setDescription(theString);

                            // Parse the html description to get the image url
                            String html = theString;
                            org.jsoup.nodes.Document docHtml = Jsoup
                                    .parse(html);
                            Elements imgEle = docHtml.select("img");
                            _item.setImage(imgEle.attr("src"));
                        }
//description
                        else if ("pubDate".equals(nodeName)) {

                            // We replace the plus and zero's in the date with
                            // empty string
                            String formatedDate = theString.replace(" +0000",
                                    "");
                            _item.setDate(formatedDate);
                        }


                        if ("link".equals(nodeName)) {
                            // Node name is equals to 'title' so set the Node
                            // value to the Title in the RSSItem.
                            _item.setLink(theString);
                        }
                    }
                }

                // add item to the list
                _feed.addItem(_item);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        // Return the final feed once all the Items are added to the RSSFeed
        // Object(_feed).
        return _feed;
    }

}

回答1:


So you are getting a java.lang.NullPointerException from:

theString = nchild.item(j).getFirstChild().getNodeValue();

The issue is that you aren't null checking and just assuming everything is non null, so one of those calls in the line is returning null, and then you are trying to call another method on it. Also, you need some code organization. Here's what you have...

           for (int j = 1; j < clength; j = j + 2) {

                Node thisNode = nchild.item(j);
                String theString = null;
                String nodeName = thisNode.getNodeName();

                theString = nchild.item(j).getFirstChild().getNodeValue();
                if (theString != null) {
                       // rest of your code

Add some null checking before trying to use your objects, like this:

    for (int j = 1; j < clength; j = j + 2) {

        Node thisNode = nchild.item(j);

        String theString = null;
        if (thisNode != null && thisNode.getFirstChild() != null) {
            theString = thisNode.getFirstChild().getNodeValue();
        }

        if (theString != null) {
            String nodeName = thisNode.getNodeName();
            // rest of your code

Note: this will fix your immediate NullPointerException, you may have other mistakes and this may not fix everything (your code is still pretty assumptive), but this should solve the issue you are posting about.



来源:https://stackoverflow.com/questions/15866584/rss-reader-nullpointerexception

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!