APP IDEA:我正在努力从Web获取XML文件并将其存储在内部存储上。当用户点击MainActivity
中的“搜索”按钮时,我的应用程序会检查是否存在Internet连接。
如果存在Internet连接,那么我应该从给定的URL获取XML并将其存储在Internal Storage上的文件中。
如果没有互联网连接,我应该使用存储的文件。
什么错误:出现的问题是,如果我启用了WiFi,它就不会通过网络解析InputStream - 因此没有输出(当用户点击搜索时它不会在XML中找到这个词,尽管它存在)。但是,如果WiFi为OFF,则它将在存储的文件中找到相同的单词。 (请查看下面的示例代码以获得更多说明)。
我的代码(这是在HandleXML.java中):
public void handlingOnlineXML(Context ctx) throws XmlPullParserException, IOException {
InputStream is;
/*
* Fetching the XML file from the Web
*/
URL url = new URL("http://meteo.arso.gov.si/uploads/probase/www/observ/surface/text/sl/observation_si_latest.xml");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Starts the query
conn.connect();
int response = conn.getResponseCode();
Log.d(TAG,"The response is: " + response);
is = conn.getInputStream();
/*
* Initiating XMLPullParser and sending the InputStream
* into parseXMLandStoreIt method
*/
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser xpp = factory.newPullParser();
/*
* Saving Input Stream to a Internal Storage file
*/
InputStream ins = is;
try {
final File file = new File(ctx.getFilesDir(), "data.xml");
final OutputStream output = new FileOutputStream(file);
try {
final byte[] buffer = new byte[1024];
int read;
while ((read = ins.read(buffer)) != -1)
output.write(buffer, 0, read);
output.flush();
} finally {
output.close();
}
} catch (Exception e) {
e.printStackTrace();
}
xpp.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES
, false);
xpp.setInput(is, null);
parseXMLAndStoreIt(xpp);
is.close();
ins.close();
}
/*******************************************************************
* Here I handle the XML data from a file stored on local storage
******************************************************************/
public void handlingStoredXML(Context ctx)throws XmlPullParserException, IOException{
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser xpp = factory.newPullParser();
xpp.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES
, false);
//File file = new File(ctx.getFilesDir(), "data.xml")
File file = new File(ctx.getFilesDir()+"/data.xml");
if(file.exists()) {
Log.d(TAG, "File Found!");
}
else{
Log.d(TAG, "There's no file!");
}
InputStream is = ctx.openFileInput("data.xml");
try {
xpp.setInput(is, null);
parseXMLAndStoreIt(xpp);
}finally {
is.close();
}
}
我的结论:通过观察logcat中的行为并进行一些行切换,我想我注意到代码的排列很重要。如果我把
xpp.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES
, false);
xpp.setInput(is, null);
在保存文件处理之前, WiFi ON选项将起作用,并且WiFi OFF选项将不起作用。但是,如果在保存文件过程之后输入上述内容(如此处的示例代码中所示),那么 WiFi ON选项将无法正常工作,并且WiFI OFF选项将起作用。
这真的很奇怪,我不知道造成这种情况的原因。我认为问题是,InputStream在首次使用后会被删除吗?
例如:
如果我使用InputStream
保存文件,它将被删除,因此无法放入xpp.setInput(is,null);
parseXMLAndStoreIt(xpp);
或者相反,如果我使用InputStream
解析在线,它将被清空并且不会保存任何内容?
LOGCAT(当WiFi关闭时,但不开启): RATECE是我点击搜索
时输入的字词11-26 10:25:10.791 29471-29471/com.example.myweatherapp.myweatherapp D/Input Location:﹕ RATECE
11-26 10:25:10.791 29471-29471/com.example.myweatherapp.myweatherapp D/Input Location:﹕ RATECE
11-26 10:25:10.821 29471-29487/com.example.myweatherapp.myweatherapp D/TAG﹕ The response is: 200
我还使用IF语句检查文件是否存在 - 我可以确认应用程序找到上述文件。
LOGCAT(当WiFi关闭不起作用且开启时):
11-26 10:43:44.021 30709-30709/com.example.myweatherapp.myweatherapp D/Input Location:﹕ RATECE
11-26 10:43:44.021 30709-30709/com.example.myweatherapp.myweatherapp D/TAG﹕ File Found!
11-26 10:43:44.021 30709-30709/com.example.myweatherapp.myweatherapp D/TAG﹕ File Found!
请帮帮我。
答案 0 :(得分:2)
您正在阅读两次InputStream is
。这是不可能的。在第一次阅读时,您已经“消耗”了它。如果解析器尝试第二次读取流,则会收到类似'stream already consume'的错误。你必须调整你的设计。例如,只需使用文件解析即可。或者使用StringBuider读取String中的响应,然后解析字符串。然后,您还可以保存字符串。