Max McKinney
Max McKinney

Reputation: 1218

Parsing XML on main thread but downloaded via AsyncTask - "Invalid stream or encoding: android.os.NetworkOnMainThreadException"

So I think I've spent all day trying to find a way to download an xml file and parse it via XMLPullParser and display the contents to a ListView. I don't know why I'm getting this system error because I'm download the XML in an AsyncTask. Should I move the parsing into the AysncTask? It doesn't seem like that should be required.

Here is my code:

public class MainActivity extends Activity {

    ListView lvNewsItems;
    NewsItemAdapter newsItemAdapter;
    ArrayList<NewsItem> newsItems;
    NewsItem item;
    InputStream urlInputStream;

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

        lvNewsItems = (ListView)findViewById(R.id.lv_newsItems);

        // Initializing instance variables
        newsItems = new ArrayList<NewsItem>();

        try {
            new URLAsyncTask().execute(new URL("http://feeds.feedburner.com/SterlingClassicalSchool?format=xml"));
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    public void ParseXMLAndShowIt(InputStream stream) {
        try {
            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            factory.setNamespaceAware(false);
            XmlPullParser xpp = factory.newPullParser();

            // We will get the XML from an input stream
            xpp.setInput(stream, "UTF_8");

            /* We will parse the XML content looking for the "<title>" tag which appears inside the "<item>" tag.
             * However, we should take in consideration that the rss feed name also is enclosed in a "<title>" tag.
             * As we know, every feed begins with these lines: "<channel><title>Feed_Name</title>...."
             * so we should skip the "<title>" tag which is a child of "<channel>" tag,
             * and take in consideration only "<title>" tag which is a child of "<item>"
             *
             * In order to achieve this, we will make use of a boolean variable.
             */
            boolean insideItem = false;

            // Returns the type of current event: START_TAG, END_TAG, etc..
            int eventType = xpp.getEventType();
            while (eventType != XmlPullParser.END_DOCUMENT) {
                if (eventType == XmlPullParser.START_TAG) {

                    if (xpp.getName().equalsIgnoreCase("item")) {
                        insideItem = true;
                        item = new NewsItem();
                    } else if (xpp.getName().equalsIgnoreCase("title")) {
                        if (insideItem)
                            item.title = xpp.nextText();
                    } else if (xpp.getName().equalsIgnoreCase("link")) {
                        if (insideItem) {}
                        //links.add(xpp.nextText()); //extract the link of article
                    }
                } else if(eventType==XmlPullParser.END_TAG && xpp.getName().equalsIgnoreCase("item")){
                    insideItem=false;
                    newsItems.add(item);
                }
                eventType = xpp.next(); //move to next element
            }

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        newsItemAdapter = new NewsItemAdapter(this, R.layout.news_item, newsItems);

        lvNewsItems.setAdapter(newsItemAdapter);

    }

    private class URLAsyncTask extends AsyncTask<URL, String, InputStream> {
        // Use the URL passed in the AysncClass and return an InputStream to be used in onPostExecute
        @Override
        protected InputStream doInBackground(URL... params) {
            try {
                Log.v("APP", "Downloading File");
                return params[0].openConnection().getInputStream();
            } catch (IOException e) {
                return null;
            }
        }

        @Override
        protected void onPostExecute(InputStream inputStream) {
            Log.v("APP", "Done downloading now parse it");
            ParseXMLAndShowIt(inputStream);
        }
    }

}

And my full error from the stack trace if you are interested:

07-01 15:49:27.773  11109-11109/com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool W/System.err﹕ Invalid stream or encoding: android.os.NetworkOnMainThreadException (position:START_DOCUMENT null@1:1 in java.io.InputStreamReader@426d1398) caused by: android.os.NetworkOnMainThreadException; nested exception is:
07-01 15:49:27.773  11109-11109/com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool W/System.err﹕ android.os.NetworkOnMainThreadException
07-01 15:49:27.773  11109-11109/com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool W/System.err﹕ at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1145)
07-01 15:49:27.773  11109-11109/com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool W/System.err﹕ at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:163)
07-01 15:49:27.773  11109-11109/com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool W/System.err﹕ at libcore.io.IoBridge.recvfrom(IoBridge.java:506)
07-01 15:49:27.773  11109-11109/com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool W/System.err﹕ at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488)
07-01 15:49:27.773  11109-11109/com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool W/System.err﹕ at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46)
07-01 15:49:27.783  11109-11109/com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool W/System.err﹕ at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240)
07-01 15:49:27.783  11109-11109/com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool W/System.err﹕ at java.io.BufferedInputStream.read(BufferedInputStream.java:283)
07-01 15:49:27.783  11109-11109/com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool W/System.err﹕ at com.android.okhttp.internal.http.HttpTransport$ChunkedInputStream.read(HttpTransport.java:441)
07-01 15:49:27.783  11109-11109/com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool W/System.err﹕ at java.io.InputStreamReader.read(InputStreamReader.java:233)
07-01 15:49:27.783  11109-11109/com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool W/System.err﹕ at org.kxml2.io.KXmlParser.fillBuffer(KXmlParser.java:1506)
07-01 15:49:27.783  11109-11109/com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool W/System.err﹕ at org.kxml2.io.KXmlParser.peekCharacter(KXmlParser.java:1460)
07-01 15:49:27.793  11109-11109/com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool W/System.err﹕ at org.kxml2.io.KXmlParser.setInput(KXmlParser.java:1735)
07-01 15:49:27.793  11109-11109/com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool W/System.err﹕ at com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool.MainActivity.ParseXMLAndShowIt(MainActivity.java:79)
07-01 15:49:27.793  11109-11109/com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool W/System.err﹕ at com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool.MainActivity$URLAsyncTask.onPostExecute(MainActivity.java:142)
07-01 15:49:27.793  11109-11109/com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool W/System.err﹕ at com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool.MainActivity$URLAsyncTask.onPostExecute(MainActivity.java:127)
07-01 15:49:27.793  11109-11109/com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool W/System.err﹕ at android.os.AsyncTask.finish(AsyncTask.java:632)
07-01 15:49:27.793  11109-11109/com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool W/System.err﹕ at android.os.AsyncTask.access$600(AsyncTask.java:177)
07-01 15:49:27.793  11109-11109/com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool W/System.err﹕ at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
07-01 15:49:27.793  11109-11109/com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:102)
07-01 15:49:27.793  11109-11109/com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool W/System.err﹕ at android.os.Looper.loop(Looper.java:136)
07-01 15:49:27.793  11109-11109/com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:5001)
07-01 15:49:27.793  11109-11109/com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool W/System.err﹕ at java.lang.reflect.Method.invokeNative(Native Method)
07-01 15:49:27.793  11109-11109/com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool W/System.err﹕ at java.lang.reflect.Method.invoke(Method.java:515)
07-01 15:49:27.793  11109-11109/com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
07-01 15:49:27.803  11109-11109/com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
07-01 15:49:27.803  11109-11109/com.doubleelite.sterlingclassicalschoolproject.sterlingclassicalschool W/System.err﹕ at dalvik.system.NativeStart.main(Native Method)

Upvotes: 2

Views: 678

Answers (1)

CommonsWare
CommonsWare

Reputation: 1006839

I don't know why I'm getting this system error because I'm download the XML in an AsyncTask.

No, you are not. You are opening a stream on a background thread. You are reading the stream on the main application thread.

Should I move the parsing into the AysncTask?

You should open the connection, download, and parse the XML from doInBackground() of your existing AsyncTask. The only pieces of your parsing method that belong in onPostExecute() are the last two lines, where you are populating the ListView.

Upvotes: 4

Related Questions