>

일부 URL에서 XML 파일을 다운로드하여 XMLPullParser의 입력처럼 사용하고 싶습니다

XML은 6-8Mb 정도입니다.

그래서 XML을 다운로드하기 위해 AsyncTask를 작성하고 코드에서 호출했지만 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();
            }
        }
        }
    }

}

코드에 어떤 문제가 있습니까?

XML을로드하고 XMLPullParser의 입력 데이터처럼 설정하는 대신 NullPointer 예외가 발생하는 이유는 무엇입니까?

따라서 NullPointerException은 무엇이며 어떻게 해결합니까?

... = 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()  실행 중이 아닙니다.

  • 답변 # 1

    파서는 초기화되지 않으며 기본적으로 NULL입니다. setInput (parserInput, null) 메소드를 사용하기 전에 초기화해야합니다.

  • 답변 # 2

    다음을 시도하십시오 :

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

관련 자료

  • 이전 c++ - C ++ 14에서 포트란 함수를 호출하기위한 일반 랩퍼를 작성하는 방법 (참조 별 호출-> 값별 호출)
  • 다음 JavaScript로 요소의 값이 두 번 변경되었습니다