0

I try to use DOM4j to phase a XML RSS feed on Android. I do add the dom4j.jar to lib\ and the user permission.

<uses-permission android:name="android.permission.INTERNET"/>

I also compile this source code in pure Java project, and it works! I'm confused if there is any restrictions on Android(if yes, what methods can I use), or only I made some mistakes.

Parts of Logcat:

03-15 23:27:10.611: W/System.err(10453): org.dom4j.DocumentException: Couldn't open http://tw.news.yahoo.com/rss/ Nested exception: Couldn't open http://tw.news.yahoo.com/rss/
03-15 23:27:10.621: W/System.err(10453):    at org.dom4j.io.SAXReader.read(SAXReader.java:484)
03-15 23:27:10.621: W/System.err(10453):    at org.dom4j.io.SAXReader.read(SAXReader.java:291)
03-15 23:27:10.621: W/System.err(10453):    at tw.danny.rss_dom4j.RSSDom4jMainActivity.onCreate(RSSDom4jMainActivity.java:28)
03-15 23:27:10.621: W/System.err(10453):    at android.app.Activity.performCreate(Activity.java:5206)
03-15 23:27:10.626: W/System.err(10453):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
03-15 23:27:10.626: W/System.err(10453):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2074)
...

Here is onCreate function in main activity:

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_rssdom4j_main);

    try {
        URL url = new URL("http://tw.news.yahoo.com/rss/");
        SAXReader saxReader = new SAXReader();
        //?
        Document document = saxReader.read(url);
        Element channel = (Element) document.getRootElement().element(
                "channel");
        for (Iterator i = channel.elementIterator("item"); i.hasNext();) {
            Element element = (Element) i.next();
            System.out.println("title: " + element.elementText("title"));

            String descrip_original = element.elementText("description");
            if (descrip_original.startsWith("<p>")) {
                // address html-like layout
                System.out.println(descrip_original.substring(
                        descrip_original.indexOf("</a>") + 4,
                        descrip_original.length() - 1));

            }

            System.out.println("link: " + element.elementText("link"));
            System.out
                    .println("pubDate: " + element.elementText("pubDate"));

            System.out.println();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Problems may occur in this line:

SAXReader saxReader = new SAXReader();
Dan
  • 301
  • 3
  • 21

1 Answers1

0

You're accessing the internet on the main UI thread. That's a no-no since Android 4.0.x. Place the code that accesses the network in an AsyncTask or spin up a new Thread for it.

new Thread( new Runnable() {
    @Override
    public void run() {
        try {
            URL url = new URL("http://tw.news.yahoo.com/rss/");
            SAXReader saxReader = new SAXReader();

            Document document = saxReader.read(url);
            Element channel = (Element) document.getRootElement().element(
                    "channel");
            for (Iterator i = channel.elementIterator("item"); i.hasNext();) {
                Element element = (Element) i.next();
                System.out.println("title: " + element.elementText("title"));

                String descrip_original = element.elementText("description");
                if (descrip_original.startsWith("<p>")) {
                    // address html-like layout
                    System.out.println(descrip_original.substring(
                            descrip_original.indexOf("</a>") + 4,
                            descrip_original.length() - 1));

                }

                System.out.println("link: " + element.elementText("link"));
                System.out
                        .println("pubDate: " + element.elementText("pubDate"));

                System.out.println();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
} ).start();
323go
  • 14,143
  • 6
  • 33
  • 41
  • Thanks a lot, it works :) I have another question. Why can't I write the phasher in another .java class , and call method like RSSPhasher.parse() in thread? – Dan Mar 16 '13 at 04:35
  • You can, as long as you invoke any network operations off the main UI thread. You'll need to be careful with SAX parsers, as they parse an input stream. If your query returns a large data set, the `read()` method might return, but subsequent parsing might access the network again. DOM parsers wouldn't have this problem, as they read/build in one sitting, but of course you have higher memory requirements there. – 323go Mar 16 '13 at 05:33