2012-03-16 3 views
8

consigo un NetworkOnMainThreadException cuando trato de poner en práctica el siguiente código:NetworkOnMainThread

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); 
     } 
} 

y el manejador:

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 ""; 
    }  

}

Cualquier idea de por qué? Debería funcionar, todos los tutoriales que he leído tratan esto como código de trabajo pero no se ejecuta y solo arroja la excepción. He leído que podría necesitar implementar asynctask pero soy nuevo y no estoy seguro de qué partes necesitan su propio hilo. Gracias por cualquier ayuda, crítica (constructiva), sugerencias, etc.

+0

posible duplicado de [] (android.os.NetworkOnMainThreadException http://stackoverflow.com/questions/6343166/android-os-networkonmainthreadexception) –

Respuesta

10

¿Alguna idea de por qué?

Porque, si ese trozo de código se está ejecutando en el subproceso principal de la aplicación, está haciendo E/S de red en el subproceso principal de la aplicación.

He leído Necesito implementar asynctask pero soy nuevo y no estoy seguro de qué partes necesitan su propio hilo.

me gustaría poner la red de E/S y el análisis de doInBackground() y la setListAdapter() llamada en onPostExecute() de un AsyncTask.

+0

Gracias que ayudaron mucho, que está funcionando ahora :) – Bob

+0

Y para cualquier persona interesada aquí está el código de trabajo: – Bob

+1

¿dónde está el código? – auraham

1

Añadiendo a la respuesta de CommonsWare, la excepción NetworkOnMainThreadException se agregó en algún momento entre 2.3.3 (Gingerbread_MR1) y 3.0 (Honeycomb). Si nos fijamos en

android.app.ActivityThread 

se encuentra el siguiente fragmento de código:

/** 
    * 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(); 
    } 

creo que los tutoriales que le estaban siguiendo fueron escritos antes de que este se puso en marcha, por lo que no causó la NetworkOnMainThreadException. Sigue las instrucciones de CommonsWare con respecto a AsyncTask y corregirás tu error.

+0

Gracias que bueno saber :) – Bob

3

Si simplemente desea probar su código, y no quiero añadir más complicaciones, sin embargo, se puede añadir a su onCreate()

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

Usted no quiere que esto sea permanente, las operaciones de red en el hilo de la interfaz de usuario crean una mala experiencia cuando se usa la aplicación, pero pueden ser útiles cuando se prueban.