NetworkOnMainThread

当我尝试实现下面的代码时,我得到一个NetworkOnMainThreadException:

public class HandlingXMLStuff extends ListActivity{ static final String URL = "xml_file"; static final String ITEM = "item"; //parent static final String Id = "id"; static final String Name = "name"; static final String Desc = "desc"; static final String Link = "Link"; @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.xmllist); ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>(); xmlparser parser = new xmlparser(); String xml = parser.getXmlFromUrl(URL); Document doc = parser.getDomElement(xml); NodeList nl = doc.getElementsByTagName(ITEM); //START: loop through all item nodes <item> for (int i = 0;i<nl.getLength();i++){ //lets create our HASHMAP!! (feeds items into our ArrayList) HashMap<String, String> map = new HashMap<String, String>(); Element e = (Element) nl.item(i); //add each child node to the HashMap (key, value/<String, String>) map.put(Name, parser.getValue(e, Name)); map.put(Desc, parser.getValue(e, Desc)); map.put(Link, parser.getValue(e, Link)); menuItems.add(map); }//DONE ListAdapter adapter = new SimpleAdapter(this, menuItems, R.layout.list_item, new String[] {Name, Desc, Link}, new int []{R.id.name, R.id.description, R.id.link}); setListAdapter(adapter); } } 

和处理程序:

 public class xmlparser{ public String getXmlFromUrl(String url) { String xml = null; try { DefaultHttpClient httpClient = new DefaultHttpClient(); HttpPost httpPost = new HttpPost(url); HttpResponse httpResponse = httpClient.execute(httpPost); HttpEntity httpEntity = httpResponse.getEntity(); xml = EntityUtils.toString(httpEntity); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return xml; } public Document getDomElement(String xml){ Document doc = null; DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); try { DocumentBuilder db = dbf.newDocumentBuilder(); InputSource is = new InputSource(); is.setCharacterStream(new StringReader(xml)); doc = db.parse(is); } catch (ParserConfigurationException e) { Log.e("Error: ", e.getMessage()); return null; } catch (SAXException e) { Log.e("Error: ", e.getMessage()); return null; } catch (IOException e) { Log.e("Error: ", e.getMessage()); return null; } return doc; } public String getValue(Element item, String str) { NodeList n = item.getElementsByTagName(str); return this.getElementValue(n.item(0)); } public final String getElementValue( Node elem ) { Node child; if( elem != null){ if (elem.hasChildNodes()){ for( child = elem.getFirstChild(); child != null; child = child.getNextSibling() ){ if( child.getNodeType() == Node.TEXT_NODE ){ return child.getNodeValue(); } } } } return ""; } 

}

任何想法为什么? 它应该工作,所有我读过的教程把它当作工作代码,但是它不运行,只抛出exception。 我读过,我可能需要实施asynctask,但即时消息新,不知道哪些部分需要自己的线程。 感谢您的帮助,批评(build设性),build议等。

任何想法为什么?

因为,如果在主应用程序线程上正在执行大量代码,则您正在主应用程序线程上执行networkingI / O。

我读过,我可能需要实施asynctask,但即时消息新,不知道哪些部分需要自己的线程。

我会把networkingI / O和parsing放在doInBackground()setListAdapter()调用的AsyncTask onPostExecute()中。

如果你只是想testing你的代码,而不想再添加任何复杂的东西,你可以将它添加到你的onCreate()

 if (android.os.Build.VERSION.SDK_INT > 9) { StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); } 

你不希望这是永久性的,因为UI线程上的networking操作在使用应用程序时会造成不好的体验,但在testing时会很有用。

添加到CommonsWare的答案,NetworkOnMainThreadException添加了2.3.3(姜饼_MR1)和3.0(蜂窝)之间的某个时间。 如果你看

 android.app.ActivityThread 

你会发现下面这段代码:

  /** * For apps targetting SDK Honeycomb or later, we don't allow * network usage on the main event loop / UI thread. * * Note to those grepping: this is what ultimately throws * NetworkOnMainThreadException ... */ if (data.appInfo.targetSdkVersion > 9) { StrictMode.enableDeathOnNetwork(); } 

我认为你所遵循的教程是在写入之前编写的,所以不会导致NetworkOnMainThreadException。 按照CommonsWare有关AsyncTask的说明,你会解决你的错误。