我正在做一个关于在专业Android 2应用程序开发中创建 EarthQuake Viewer 的功课。我收到了错误Networkonmainthreadexception
。我用AsyncTask
更改了代码,但仍然出现了错误。 [第{148}页http://docdro.id/1GgD2Pc]
public class refreshQuake extends AsyncTask<String/* Param */, InputStream /* Progress */, Boolean /* Result */> {
Activity ctx;
ListView earthquakeListView;
ArrayAdapter<Quake> arrayAdapter;
ArrayList<Quake> earthquakes = new ArrayList<Quake>();
public refreshQuake(Activity ctx){
this.ctx = ctx;
}
@Override
protected Boolean doInBackground(String... params) {
try {
URL url = new URL(params[0]);
URLConnection connection;
connection = url.openConnection();
HttpURLConnection httpURLConnection = (HttpURLConnection) connection;
connection.setConnectTimeout(2000);
int responseCode = httpURLConnection.getResponseCode();
if(responseCode == HttpURLConnection.HTTP_OK){
int layoutID = android.R.layout.simple_list_item_1;
earthquakes.clear();
arrayAdapter = new ArrayAdapter<Quake>(ctx, layoutID, earthquakes);
publishProgress(httpURLConnection.getInputStream());
return true;
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onProgressUpdate(InputStream... inputStream){
super.onProgressUpdate(inputStream[0]);
try {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document dom = documentBuilder.parse(inputStream[0]);
Element docEle = dom.getDocumentElement();
NodeList nodeList = docEle.getElementsByTagName("entry");
if(nodeList != null && nodeList.getLength() > 0){
for(int i = 0; i < nodeList.getLength(); i++){
Element entry = (Element) nodeList.item(i);
Element title = (Element) entry.getElementsByTagName("title").item(0);
Element g = (Element) entry.getElementsByTagName("georss:point").item(0);
Element when = (Element) entry.getElementsByTagName("updated").item(0);
Element link = (Element) entry.getElementsByTagName("link").item(0);
String details = title.getFirstChild().getNodeValue();
String hostname = "http://earthquake.usgs.gov";
String linkString = hostname + link.getAttribute("href");
String point = g.getFirstChild().getNodeValue();
String dt = when.getFirstChild().getNodeName();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss'Z'");
Date qdate = new GregorianCalendar(0,0,0).getTime();
try{
qdate = simpleDateFormat.parse(dt);
} catch (ParseException e) {
e.printStackTrace();
}
String[] location = point.split(" ");
Location l = new Location("dummyGPS");
l.setLatitude(Double.parseDouble(location[0]));
l.setLongitude(Double.parseDouble(location[1]));
String magnitudeString = details.split(" ")[1];
int end = magnitudeString.length()-1;
double magnitude = Double.parseDouble(magnitudeString.substring(0, end));
details = details.split(",")[1].trim();
Quake quake = new Quake(qdate, details, l, magnitude, linkString);
earthquakeListView.setAdapter(arrayAdapter);
addNewQuake(quake);
}
}
} catch (SAXException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
protected void onPostExecute(Boolean inputStream) {
super.onPostExecute(inputStream);
}
private void addNewQuake(Quake _quake){
earthquakes.add(_quake);
arrayAdapter.notifyDataSetChanged();
}
}
我的输入是rQuake.execute(getString(http://earthquake.usgs.gov/earthquakes/map/));
第
行的错误Networkonmainthreadexception
Document dom = documentBuilder.parse(inputStream[0]);
我如何获得InputStream
?
public class refreshQuake extends AsyncTask<String/* Param */, Quake /* Progress */, Boolean /* Result */> {
Activity ctx;
ListView earthquakeListView;
ArrayAdapter<Quake> arrayAdapter;
ArrayList<Quake> earthquakes = new ArrayList<Quake>();
public refreshQuake(Activity ctx){
this.ctx = ctx;
}
@Override
protected Boolean doInBackground(String... params) {
try {
URL url = new URL(params[0]);
URLConnection connection;
connection = url.openConnection();
HttpURLConnection httpURLConnection = (HttpURLConnection) connection;
int responseCode = httpURLConnection.getResponseCode();
if(responseCode == HttpURLConnection.HTTP_OK){
int layoutID = android.R.layout.simple_list_item_1;
earthquakes.clear();
arrayAdapter = new ArrayAdapter<Quake>(ctx, layoutID, earthquakes);
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document dom = documentBuilder.parse(httpURLConnection.getInputStream());
Element docEle = dom.getDocumentElement();
NodeList nodeList = docEle.getElementsByTagName("entry");
if(nodeList != null && nodeList.getLength() > 0){
for(int i = 0; i < nodeList.getLength(); i++){
Element entry = (Element) nodeList.item(i);
Element title = (Element) entry.getElementsByTagName("title").item(0);
Element g = (Element) entry.getElementsByTagName("georss:point").item(0);
Element when = (Element) entry.getElementsByTagName("updated").item(0);
Element link = (Element) entry.getElementsByTagName("link").item(0);
String details = title.getFirstChild().getNodeValue();
String hostname = "http://earthquake.usgs.gov";
String linkString = hostname + link.getAttribute("href");
String point = g.getFirstChild().getNodeValue();
String dt = when.getFirstChild().getNodeName();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss'Z'");
Date qdate = new GregorianCalendar(0,0,0).getTime();
try{
qdate = simpleDateFormat.parse(dt);
} catch (ParseException e) {
e.printStackTrace();
}
String[] location = point.split(" ");
Location l = new Location("dummyGPS");
l.setLatitude(Double.parseDouble(location[0]));
l.setLongitude(Double.parseDouble(location[1]));
String magnitudeString = details.split(" ")[1];
int end = magnitudeString.length()-1;
double magnitude = Double.parseDouble(magnitudeString.substring(0, end));
details = details.split(",")[1].trim();
Quake quake = new Quake(qdate, details, l, magnitude, linkString);
publishProgress(quake);
return true;
}}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParserConfigurationException e1) {
e1.printStackTrace();
} catch (SAXException e1) {
e1.printStackTrace();
}
return null;
}
@Override
protected void onProgressUpdate(Quake... quake){
super.onProgressUpdate(quake);
System.out.println("test2");
earthquakeListView.setAdapter(arrayAdapter);
addNewQuake(quake[0]);
}
@Override
protected void onPostExecute(Boolean inputStream) {
super.onPostExecute(inputStream);
}
private void addNewQuake(Quake _quake){
earthquakes.add(_quake);
arrayAdapter.notifyDataSetChanged();
}
}
输出
02-26 22:07:01.997 20240-2079/com.begood.earthquake W/System.err: org.xml.sax.SAXParseException: expected: /link read: head (position:END_TAG </head>@6:176 in java.io.InputStreamReader@b41220f0)
02-26 22:07:01.997 20240-2079/com.begood.earthquake W/System.err: at org.apache.harmony.xml.parsers.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:146)
02-26 22:07:01.997 20240-2079/com.begood.earthquake W/System.err: at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:107)
02-26 22:07:01.997 20240-2079/com.begood.earthquake W/System.err: at com.begood.earthquake.refreshQuake$override.doInBackground(refreshQuake.java:56)
02-26 22:07:01.997 20240-2079/com.begood.earthquake W/System.err: at com.begood.earthquake.refreshQuake$override.access$dispatch(refreshQuake.java)
02-26 22:07:01.997 20240-2079/com.begood.earthquake W/System.err: at com.begood.earthquake.refreshQuake.doInBackground(refreshQuake.java:0)
02-26 22:07:01.997 20240-2079/com.begood.earthquake W/System.err: at com.begood.earthquake.refreshQuake.doInBackground(refreshQuake.java:32)
02-26 22:07:01.997 20240-2079/com.begood.earthquake W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:287)
02-26 22:07:01.997 20240-2079/com.begood.earthquake W/System.err: at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
02-26 22:07:01.997 20240-2079/com.begood.earthquake W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:137)
02-26 22:07:01.997 20240-2079/com.begood.earthquake W/System.err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
02-26 22:07:01.997 20240-2079/com.begood.earthquake W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
02-26 22:07:01.997 20240-2079/com.begood.earthquake W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
02-26 22:07:01.997 20240-2079/com.begood.earthquake W/System.err: at java.lang.Thread.run(Thread.java:856)
第56行是Document dom = documentBuilder.parse(httpURLConnection.getInputStream());
第32行是public class refreshQuake extends AsyncTask<String/* Param */, Quake /* Progress */, Boolean /* Result */>
使用新的XML
<string name="quake_feed">
http://earthquake.usgs.gov/realtime/product/origin/pr16057008/pr/1456491131155/product.xml
</string>
02-26 22:36:05.964 20240-20258/com.begood.earthquake I/System.out: 200 200
02-26 22:36:21.715 5892-5892/com.begood.earthquake I/System.out: Sending WAIT chunk
02-26 22:36:22.554 5892-5892/com.begood.earthquake I/System.out: Debugger has connected
02-26 22:36:22.554 5892-5892/com.begood.earthquake I/System.out: waiting for debugger to settle...
02-26 22:36:22.754 5892-5892/com.begood.earthquake I/System.out: waiting for debugger to settle...
02-26 22:36:22.964 5892-5892/com.begood.earthquake I/System.out: waiting for debugger to settle...
02-26 22:36:23.174 5892-5892/com.begood.earthquake I/System.out: waiting for debugger to settle...
02-26 22:36:23.384 5892-5892/com.begood.earthquake I/System.out: waiting for debugger to settle...
02-26 22:36:23.594 5892-5892/com.begood.earthquake I/System.out: waiting for debugger to settle...
02-26 22:36:23.794 5892-5892/com.begood.earthquake I/System.out: waiting for debugger to settle...
02-26 22:36:24.004 5892-5892/com.begood.earthquake I/System.out: waiting for debugger to settle...
02-26 22:36:24.214 5892-5892/com.begood.earthquake I/System.out: waiting for debugger to settle...
02-26 22:36:24.424 5892-5892/com.begood.earthquake I/System.out: waiting for debugger to settle...
02-26 22:36:24.625 5892-5892/com.begood.earthquake I/System.out: debugger has settled (1325)
02-26 22:36:24.685 5892-5892/com.begood.earthquake I/dalvikvm: Could not find method android.content.Context.getSystemService, referenced from method com.begood.earthquake.MainActivity.access$super
02-26 22:36:24.685 5892-5892/com.begood.earthquake W/dalvikvm: VFY: unable to resolve virtual method 424: Landroid/content/Context;.getSystemService (Ljava/lang/Class;)Ljava/lang/Object;
02-26 22:36:24.694 5892-5892/com.begood.earthquake I/dalvikvm: Could not find method android.content.ContextWrapper.getSystemServiceName, referenced from method com.begood.earthquake.MainActivity.access$super
02-26 22:36:24.694 5892-5892/com.begood.earthquake W/dalvikvm: VFY: unable to resolve virtual method 497: Landroid/content/ContextWrapper;.getSystemServiceName (Ljava/lang/Class;)Ljava/lang/String;
答案 0 :(得分:0)
我认为您没有正确使用inputStream,请尝试这种方式:
super.onProgressUpdate(inputStream);
...
Document dom = documentBuilder.parse(inputStream);
答案 1 :(得分:0)
这是不可能的。您无法在主线程中使用任何网络InputStream
(运行onProgressUpdate
)。
在工作线程(doInBackground
)中解析文档并仅传递结果。
答案 2 :(得分:0)
您错误,因为您将documentBuilder.parse(inputStream);
放置到MainThread。输入流来自网络,因此这与您在MainThread上从网络读取内容相同,因此存在此类错误。
因此,您应该将其放在doInBackground
中,一旦获得数据,将其传递给onProgressUpdate
或onPostExecute
。