使用AsyncTask加载XML时出错

时间:2019-04-25 10:59:26

标签: android android-asynctask xmlpullparser

我想从某个URL下载XML文件,并将其用作XMLPullParser的输入。

XML很大-大约6-8Mb。

所以我写了AsyncTask来下载XML并在我的代码中调用它,但是我遇到了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

在这里开始我的活动和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();
            }
        }
        }
    }


}

我的代码有什么问题?

为什么我得到NullPointer异常而不是加载xml并将其设置为XMLPullParser的输入数据?

所以根据: What is a NullPointerException, and how do I fix it?

我应该在尚未初始化对象的地方使用... = null;吗?但是初始化InputStream parserInput = null;后,我得到了同样的错误。

UPD

解析器:

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

它与本地xml一起使用。

UPD 2:

根据我完成的答案中的信息:

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

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

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

现在我得到了:

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

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

parser.setInput(is, null);初始化后,我看到parser,所以这段代码像我的:

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

现在怎么了? 似乎parser.setInput();中的onPostExecute()的块尝试未执行。

2 个答案:

答案 0 :(得分:0)

解析器未初始化,默认为NULL。 应该在使用其setInput(parserInput,null)方法之前对其进行初始化

答案 1 :(得分:0)

尝试一下:

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