Difficulty parsing rss feed for Android project

530 views Asked by At

I'm trying to create an RSS feed parsing app, and I am new to android programming. I currently have a Main Activity, which prompts the user to enter an rss URL, and the maxRows of the rss feed requested. I'm using the ROME library for RSS feed parsing in Java. Below is my code:

package com.xetur.simplerss;

import java.io.IOException;
import java.net.URL;
import java.util.Iterator;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.sun.syndication.feed.synd.SyndContent;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.FeedException;
import com.sun.syndication.io.SyndFeedInput;
import com.sun.syndication.io.XmlReader;

    public class ListRowsActivity extends Activity {
        private URL url;
        private int maxRows;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_list_rows);
            readFeed();
            new Thread(new Runnable() {
                public void run() {
                    readFeed();
                }
            }).start();
        }

        @SuppressWarnings("deprecation")
        private void readFeed() {
            XmlReader reader = null;

            try {
                Bundle extras = getIntent().getExtras();
                url = new URL(extras.getString("url"));
                maxRows = (Integer) extras.get("maxRows");
                reader = new XmlReader(url.openConnection());

                SyndFeed feed = new SyndFeedInput().build(reader);
                List<SyndEntry> entries = feed.getEntries();
                Iterator<SyndEntry> iEntries = entries.iterator();

                LinearLayout layout = (LinearLayout)     findViewById(R.id.list_rows_layout);

                int i = 0;
                while (i < maxRows) {
                    if (iEntries.hasNext()) {
                        SyndEntry entry = (SyndEntry) iEntries.next();
                        SyndContent content = entry.getDescription();
                        if (content != null) {
                            i++;
                            String description = content.getValue();
                            System.out.println(description);
                            TextView entryView = new TextView(getApplicationContext());
                            entryView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
                            entryView.setId((int) System.currentTimeMillis());
                            entryView.setText(description);
                            layout.addView(entryView);
                        }
                    }
                }
            } catch (IllegalArgumentException e) {
            } catch (FeedException e) {
            } catch (IOException e) {
            } finally {
                if (reader != null)
                    try {
                        reader.close();
                    } catch (IOException e) {
                    }
            }
        }
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.list_rows, menu);
            return true;
        }

    }

The keys "url" and "maxRows" are used to get the two entered values entered. However, this code does not work... Particularly, it fails at reader = new XmlReader(url.openConnection());... and I'm not sure why. The goal of this activity is simply to query the url provided, and output feed descriptions as subsequent textViews. Am I doing this correctly?

Here's the full stack trace:

09-11 17:20:11.481: W/dalvikvm(1198): threadid=1: thread exiting with uncaught exception (group=0x41465700)
09-11 17:20:11.601: E/AndroidRuntime(1198): FATAL EXCEPTION: main
09-11 17:20:11.601: E/AndroidRuntime(1198): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.xetur.simplerss/com.xetur.simplerss.ListRowsActivity}: android.os.NetworkOnMainThreadException
09-11 17:20:11.601: E/AndroidRuntime(1198):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at android.app.ActivityThread.access$600(ActivityThread.java:141)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at android.os.Handler.dispatchMessage(Handler.java:99)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at android.os.Looper.loop(Looper.java:137)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at android.app.ActivityThread.main(ActivityThread.java:5103)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at java.lang.reflect.Method.invokeNative(Native Method)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at java.lang.reflect.Method.invoke(Method.java:525)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at dalvik.system.NativeStart.main(Native Method)
09-11 17:20:11.601: E/AndroidRuntime(1198): Caused by: android.os.NetworkOnMainThreadException
09-11 17:20:11.601: E/AndroidRuntime(1198):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1133)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at java.net.InetAddress.getAllByName(InetAddress.java:214)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at libcore.net.http.HttpConnection.<init>(HttpConnection.java:70)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at libcore.net.http.HttpConnection.<init>(HttpConnection.java:50)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:340)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:87)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at libcore.net.http.HttpConnection.connect(HttpConnection.java:128)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:316)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at libcore.net.http.HttpEngine.connect(HttpEngine.java:311)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:282)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at com.sun.syndication.io.XmlReader.<init>(XmlReader.java:237)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at com.xetur.simplerss.ListRowsActivity.readFeed(ListRowsActivity.java:46)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at com.xetur.simplerss.ListRowsActivity.onCreate(ListRowsActivity.java:30)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at android.app.Activity.performCreate(Activity.java:5133)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
09-11 17:20:11.601: E/AndroidRuntime(1198):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
09-11 17:20:11.601: E/AndroidRuntime(1198):     ... 11 more
1

There are 1 answers

1
Joe Malin On BEST ANSWER

The fundamental error is

Unable to start activity ComponentInfo{com.xetur.simplerss/com.xetur.simplerss.ListRowsActivity}: android.os.NetworkOnMainThreadException 09-11 17:20:11.601: E/AndroidRuntime(1198): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211) 09-11 17:20:11.601: E/AndroidRuntime(1198): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261) 09-11 17:20:11.601: E/AndroidRuntime(1198): at

You're trying to access the network on the main thread. Looks like you're trying to create a new Thread, but it's accessing the UI on the main thread. This will cause trouble.

The Android training class RUnning in A Background Service includes a sample app that has a robust RSS feed parser. It uses an IntentService to do the read in the background and store the results in a content provider, which is the way you should do it.