DOM解析器无法在Android Ice Cream Sandwich上运行

时间:2012-11-23 11:39:46

标签: android xmldom

我正在尝试从URL解析xml数据,它正在使用android 2.3,但它在ICE-cream三明治及其上面崩溃了。谁可以帮我这个事?提前谢谢。

XMLFunctions.class中的

代码

import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URLDecoder;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import android.util.Log;


public class XMLFunctions {

    public final static Document XMLfromString(String xml){

        Document doc = null;

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        try {

            DocumentBuilder db = dbf.newDocumentBuilder();

            InputSource is = new InputSource();
            is.setCharacterStream(new StringReader(xml));
            is.setEncoding("UTF-8");
            doc = db.parse(is); 

        } catch (ParserConfigurationException e) {
            Log.e("XMLFunctions", "XML parse error: " + e.getMessage());
            return null;
        } catch (SAXException e) {
            Log.e("XMLFunctions", "Wrong XML file structure: " + e.getMessage());
            return null;
        } catch (IOException e) {
            Log.e("XMLFunctions", "I/O exeption: " + e.getMessage());
            return null;
        }

        return doc;

    }

    /** Returns element value
      * @param elem element (it is XML tag)
      * @return Element value otherwise empty String
      */
     public final static String getElementValue( Node elem ) {
         Node kid;
         if( elem != null){
             if (elem.hasChildNodes()){
                 for( kid = elem.getFirstChild(); kid != null; kid = kid.getNextSibling() ){
                     if( kid.getNodeType() == Node.TEXT_NODE  ){
                         return kid.getNodeValue();
                     }
                 }
             }
         }
         return "";
     }


     public static String getXML(String xmlURL){     
            String line = null;

            try {

                DefaultHttpClient httpClient = new DefaultHttpClient();

                HttpPost httpPost = new HttpPost(xmlURL);

                HttpResponse httpResponse = httpClient.execute(httpPost);
                HttpEntity httpEntity = httpResponse.getEntity();
                line = EntityUtils.toString(httpEntity);

            } catch (UnsupportedEncodingException e) {
                line = "<items count=\"0\" status=\"error\"></items>";
            } catch (MalformedURLException e) {
                line = "<items count=\"0\" status=\"error\"></items>";
            } catch (IOException e) {
                line = "<items count=\"0\" status=\"error\"></items>";
            }

            return line;

    }

    public static String numResults(Document doc){      
        Node items = doc.getDocumentElement();
        String res = "0";

        try{
            res = String.valueOf(items.getAttributes().getNamedItem("count").getNodeValue());
        }catch(Exception e ){
            res = "0";
        }

        return res;
    }

    public static String statusResult(Document doc){        
        Node items = doc.getDocumentElement();
        String res = "error";

        try{
            res = String.valueOf(items.getAttributes().getNamedItem("status").getNodeValue());
        }catch(Exception e ){
            res = "error";
        }

        return res;
    }

    public static String getValue(Element item, String str) {    

        NodeList n = item.getElementsByTagName(str);        
        return ParseXMLMethods.getElementValue(n.item(0));

      //  NodeList n = ((Document) e).getElementsByTagName(str);      
       // return XMLFunctions.getElementValue(n.item(0));
    }


