Android &引用;NetworkOnMainThreadException“;,但在主线程上没有网络调用

Android &引用;NetworkOnMainThreadException“;,但在主线程上没有网络调用,android,multithreading,Android,Multithreading,在主线程上没有网络调用,但我仍然得到相同的错误:NetworkOnMainThreadException MainActivity.class: public class MainActivity extends Activity { private TextView tv1, tv2, tv3; @Override protected void onCreate(Bu

在主线程上没有网络调用,但我仍然得到相同的错误:NetworkOnMainThreadException

MainActivity.class:

public class MainActivity extends Activity
{
    private TextView    tv1,
                        tv2,
                        tv3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tv1 = (TextView) findViewById(R.id.tv1);
        tv2 = (TextView) findViewById(R.id.tv2);
        tv3 = (TextView) findViewById(R.id.tv3);

        String xmlUrl = "https://dl.dropboxusercontent.com/s/wbuxa7cutb6/update.xml";

        new DownloadData().execute(xmlUrl);
    }

    public class DownloadData extends AsyncTask<String, Void, InputStream>
    {
        @Override
        protected InputStream doInBackground(String... urls) {
            try {
                URL url = new URL(urls[0]);

                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setReadTimeout(10000);
                connection.setConnectTimeout(15000);
                connection.setRequestMethod("GET");
                connection.setDoInput(true);

                connection.connect();
                int response = connection.getResponseCode();
                Log.d("", "The response is: " + response);

                return connection.getInputStream();
                //return new Scanner(connection.getInputStream(),"UTF-8").useDelimiter("\\A").next();
            }
            catch (Exception e) {
                e.printStackTrace();
            }
            return null;    
        }

        @Override
        protected void onPostExecute(InputStream is)
        {
            List<List<String>> lists = new XmlParser().parse(is);

            tv1.setText(lists.get(0).get(0));
            tv2.setText(lists.get(0).get(1));
            tv3.setText(lists.get(0).get(2));
        }
    }
}
01-13 03:18:37.668: E/AndroidRuntime(5679): FATAL EXCEPTION: main
01-13 03:18:37.668: E/AndroidRuntime(5679): android.os.NetworkOnMainThreadException
01-13 03:18:37.668: E/AndroidRuntime(5679):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLInputStream.read(OpenSSLSocketImpl.java:657)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at libcore.net.http.FixedLengthInputStream.read(FixedLengthInputStream.java:45)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at libcore.io.Streams.readSingleByte(Streams.java:41)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at libcore.net.http.AbstractHttpInputStream.read(AbstractHttpInputStream.java:63)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at org.kxml2.io.KXmlParser.setInput(KXmlParser.java:1623)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at org.apache.harmony.xml.parsers.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:111)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:132)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at neviat.test.downloaddata.XmlParser.parse(XmlParser.java:39)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at neviat.test.downloaddata.MainActivity$DownloadData.onPostExecute(MainActivity.java:70)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at neviat.test.downloaddata.MainActivity$DownloadData.onPostExecute(MainActivity.java:1)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at android.os.AsyncTask.finish(AsyncTask.java:631)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at android.os.AsyncTask.access$600(AsyncTask.java:177)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at android.os.Handler.dispatchMessage(Handler.java:99)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at android.os.Looper.loop(Looper.java:137)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at android.app.ActivityThread.main(ActivityThread.java:5041)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at java.lang.reflect.Method.invokeNative(Native Method)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at java.lang.reflect.Method.invoke(Method.java:511)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at dalvik.system.NativeStart.main(Native Method)
public class XmlParser
{
    private DocumentBuilderFactory factory;
    private DocumentBuilder builder;

    private String getNodeValue(NamedNodeMap map, String key) {
        String nodeValue = null;
        Node node = map.getNamedItem(key);
        if (node != null)
            nodeValue = node.getNodeValue();
        return nodeValue;
    }

