0

我有以下错误:

12-05 20:35:31.005: E/AndroidRuntime(1084): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.helplawyer/com.example.helplawyer.AndroidXMLParsingActivity}: android.os.NetworkOnMainThreadException

在我添加的 xml 清单中<uses-permission android:name="android.permission.INTERNET" />

这是我的主要课程

package com.example.helplawyer;


public class AndroidXMLParsingActivity extends ListActivity {

// All static variables
static final String URL = "http://www.consultant.ru/rss/hotdocs.xml";
// XML node keys
static final String KEY_ITEM = "item"; // parent node
static final String KEY_TITLE = "title";
static final String KEY_DATE = "pubDate";
static final String KEY_LINK = "link";
static final String KEY_DESC = "description";

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.mainxml);

    ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();

    XMLParser parser = new XMLParser();
    String xml = parser.getXmlFromUrl(URL); // getting XML
    Document doc = parser.getDomElement(xml); // getting DOM element

    NodeList nl = doc.getElementsByTagName(KEY_ITEM);
    // looping through all item nodes <item>
    for (int i = 0; i < nl.getLength(); i++) {
        // creating new HashMap
        HashMap<String, String> map = new HashMap<String, String>();
        Element e = (Element) nl.item(i);
        // adding each child node to HashMap key => value

        map.put(KEY_TITLE, parser.getValue(e, KEY_TITLE));
        map.put(KEY_LINK, parser.getValue(e, KEY_LINK));
        map.put(KEY_DATE, parser.getValue(e, KEY_DATE));
        map.put(KEY_DESC, parser.getValue(e, KEY_DESC));

        // adding HashList to ArrayList
        menuItems.add(map);
    }

    // Adding menuItems to ListView
    ListAdapter adapter = new SimpleAdapter(this, menuItems,
            R.layout.list_item,
            new String[] { KEY_TITLE, KEY_DESC, KEY_DATE, KEY_LINK }, new int[] {
                    R.id.name, R.id.description, R.id.cost, R.id.link });

    setListAdapter(adapter);

    // selecting single ListView item
    ListView lv = getListView();

    lv.setOnItemClickListener(new OnItemClickListener() {

        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {
            // getting values from selected ListItem
            String name = ((TextView) view.findViewById(R.id.name)).getText().toString();
            String cost = ((TextView) view.findViewById(R.id.cost)).getText().toString();
            String link = ((TextView) view.findViewById(R.id.link)).getText().toString();
            String description = ((TextView) view.findViewById(R.id.description)).getText().toString();

            // Starting new intent
            Intent in = new Intent(getApplicationContext(), SingleMenuItemActivity.class);
            in.putExtra(KEY_TITLE, name);
            in.putExtra(KEY_DATE, cost);
            in.putExtra(KEY_LINK, link);
            in.putExtra(KEY_DESC, description);
            startActivity(in);

        }
    });
}

}

XML解析器

package com.example.helplawyer;

public class XMLParser {

// constructor
public XMLParser() {

}

/**
 * Getting XML from URL making HTTP request
 * @param url string
 * */
public String getXmlFromUrl(String url) {
    String xml = null;

    try {
        // defaultHttpClient
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(url);

        HttpResponse httpResponse = httpClient.execute(httpGet);
        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
    return xml;
}

/**
 * Getting XML DOM element
 * @param XML string
 * */
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;
}

/** Getting node value
  * @param elem element
  */
 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 "";
 }

 /**
  * Getting node value
  * @param Element node
  * @param key string
  * */
 public String getValue(Element item, String str) {     
        NodeList n = item.getElementsByTagName(str);        
        return this.getElementValue(n.item(0));
    }

}

我阅读了我需要使用的stackoverflownew Thread(new Runnable() { , 但我不明白如何重写我的应用程序运行良好的代码。请帮我解决我的问题!谢谢

4

3 回答 3

1

来自 Android文档

当应用程序尝试在其主线程上执行网络操作时引发的异常。

这仅针对面向 Honeycomb SDK 或更高版本的应用程序抛出。允许以早期 SDK 版本为目标的应用程序在其主事件循环线程上进行网络连接,但非常不鼓励这样做。请参阅文档设计响应性。

另请参阅严格模式。

在这里查看在后台运行此操作的示例(查找“如何避免 ANR ”)

于 2012-12-05T17:11:33.767 回答
0

您无法从主线程访问网络。你需要使用 AsyncTask 。在Android Connecting with PHP and MySql Force Close检查我的答案

注意AsyncTask<String, Void, String>,这里第一个String是参数 to doInBackgroundVoid是参数 to onProgressUpdate(),我们没有实现这个方法,第二个String是参数 toonPostExecute()

现在,从MainActivity你调用new InnerClass().execute(urltoxml);Android 开始,它会自动调用doInBackground()urltoxml作为参数传递`

在里面做你所有的网络东西doInbackground,完成后,doInBackground 将返回一个结果string,android 会将它作为参数传递给onPostExecute(). 在 onPostExecute 中使用你想要的字符串

public class MainActivity extends Activity implements OnClickListener{ 

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

    Button button = (Button)findViewById(R.id.button1);
    button.setOnClickListener( new OnClickListener(){

    @Override
    public void onClick(View v){
        new InnerClass().execute(urltoxml);
    }

    });
}

public class InnerClass extends AsyncTask<String, Void, String>{


    @Override
    protected String doInBackground(String... arg0) {
        String returnVal;
        //process your xml here
        //store the result in returnVal;
        return returnVal;
    }

    @Override
    protected void onPostExecute(String result) {
        //do something with the data
    }

}

}
于 2012-12-05T17:42:19.353 回答
0

您正在Network Requestmain上运行UI thread

Android >=3.0不允许Network Request在 main上运行UI thread。你需要使用

AsyncTask做网络操作。

于 2012-12-05T17:15:22.427 回答