    public static String urldecode(String stringToDecode){
        try {
            stringToDecode = URLDecoder.decode(stringToDecode, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return stringToDecode;
    }

}`

MainClass是XMLEntertainment.class

`

import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import android.app.ListActivity;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class XMLEntertainment extends ListActivity {
    static final String KEY_ID="ItemID";
    static final String KEY_Image = "ImageURL";
    static final String KEY_Video = "VideoURL";
    static final String KEY_Audio = "AudioURL";
    static final String KEY_StartDate = "StartDate";
    static final String KEY_EndDate = "EndDate";
    static final String KEY_ItemName = "ItemName";
    static final String KEY_Address = "Address";
    static final String KEY_Suburb = "Suburb";
    static final String KEY_PostCode= "Postcode";
    static final String KEY_Longitude = "Longitude";
    static final String KEY_Latitude = "Latitude";
    static final String KEY_SubtypeName = "SubtypeName";
    static final String KEY_Cost = "Cost";
    static final String KEY_Details = "Details";
    static final String KEY_Website = "Website";
    static final String KEY_MajorRegionName = "MajorRegionName";
    static final String KEY_Phone = "Phone";
    static final String KEY_Email = "Email";
    static final String KEY_OpeningHours = "OpeningHours";
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_entertainment);

        ArrayList<HashMap<String, String>> mylist = new ArrayList<HashMap<String, String>>();
        String xmlURL = "myURL Link";
        String xml = XMLFunctions.getXML(xmlURL);
       Document doc = XMLFunctions.XMLfromString(xml);

       // String xml = ParseXMLOutings.getXML();
       // Document doc = ParseXMLOutings.XMLfromString(xml);

        /*
        int numResults = XMLFunctions.numResults(doc);

        if((numResults <= 0)){
            Toast.makeText(ParseXMLDemo.this, "There is no data in the xml file", Toast.LENGTH_LONG).show();  
            finish();
        }
        */

        NodeList children = doc.getElementsByTagName("ListingElement");

        for (int i = 0; i < children.getLength(); i++) {                            
            HashMap<String, String> map = new HashMap<String, String>();    
            Element e = (Element)children.item(i);
            map.put(KEY_ID, XMLFunctions.getValue(e, KEY_ID));
            map.put(KEY_Image, XMLFunctions.getValue(e, KEY_Image));
            map.put(KEY_Video, XMLFunctions.getValue(e, KEY_Video));
            map.put(KEY_Audio, XMLFunctions.getValue(e, KEY_Audio));
            map.put(KEY_StartDate, XMLFunctions.getValue(e, KEY_StartDate));
            map.put(KEY_EndDate, XMLFunctions.getValue(e, KEY_EndDate));
            map.put(KEY_ItemName, XMLFunctions.getValue(e, KEY_ItemName));
            map.put(KEY_Address, XMLFunctions.getValue(e, KEY_Address));
            map.put(KEY_Suburb, XMLFunctions.getValue(e, KEY_Suburb));
            map.put(KEY_PostCode, XMLFunctions.getValue(e, KEY_PostCode));
            map.put(KEY_Longitude, XMLFunctions.getValue(e, KEY_Longitude));
            map.put(KEY_Latitude, XMLFunctions.getValue(e, KEY_Latitude));
            map.put(KEY_SubtypeName, XMLFunctions.getValue(e, KEY_SubtypeName));
            map.put(KEY_Cost, XMLFunctions.getValue(e, KEY_Cost));
            map.put(KEY_Details, XMLFunctions.getValue(e, KEY_Details));
            map.put(KEY_Website, XMLFunctions.getValue(e, KEY_Website));
            map.put(KEY_MajorRegionName, XMLFunctions.getValue(e, KEY_MajorRegionName));
            map.put(KEY_Phone, XMLFunctions.getValue(e,  KEY_Phone));
            map.put(KEY_Email, XMLFunctions.getValue(e, KEY_Email));
            map.put(KEY_OpeningHours, XMLFunctions.getValue(e, KEY_OpeningHours));



            mylist.add(map);            
        }       



         ListAdapter adapter = new SimpleAdapter(this, mylist , R.layout.list_items, 
                 new String[] { KEY_ItemName, KEY_SubtypeName, KEY_Suburb, KEY_PostCode, KEY_Cost,KEY_Details,KEY_Website,
        KEY_Phone,KEY_Email,KEY_MajorRegionName,KEY_OpeningHours}, 
            new int[] { R.id.title, R.id.type});

        setListAdapter(adapter);

        final ListView lv = getListView();
        lv.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {              
                @SuppressWarnings("unchecked")
                HashMap<String, String> o = (HashMap<String, String>) lv.getItemAtPosition(position);                   
            //Toast.makeText(xmlOutings.this,o.get("TourDetails"), Toast.LENGTH_LONG).show(); 


                 // getting values from selected ListItem
                String imageURL = o.get(KEY_Image);
                 String ItemName = o.get(KEY_ItemName);
                 String AudioURL=o.get(KEY_Audio);
                 String  VideoURL= o.get(KEY_Video);
                String Details =o.get(KEY_Details);
                String type = o.get(KEY_SubtypeName);
                String openingHours = o.get(KEY_OpeningHours);
                String cost = o.get(KEY_Cost);
              // String image1 = in.getStringExtra(KEY_Media_URL);
                String phone= o.get(KEY_Phone);
                String email =o.get(KEY_Email);
                String website = o.get(KEY_Website);
                String address =o.get(KEY_Address);
                String suburb = o.get(KEY_Suburb);
                String postcode = o.get(KEY_PostCode);
               String lat = o.get(KEY_Latitude);
              String lng = o.get(KEY_Longitude);



                    // Starting new intent
                   Intent in = new Intent(getApplicationContext(), ExplorerActivity.class);
                 //  in.putExtra(KEY_Image, imageURL );
                   in.putExtra(KEY_ItemName, ItemName );
                   in.putExtra(KEY_Audio, AudioURL );
                  in.putExtra(KEY_Video, VideoURL );
                  in.putExtra(KEY_Details, Details );
                  in.putExtra(KEY_SubtypeName, type );
                  in.putExtra(KEY_OpeningHours, openingHours );
                  in.putExtra(KEY_Cost, cost );
                  in.putExtra(KEY_Email, email);
                  in.putExtra(KEY_Phone, phone );
                  in.putExtra(KEY_Website, website);
                  in.putExtra(KEY_Address, address );
                  in.putExtra(KEY_Suburb, suburb);
                  in.putExtra(KEY_PostCode, postcode );
                  in.putExtra(KEY_Latitude, lat );
                  in.putExtra(KEY_Longitude, lng);

                      startActivity(in);
            }
            private Drawable LoadImageFromWebOperations(String url)
            {
                  try{
                InputStream is = (InputStream) new URL(url).getContent();
                Drawable d = Drawable.createFromStream(is, "KEY_Image");
                return d;
              }catch (Exception e) {
                System.out.println("Exc="+e);
                return null;
              }
            }

        });
    }
}

