Getting error while loading XML using AsyncTask

198 Views Asked by At

I want to download XML file from some URL and use it like input for my XMLPullParser.

XML is big - about 6-8Mb.

So I wrote AsyncTask for downloading XML and call it in my code, but I have got NullPointerException:

java.lang.RuntimeException: Unable to start activity java.lang.NullPointerException: Attempt to invoke interface method 'void org.xmlpull.v1.XmlPullParser.setInput(java.io.InputStream, java.lang.String)' on a null object reference

Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'void org.xmlpull.v1.XmlPullParser.setInput(java.io.InputStream, java.lang.String)' on a null object reference

Here starts my Activity and AsynTask:

public class Parsing extends AppCompatActivity {
    private final static String url = "http://validURL";
    InputStream parserInput;
    XmlPullParser parser;

    protected void onCreate(Bundle savedInstanceState) {
...
        try {
            parserInput = new GetXML(this).execute(url).get();
        } catch (ExecutionException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (XmlPullParserException e) {
            e.printStackTrace();
        }
...
}
    class GetXML extends AsyncTask<String, Void, InputStream> {
        private Parsing activity;
        private String url;
        private ProgressDialog pDialog;

        public GetXML(Parsing activity/*, String url*/) {
            this.activity = activity;
            this.url = url;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pDialog = new ProgressDialog(activity);
            pDialog.setTitle("Getting XML");
            pDialog.setMessage("Loading...");
            pDialog.show();
        }

        @Override
        protected InputStream doInBackground(String... params) {
            try {
                URL url = new URL(this.url);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setReadTimeout(10000 /* milliseconds */);
                connection.setConnectTimeout(15000 /* milliseconds */);
                connection.setRequestMethod("GET");
                connection.setDoInput(true);
                connection.connect();
                InputStream stream = connection.getInputStream();

                stream.close();
                return stream;

            } catch (Exception e) {
                e.printStackTrace();
                Log.e("AsyncTask", "exception");
                return null;
            }
        }

        @Override
        protected void onPostExecute(InputStream result) {
            pDialog.dismiss();
        if (result != null) {
            try {
                parser.setInput(result, null);
            } catch (XmlPullParserException e) {
                e.printStackTrace();
            }
        }
        }
    }


}

What is wrong in my code?

Why I am getting NullPointer exception instead of loading xml and setting it like input data for XMLPullParser?

So according to: What is a NullPointerException, and how do I fix it?

I should use ... = null; where I have not initialize object? But after initializing InputStream parserInput = null; I am getting the same error.

UPD

Parser:

        try {
            parserInput = new GetXML(this).execute(url).get();

            while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {

                switch (parser.getEventType()) {

                    case XmlPullParser.START_DOCUMENT:
                        ...
                        break;

                    case XmlPullParser.START_TAG:
                        tagname = parser.getName();
                        if (parser.getName().equals(iconsrc)) {                
                            ...

                        }
                        break;

                    case XmlPullParser.TEXT:
                        tagtext = parser.getText();
                        break;

                    case XmlPullParser.END_TAG:
                        parser.getName();

                        break;
                    default:
                        break;
                }
                parser.next();
            }

        } catch (Throwable t) {
            Toast.makeText(this,
                    "Error: " + t.toString(), Toast.LENGTH_LONG)
                    .show();
        }

It works with local xml.

UPD 2:

According to information in answers I have done:

        factory = XmlPullParserFactory.newInstance();
        factory.setNamespaceAware(true);
        parser = factory.newPullParser();

        new GetXML(this).execute(url).get();

        while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
...

And now I am getting:

org.xmlpull.v1.XmlPullParserException: setInput() must be called first. (position START_DOCUMENT null@1:1)

Here:http://theopentutorials.com/tutorials/android/xml/android-simple-xmlpullparser-tutorial/

I see parser.setInput(is, null); after parser initializing, so this code like mine:

new GetXML(this).execute(url).get();

What Is wrong now? It looks like block try with parser.setInput(); in onPostExecute() is not executing.

2

There are 2 best solutions below

3
Dmytro Batyuk On

parser is not initialized and is NULL by default. It should be initialized before using its setInput(parserInput,null) method

5
p.mathew13 On

Try this:

public class Parsing extends AppCompatActivity {
private final static String url = "http://validURL";
InputStream parserInput;
XmlPullParser parser;

protected void onCreate(Bundle savedInstanceState) {

    try {
        parserInput = new GetXML(this).execute(url).get();

    } catch (ExecutionException e) {
        e.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (XmlPullParserException e) {
        e.printStackTrace();
    }
}
class GetXML extends AsyncTask<String, Void, InputStream> {
    private Parsing activity;
    private String url;
    private ProgressDialog pDialog;

    public GetXML(Parsing activity/*, String url*/) {
        this.activity = activity;
        this.url = url;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(activity);
        pDialog.setTitle("Getting XML");
        pDialog.setMessage("Loading...");
        pDialog.show();
    }

    @Override
    protected InputStream doInBackground(String... params) {
        try {
            URL url = new URL(this.url);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setReadTimeout(10000 /* milliseconds */);
            connection.setConnectTimeout(15000 /* milliseconds */);
            connection.setRequestMethod("GET");
            connection.setDoInput(true);
            connection.connect();
            InputStream stream = connection.getInputStream();

            stream.close();
            return stream;

        } catch (Exception e) {
            e.printStackTrace();
            Log.e("AsyncTask", "exception");
            return null;
        }
    }

    @Override
    protected void onPostExecute(InputStream result) {
        pDialog.dismiss();
        if(result!=null){
        parser.setInput(result,null);
    }
    }
 }
}