如何从AsyncTask获取InputStream?

时间:2016-02-26 14:26:23

标签: android android-asynctask

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

3 个答案:

答案 0 :(得分:0)

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

  super.onProgressUpdate(inputStream);
...

    Document dom = documentBuilder.parse(inputStream);

答案 1 :(得分:0)

这是不可能的。您无法在主线程中使用任何网络InputStream(运行onProgressUpdate)。

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

答案 2 :(得分:0)

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

因此,您应该将其放在doInBackground中,一旦获得数据,将其传递给onProgressUpdateonPostExecute