    public List<List<String>> parse(InputStream inStream)
    {
        List<List<String>> lists = new ArrayList<List<String>>();

        try {
            factory = DocumentBuilderFactory.newInstance();
            builder = factory.newDocumentBuilder();
            builder.isValidating();
            Document doc = builder.parse(inStream, null);

            doc.getDocumentElement().normalize();

            NodeList itemList = doc.getElementsByTagName("item");
            final int length = itemList.getLength();

            for (int i = 0; i < length; i++) {
                final NamedNodeMap attr = itemList.item(i).getAttributes();
                final String dataId         = getNodeValue(attr, "id");
                final String dataName       = getNodeValue(attr, "name");
                final String dataUrl        = getNodeValue(attr, "url");

                List<String> list = new ArrayList<String>();

                list.add(dataId);
                list.add(dataName);
                list.add(dataUrl);

                lists.add(list);
            }
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        }

        return lists;
    }
}
XmlParser:

public class MainActivity extends Activity
{
    private TextView    tv1,
                        tv2,
                        tv3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tv1 = (TextView) findViewById(R.id.tv1);
        tv2 = (TextView) findViewById(R.id.tv2);
        tv3 = (TextView) findViewById(R.id.tv3);

        String xmlUrl = "https://dl.dropboxusercontent.com/s/wbuxa7cutb6/update.xml";

        new DownloadData().execute(xmlUrl);
    }

    public class DownloadData extends AsyncTask<String, Void, InputStream>
    {
        @Override
        protected InputStream doInBackground(String... urls) {
            try {
                URL url = new URL(urls[0]);

                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setReadTimeout(10000);
                connection.setConnectTimeout(15000);
                connection.setRequestMethod("GET");
                connection.setDoInput(true);

                connection.connect();
                int response = connection.getResponseCode();
                Log.d("", "The response is: " + response);

                return connection.getInputStream();
                //return new Scanner(connection.getInputStream(),"UTF-8").useDelimiter("\\A").next();
            }
            catch (Exception e) {
                e.printStackTrace();
            }
            return null;    
        }

        @Override
        protected void onPostExecute(InputStream is)
        {
            List<List<String>> lists = new XmlParser().parse(is);

            tv1.setText(lists.get(0).get(0));
            tv2.setText(lists.get(0).get(1));
            tv3.setText(lists.get(0).get(2));
        }
    }
}
01-13 03:18:37.668: E/AndroidRuntime(5679): FATAL EXCEPTION: main
01-13 03:18:37.668: E/AndroidRuntime(5679): android.os.NetworkOnMainThreadException
01-13 03:18:37.668: E/AndroidRuntime(5679):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLInputStream.read(OpenSSLSocketImpl.java:657)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at libcore.net.http.FixedLengthInputStream.read(FixedLengthInputStream.java:45)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at libcore.io.Streams.readSingleByte(Streams.java:41)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at libcore.net.http.AbstractHttpInputStream.read(AbstractHttpInputStream.java:63)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at org.kxml2.io.KXmlParser.setInput(KXmlParser.java:1623)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at org.apache.harmony.xml.parsers.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:111)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:132)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at neviat.test.downloaddata.XmlParser.parse(XmlParser.java:39)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at neviat.test.downloaddata.MainActivity$DownloadData.onPostExecute(MainActivity.java:70)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at neviat.test.downloaddata.MainActivity$DownloadData.onPostExecute(MainActivity.java:1)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at android.os.AsyncTask.finish(AsyncTask.java:631)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at android.os.AsyncTask.access$600(AsyncTask.java:177)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at android.os.Handler.dispatchMessage(Handler.java:99)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at android.os.Looper.loop(Looper.java:137)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at android.app.ActivityThread.main(ActivityThread.java:5041)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at java.lang.reflect.Method.invokeNative(Native Method)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at java.lang.reflect.Method.invoke(Method.java:511)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
01-13 03:18:37.668: E/AndroidRuntime(5679):     at dalvik.system.NativeStart.main(Native Method)
public class XmlParser
{
    private DocumentBuilderFactory factory;
    private DocumentBuilder builder;

    private String getNodeValue(NamedNodeMap map, String key) {
        String nodeValue = null;
        Node node = map.getNamedItem(key);
        if (node != null)
            nodeValue = node.getNodeValue();
        return nodeValue;
    }

