【问题标题】:Unable to start activity ComponentInfo{无法启动活动 ComponentInfo{
【发布时间】:2012-11-23 14:17:17
【问题描述】:

我有以下错误:

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

}

我在stackoverflow 上看到我需要使用new Thread(new Runnable() { 但我不明白如何重写我的应用程序运行良好的代码。 请帮我解决我的问题! 谢谢

【问题讨论】:

  • 不清楚,你在哪里得到异常?请添加相关信息。此外,从 Exception 我看不到对您发布的代码的任何引用。
  • 你在哪里调用 getXmlFromUrl 方法发布相关代码然后我们会尝试帮助你

标签: android android-activity xmlhttprequest nullpointerexception components


【解决方案1】:

来自安卓documentation

应用程序尝试执行 在其主线程上进行网络操作。

这仅针对以 Honeycomb SDK 为目标的应用程序或 更高。允许针对早期 SDK 版本的应用程序执行 在他们的主事件循环线程上联网,但它很重 灰心。请参阅文档设计响应性。

另见 StrictMode。

查看here 以获取在后台运行此操作的示例(查找“如何避免 ANR”)

【讨论】:

    【解决方案2】:

    您正在主 UI thread 上运行 Network Request

    Android &gt;=3.0 不允许在主 UI thread 上运行 Network Request。你需要使用

    AsyncTask做网络操作。

    【讨论】:

    • 我说得对吗,AsyncTask 需要,因为我的“解析器”适用于“漫长而繁重的任务”,这就是 Android 不启动我的应用程序的原因?
    • @user1873342 您正在主 ui 线程上执行网络操作,这是不可能的 android=>3.0
    【解决方案3】:

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

    注意AsyncTask&lt;String, Void, String&gt;,这里首先StringdoInBackground的参数,VoidonProgressUpdate()的参数,我们没有实现这个方法,第二个StringonPostExecute()的参数

    现在,从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
        }
    
    }
    
    }
    

    【讨论】:

    • 谢谢罗宾。我刚试过。我有一个问题:你能告诉我如何调用 new MyInnerClass().execute();从我的主要活动。 (示例代码)。
    • 感谢您的回答!我在上面更新了我的代码。我有一个解析器 xml,它由公共类 XMLParser 和公共类 AndroidXMLParsingActivity 组成据我所知,我需要将 XMLParser 类的公共 String getXmlFromUrl 的一部分插入受保护的 String doInBackground 中。但我不明白我的下一步是什么以及它如何与 AndroidXMLParsingActivity 类联系
    • 我在上面没有看到任何更新的代码。您在问题中复制了两次 XMLParser 类
    • 对不起。你说的对。我已经删除了代码副本。你能解释一下如何将我的代码从公共类 AndroidXMLParsingActivity 和公共类 XMLParser 插入到“doInBackground”和“onPostExecute”中,非常感谢!
    • 我使用了一个 ArrayList (menuItems),当我尝试插入“doInBackground”时它让我很困惑
    猜你喜欢
    • 1970-01-01
    • 2013-11-14
    • 2014-05-12
    • 2014-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多