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的说明,你会解决你的错误。