3 个答案:

答案 0 :(得分:1)

您应该在ICS版Android中使用AsyncTask进行网络操作。您无法在主线程或UI线程上执行网络操作。您应该在logcat上获得NetworkOnMainThread异常。

一个例子如下,

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
     protected String doInBackground(URL... urls) {
         String line = null;
         try {

            DefaultHttpClient httpClient = new DefaultHttpClient();

            HttpPost httpPost = new HttpPost(xmlURL);

            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            line = EntityUtils.toString(httpEntity);

        } catch (UnsupportedEncodingException e) {
            line = "<items count=\"0\" status=\"error\"></items>";
        } catch (MalformedURLException e) {
            line = "<items count=\"0\" status=\"error\"></items>";
        } catch (IOException e) {
            line = "<items count=\"0\" status=\"error\"></items>";
        }

        return line;
     }

     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }

     protected void onPostExecute(Long result) {
         // do further operations like start parsing from here
     }
 }

答案 1 :(得分:1)

如果没有看到您的错误堆栈跟踪,我们无法帮助您。

但根据你的陈述it is working on android 2.3 but it crashes on ICE-cream sandwich and above.

我建议您使用AsyncTask进行XML文件解析。这是因为您在应用程序的主UI线程中解析XML。

答案 2 :(得分:0)

这个问题有两个解决方案。

1)不要在Main UIThread,Use Async Task中编写网络调用。

2)在setContentView(R.layout.activity_main)之后将下面的代码写入MainActivity文件;

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

将import语句放到你的java文件中。

import android.os.StrictMode;