    public List<List<String>> parse(InputStream inStream)
    {
        List<List<String>> lists = new ArrayList<List<String>>();

        try {
            factory = DocumentBuilderFactory.newInstance();
            builder = factory.newDocumentBuilder();
            builder.isValidating();
            Document doc = builder.parse(inStream, null);

            doc.getDocumentElement().normalize();

            NodeList itemList = doc.getElementsByTagName("item");
            final int length = itemList.getLength();

            for (int i = 0; i < length; i++) {
                final NamedNodeMap attr = itemList.item(i).getAttributes();
                final String dataId         = getNodeValue(attr, "id");
                final String dataName       = getNodeValue(attr, "name");
                final String dataUrl        = getNodeValue(attr, "url");

                List<String> list = new ArrayList<String>();

                list.add(dataId);
                list.add(dataName);
                list.add(dataUrl);

                lists.add(list);
            }
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        }

        return lists;
    }
}
公共类XmlParser
{
私人文件建设者工厂;
私人文档生成器;
私有字符串getNodeValue(NamedNodeMap映射,字符串键){
字符串nodeValue=null;
Node=map.getNamedItem(键);
如果(节点!=null)
nodeValue=node.getNodeValue();
返回nodeValue;
}
公共列表解析(InputStream-inStream)
{
List lists=新建ArrayList();
试一试{
factory=DocumentBuilderFactory.newInstance();
builder=factory.newDocumentBuilder();
isValidating();
Document doc=builder.parse(流内,空);
doc.getDocumentElement().normalize();
nodelistitemlist=doc.getElementsByTagName(“项”);
final int length=itemList.getLength();
for(int i=0;i
您正在将InputStream返回到主线程,这意味着您将在onPostExecute方法(在主线程上运行)中执行网络操作。您必须获取后台线程中的所有数据。只有当数据不是来自网络时,才可以从InputStream解析UI线程上的数据,这不是您的情况

简而言之,将您的
List List=newxmlparser().parse(is)
doInBackground方法中的代码,并返回您的列表


澄清:您缺少的是流线型的用途。它们是用来使用的,因此您不需要一次加载所有数据(使资源使用率,特别是内存消耗,较低)。当您将InputStream传递给UI线程时,您不知道已经下载了多少数据(如果有的话)。假设您正在下载一个巨大的XML文件(例如30MB),并且需要对其进行解析。使用InputStream可以避免下载整个内容,将其放入内存(这会使应用程序崩溃),然后对其进行解析。使用Streams,该方法将下载少量数据,对其进行解析并释放使用的内存,因此内存消耗始终保持较低。

引用项目的第一行会告诉您错误所在

at neviat.test.downloaddata.XmlParser.parse(XmlParser.java:39)
因此,错误实际上出现在第39行的
XmlParser.java
中,而不是
MainActivity
中。但是,stacktrace通过查看引用您的项目的下一行,向我们显示了从何处调用它

at neviat.test.downloaddata.MainActivity$DownloadData.onPostExecute(MainActivity.java:70)
因此,我们可以在
UI线程上运行的
MainActivity
中的
onPostExecute()
中看到这一点。因此,解决方案是在
doInBackground()
中运行该行

List List=new XmlParser().parse(is);

但是,根据您将使用
列表的其他位置,您需要将其声明为
异步任务
活动
的成员变量(无论您需要的范围如何)。然后您可以在
doInBackground()

中初始化它,这是否显示在您的日志中
Log.d(“,”响应为:“+response”)
XmlParser
的第39行是什么?从
InputStream
解析XML是一种网络操作。这应该移动到
doInBackground()
方法。谢谢!但为什么解析输入流(从互联网上获得)可以在互联网上工作呢?我曾经在另一个项目中使用过parse,我不需要在后台使用它=/@Neviat向我们展示您的解析代码。可疑网络操作there@Neviat如果你检查这个链接。向下滚动,您将知道您不是在解析本地xml文件中的xml。从inputstream解析xml应该在doInbackground@Neviat,请参阅我的回答中的澄清部分。希望这能为您澄清一些事情。:)伟大的非常感谢你!