0

我在以下教程中创建了一个 RSS 阅读器:http: //techiedreams.com/android-rss-reader-part-3-action-bar-with-animated-item/

我的问题是:当我加载列表(使用 ListActivity.java)时,有时会出现 NullPointerException,我只能看到某些列表项中的文本和其他列表项中的图像。

logCat 是:

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

DOMParser 类第 56 行是:

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

ListActivity 第 115 行是:

        feed = tmpDOMParser.parseXml(feedLink);

我必须做些什么才能使它工作..?我真的在这里找不到我的错误:(

编辑:

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

}
4

1 回答 1

3

所以你得到一个java.lang.NullPointerException来自:

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

问题是您没有null检查并且只是假设所有内容都是 non null,因此该行中的其中一个调用正在返回null,然后您尝试对其调用另一种方法。此外,您需要一些代码组织。这就是你所拥有的...

           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

null在尝试使用您的对象之前添加一些检查,如下所示:

    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

注意:这将解决您的即时问题NullPointerException,您可能还有其他错误,并且这可能无法解决所有问题(您的代码仍然很假设),但这应该可以解决您发布的问题。

于 2013-04-07T19:32:56.897 回答