如何从 AsyncTask 获取 InputStream



我正在做一个关于在专业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


更新 1

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 */>


更新 2

使用新的 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;

是不可能的。不能在主线程(运行onProgressUpdate的位置)中使用任何网络InputStream

在工作线程 ( doInBackground ) 中解析文档并仅传递结果。

我认为您没有正确使用inputStream,请尝试以下方式:

  super.onProgressUpdate(inputStream);
...
    Document dom = documentBuilder.parse(inputStream);

您错误,因为您documentBuilder.parse(inputStream);放置到主线程.输入流来自网络,因此这与您在主线程上从网络读取内容相同,因此存在此类错误。

所以你应该把它放在你的doInBackground,一旦你得到数据,把它传递给onProgressUpdateonPostExecute

最新更新