Java RSS阅读器NullPointerException

Java RSS阅读器NullPointerException,java,android,rss,Java,Android,Rss,我已经创建了一个RSS阅读器,如以下教程所示: 我的问题是: 当我加载列表(使用ListActivity.java)时,有时会得到一个NullPointerException,我只能在一些listitems中看到文本,在另一些listitems中看到图像 logCat是: 04-07 22:01:26.900: W/System.err(22141): java.lang.NullPointerException 04-07 22:01:26.900: W/System.err(22141):

我已经创建了一个RSS阅读器,如以下教程所示:

我的问题是: 当我加载列表(使用ListActivity.java)时,有时会得到一个NullPointerException,我只能在一些listitems中看到文本,在另一些listitems中看到图像

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

    }

}
公共类ListActivity扩展活动{
RSSFeed饲料;
ListView lv;
自定义列表适配器;
串馈链;
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.feed_列表);
//将提要链接设置为刷新
feedLink=新SplashActivity().RSSFEEDURL;
//从文件中获取提要
提要=(RSSFeed)getIntent().getExtras().get(“提要”);
//初始化变量:
lv=(ListView)findViewById(R.id.ListView);
lv.setVerticalFadingEdgeEnabled(正确);
//将适配器设置为ListView
adapter=新的CustomListAdapter(此);
低压设置适配器(适配器);
//在项目上设置单击ListView的侦听器
lv.setOnItemClickListener(新的OnItemClickListener(){
@凌驾
公共链接(AdapterView arg0、视图arg1、内部arg2、,
长arg3){
//单击列表项时要执行的操作
int pos=arg2;
Bundle=新Bundle();
bundle.putSerializable(“提要”,提要);
意向意向=新意向(ListActivity.this,
活动类);
意向。额外支出(捆绑);
意向。额外(“pos”,pos);
星触觉(意向);
}
});
}
@凌驾
公共布尔onCreateOptions菜单(菜单){
新菜单充气器(此)。充气(右菜单活动主菜单);
返回(super.oncreateoptions菜单(menu));
}
@凌驾
公共布尔值onOptionsItemSelected(菜单项项){
开关(item.getItemId()){
案例R.id.refresh\u选项:
更新列表(项目);
返回(真);
案例R.id.about_选项:
Toast.makeText(这是“RSS阅读器!”,Toast.LENGTH_SHORT.show();
返回(真);
}
返回super.onOptionsItemSelected(项目);
}
公共无效刷新列表(最终菜单项){
/*将旋转图像视图作为ActionView附加到刷新项*/
LayoutFlater充气器=(LayoutFlater)getApplication()
.getSystemService(上下文布局\充气机\服务);
ImageView iv=(ImageView)充气器。充气(R.layout.action_刷新,
无效);
动画旋转=AnimationUtils.loadAnimation(getApplication(),
R.anim.刷新(旋转);
rotation.setRepeatCount(Animation.INFINITE);
iv.启动(旋转);
项目.setActionView(四);
//触发源刷新:
Thread Thread=新线程(new Runnable(){
@凌驾
公开募捐{
DOMParser tmpDOMParser=新的DOMParser();
feed=tmpDOMParser.parseXml(feedLink);
ListActivity.this.runOnUiThread(新的Runnable(){
@凌驾
公开募捐{
if(feed!=null&&feed.getItemCount()>0){
adapter.notifyDataSetChanged();
//低压设置适配器(适配器);
item.getActionView().clearAnimation();
item.setActionView(空);
}
}
});
}
});
thread.start();
}
@凌驾
受保护的空onDestroy(){
super.ondestory();
adapter.imageLoader.clearCache();
adapter.notifyDataSetChanged();
}
//列表适配器类
类CustomListAdapter扩展了BaseAdapter{
私人停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场停车场;
公共图像加载器;
公共CustomListAdapter(ListActivity活动){
layoutInflater=(layoutInflater)活动
.getSystemService(上下文布局\充气机\服务);
imageLoader=新的imageLoader(activity.getApplicationContext());
}
@凌驾
public int getCount(){
//设置总列表项计数
返回feed.getItemCount();
}
@凌驾
公共对象getItem(int位置){
返回位置;
}
@凌驾
公共长getItemId(int位置){
返回位置;
}
@凌驾
公共视图getView(int位置、视图转换视图、视图组父视图){
//充气项目布局并设置视图
查看列表项=转换视图;
int pos=位置;
如果(listItem==null){
listItem=LayoutFlater.inflate(R.layout.list\u项,空);
}
//初始化布局中的视图
ImageView iv=(ImageView)listItem.findViewById(R.id.thumb);
TextView tvTitle=(TextView)listItem.findViewById(R.id.title);
TextView tvDate=(TextView)listItem.findViewById(R.id.date);
//在布局中设置视图
imageLoader.DisplayImage(feed.getItem(pos.getImage(),iv);
setText(feed.getItem(pos.getTitle());
tvDate.setText(feed.getItem(pos.getDate());
返回列表项;
}
}
}
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;
    }

}
公共类DOMParser{
私有RSSFeed_feed=新RSSFeed();
公共RSSFeed解析xml(字符串xml){
//_饲料。
theString = nchild.item(j).getFirstChild().getNodeValue();
           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
    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