4

我正在做一個應用程序,必須從一個URL獲取XML文件並解析它。我一直覺得這個日誌貓(PS:我無法找到正確的谷歌美化sintax代碼高亮):http://www.lookedpath.tk/apps/firstapp/version.xmlAndroid的asynctask例外

的update.java代碼:

11-06 23:12:44.940: E/Trace(8751): error opening trace file: No such file or directory(2) 
11-06 23:12:51.345: E/Error:(8751): expected: /hr read: body (position:END_TAG </body>@6:8 in [email protected]) 
11-06 23:12:51.360: E/AndroidRuntime(8751): FATAL EXCEPTION: AsyncTask #1 
11-06 23:12:51.360: E/AndroidRuntime(8751): java.lang.RuntimeException: An error occured while executing doInBackground() 
11-06 23:12:51.360: E/AndroidRuntime(8751):  at android.os.AsyncTask$3.done(AsyncTask.java:299) 
11-06 23:12:51.360: E/AndroidRuntime(8751):  at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) 
11-06 23:12:51.360: E/AndroidRuntime(8751):  at java.util.concurrent.FutureTask.setException(FutureTask.java:124) 
11-06 23:12:51.360: E/AndroidRuntime(8751):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) 
11-06 23:12:51.360: E/AndroidRuntime(8751):  at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
11-06 23:12:51.360: E/AndroidRuntime(8751):  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230) 
11-06 23:12:51.360: E/AndroidRuntime(8751):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 
11-06 23:12:51.360: E/AndroidRuntime(8751):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 
11-06 23:12:51.360: E/AndroidRuntime(8751):  at java.lang.Thread.run(Thread.java:856) 
11-06 23:12:51.360: E/AndroidRuntime(8751): Caused by: java.lang.NullPointerException 
11-06 23:12:51.360: E/AndroidRuntime(8751):  at com.ambro.app.Update$connection.doInBackground(Update.java:39) 
11-06 23:12:51.360: E/AndroidRuntime(8751):  at com.ambro.app.Update$connection.doInBackground(Update.java:1) 
11-06 23:12:51.360: E/AndroidRuntime(8751):  at android.os.AsyncTask$2.call(AsyncTask.java:287) 
11-06 23:12:51.360: E/AndroidRuntime(8751):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 
11-06 23:12:51.360: E/AndroidRuntime(8751):  ... 5 more 

的XML可以在這裏找到

public class Update extends Activity { 
    private TextView testo2; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     setContentView(R.layout.update); 
     super.onCreate(savedInstanceState); 
     testo2= (TextView) findViewById(R.id.textView2); 

    } 
    public void goToUpdate (View view) { 
     System.out.println("ciao"); 
     new connection().execute(); 
    } 
    public class connection extends AsyncTask<Void, Void, Boolean> { 
     protected Boolean doInBackground(Void... params) { 
      boolean updated=false; 
      String lastversion=null; 
      Element e=null; 
      final String URL = "http://www.lookedpath.tk/apps/firstapp/version.xml"; 
      final String VERSION = "version"; 
      final String APPLICATION = "application"; 
      XMLParser parser = new XMLParser(); 
      String xml = parser.getXmlFromUrl(URL); // getting XML 
      Document doc = parser.getDomElement(xml); // getting DOM element 

      NodeList nl = doc.getElementsByTagName(APPLICATION); 
      for (int i=0;i<nl.getLength();i++) { 
       e = (Element) nl.item(0); 
       lastversion = parser.getValue(e, VERSION); // name child value 
      } 

      String actver = getString(R.string.version); 
      if(actver==lastversion) updated=true; 

      return updated; 
     } 
     protected void onPostExecute(Boolean... result) { 
      if(result[0]==false){ 
       testo2.setText(R.string.newversion); 
      } else { 
       testo2.setText(R.string.nonewversion); 
      } 

     } 

    }; 

} 

所以這是xmlparser.java文件:

public class XMLParser { 
public String getXmlFromUrl(String url) { 
    String xml = null; 

    try { 
     // defaultHttpClient 
     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 
    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 DOM 
     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 ""; 
    } 
} 

logcat說錯誤在更新類的第39行:

NodeList nl = doc.getElementsByTagName(APPLICATION); 

但我無法設法解決問題。誰能幫我?

更新: 我已修復錯誤405,但我仍然有一個空指針異常。我發現程序運行正常,但從未輸入執行後執行方法,因爲這個例外。

回答

3

我曾嘗試你的代碼沒有任何問題,它是好的。問題在於鏈接。

在瀏覽器,它看起來像這樣

<?xml version="1.0" encoding="UTF-8"?> 
<menu> 
<application> 
<version>1.5</version> 
</application> 
</menu> 

但是當我打印XML變量它給我

<html> 
<head><title>405 Not Allowed</title></head> 
<body bgcolor="white"> 
<center><h1>405 Not Allowed</h1></center> 
<hr><center>nginx</center> 
</body> 
</html> 

,然後在DOM變數中你得到了空當你試圖找到在NL元素變量是null你得到錯誤..,。

我試着用一些其他的xml提要你的代碼它工作得很好..,。

+0

那麼你有什麼建議嗎?我該如何修復xml文件? –

+0

SORRY,我不知道。 「POST」方法常常會出現405錯誤,您可能會嘗試在網站上引入某種輸入表單,但並非所有ISP都允許使用POST方法來處理表單「」FROM http:// www.checkupdown.com/status/E405.html鏈接 – user1690588

+1

我已修復了錯誤405,但我仍然有一個空指針異常。我發現程序正常運行,但從未輸入post執行方法,因爲此例外.. –

0

嘿,看看我的Library

您可以輕鬆地操縱它XML)

+0

感謝您的答案,但我不明白如何使用您的代碼來解析我的XML :)我是新的關於Android開發和你的幫助是非常有用 –

+0

看看源代碼和示例.java – ChristopheCVB

+0

在你的鏈接中只有4行代碼..我在哪裏可以找到源代碼和example.java?在你的代碼中你已經有 String myXMLDocument =「」; 但我怎麼能從網址帶來的字符串?也許我有點困惑,希望你能耐心等待,謝謝:) –

0

您可以檢查此鏈接,XML從XML解析。 http://www.androidhive.info/2012/02/android-custom-listview-with-image-and-text/

在您的活動中,您正在開發AsyncTask,但您忘記了覆蓋onPreExecute方法。請參閱此示例以瞭解如何在您的活動中開發AsyncTask

package com.androidhive.jsonparsing; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.UnsupportedEncodingException; 
import java.util.ArrayList; 
import java.util.HashMap; 

import org.apache.http.HttpEntity; 
import org.apache.http.HttpResponse; 
import org.apache.http.client.ClientProtocolException; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.json.JSONArray; 
import org.json.JSONException; 
import org.json.JSONObject; 

import android.app.ListActivity; 
import android.app.ProgressDialog; 
import android.content.Intent; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.widget.AdapterView; 
import android.widget.AdapterView.OnItemClickListener; 
import android.widget.ListAdapter; 
import android.widget.ListView; 
import android.widget.SimpleAdapter; 
import android.widget.TextView; 

public class AndroidJSONParsingActivity extends ListActivity { 

    // url to make request 
    private static String url = "http://api.androidhive.info/contacts/"; 

    // JSON Node names 
    private static final String TAG_CONTACTS = "contacts"; 
    private static final String TAG_ID = "id"; 
    private static final String TAG_NAME = "name"; 
    private static final String TAG_EMAIL = "email"; 
    private static final String TAG_ADDRESS = "address"; 
    private static final String TAG_GENDER = "gender"; 
    private static final String TAG_PHONE = "phone"; 
    private static final String TAG_PHONE_MOBILE = "mobile"; 
    private static final String TAG_PHONE_HOME = "home"; 
    private static final String TAG_PHONE_OFFICE = "office"; 
    static InputStream is = null; 
    static JSONObject jObj = null; 
    static String json = ""; 

    // contacts JSONArray 
    JSONArray contacts = null; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     new GetEventsTask().execute(""); 
    } 

    protected class GetEventsTask extends 
      AsyncTask<String, Integer, ArrayList<HashMap<String, String>>> { 
     protected ArrayList<HashMap<String, String>> contactList; 

     private final ProgressDialog dialog = new ProgressDialog(
       AndroidJSONParsingActivity.this); 

     //PreExecute Method 

     protected void onPreExecute() { 
      this.dialog.setMessage("Loading, Please Wait.."); 
      this.dialog.setCancelable(false); 
      this.dialog.show(); 
     } 

     //doInBackground Method 

     @Override 
     protected ArrayList<HashMap<String, String>> doInBackground(
       String... params) { 
      contactList = new ArrayList<HashMap<String, String>>(); 
      // Making HTTP request 
      try { 
       // defaultHttpClient 
       DefaultHttpClient httpClient = new DefaultHttpClient(); 
       HttpPost httpPost = new HttpPost(url); 

       HttpResponse httpResponse = httpClient.execute(httpPost); 
       HttpEntity httpEntity = httpResponse.getEntity(); 
       is = httpEntity.getContent(); 
       BufferedReader reader = new BufferedReader(
         new InputStreamReader(is, "iso-8859-1"), 8); 
       StringBuilder sb = new StringBuilder(); 
       String line = null; 
       while ((line = reader.readLine()) != null) { 
        sb.append(line + "\n"); 
       } 
       is.close(); 
       json = sb.toString(); 

      } catch (UnsupportedEncodingException e) { 
       e.printStackTrace(); 
      } catch (ClientProtocolException e) { 
       e.printStackTrace(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 

      // try parse the string to a JSON object 
      try { 
       jObj = new JSONObject(json); 
       Log.i("json objects",""+json); 
      } catch (JSONException e) { 
       Log.e("JSON Parser", "Error parsing data " + e.toString()); 
      } 
      try { 
       // Getting Array of Contacts 
       contacts = jObj.getJSONArray(TAG_CONTACTS); 

       // looping through All Contacts 
       for (int i = 0; i < contacts.length(); i++) { 
        JSONObject c = contacts.getJSONObject(i); 

        // Storing each json item in variable 
        String id = c.getString(TAG_ID); 
        String name = c.getString(TAG_NAME); 
        String email = c.getString(TAG_EMAIL); 
        String address = c.getString(TAG_ADDRESS); 
        String gender = c.getString(TAG_GENDER); 

        // Phone number is agin JSON Object 
        JSONObject phone = c.getJSONObject(TAG_PHONE); 
        String mobile = phone.getString(TAG_PHONE_MOBILE); 
        String home = phone.getString(TAG_PHONE_HOME); 
        String office = phone.getString(TAG_PHONE_OFFICE); 

        // creating new HashMap 
        HashMap<String, String> map = new HashMap<String, String>(); 

        // adding each child node to HashMap key => value 
        map.put(TAG_ID, id); 
        map.put(TAG_NAME, name); 
        map.put(TAG_EMAIL, email); 
        map.put(TAG_PHONE_MOBILE, mobile); 

        // adding HashList to ArrayList 
        contactList.add(map); 
       } 
      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 

      return contactList; 
     } 

     //onPostExecute Method 


     protected void onPostExecute(ArrayList<HashMap<String, String>> result) { 

      ListAdapter adapter = new SimpleAdapter(getApplicationContext(), 
        contactList, R.layout.list_item, new String[] { TAG_NAME, 
          TAG_EMAIL, TAG_PHONE_MOBILE }, new int[] { 
          R.id.name, R.id.email, R.id.mobile }); 
      // selecting single ListView item 
      ListView lv = getListView(); 
      lv.setAdapter(adapter); 



      // Launching new screen on Selecting Single ListItem 
      lv.setOnItemClickListener(new OnItemClickListener() { 
       @Override 
       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.email)).getText().toString(); 
        String description = ((TextView) view.findViewById(R.id.mobile)).getText().toString(); 

        // Starting new intent 
        Intent in = new Intent(getApplicationContext(),SingleMenuItemActivity.class); 
        in.putExtra(TAG_NAME, name); 
        in.putExtra(TAG_EMAIL, cost); 
        in.putExtra(TAG_PHONE_MOBILE, description); 
        startActivity(in); 
       } 
      }); 
      if (this.dialog.isShowing()) { 
       this.dialog.dismiss(); 
      } 
     } 

    } 

} 
+0

現在我重寫onPreExecute方法,但錯誤仍然是相同的。我已經使用了你鏈接的XML解析器,它是顯示這個錯誤 –

+0

不,我沒有在這裏使用asny任務。首先做解析沒有異步任務,如果你從url獲得數據,那麼你想想asyntask。在真正的設備上運行這個或檢查你的AVD互聯網設置 –

0

從日誌中,我可以看到你在Update.java中有一個NullPointer,第39行。你可以從這裏開始。我相信它與AsyncTask無關。

+0

我看到錯誤是在第39行,但我不明白哪裏的錯誤。謝謝 –

+0

第39行是什麼? – josephus

+0

NodeList nl = doc.getElementsByTagName(APPLICATION); –

0

你得到空xml在那個位置,所以打亂你的應用程序首先檢查任何XML響應你得到或不?

如果u得到空XML,然後使用下面的代碼解析XML

import org.xml.sax.Attributes; 
import org.xml.sax.SAXException; 
import org.xml.sax.helpers.DefaultHandler; 
import android.util.Log; 
public class XMLHandler extends DefaultHandler { 

String elementValue = null; 
Boolean elementOn = false; 
userdata d = userdata.getInstance(); 
public static XMLGettersSetters data = null; 

public static XMLGettersSetters getXMLData() { 
    return data; 
} 

public static void setXMLData(XMLGettersSetters data) { 
    XMLHandler.data = data; 
} 

/** 

* This will be called when the tags of the XML starts. 

**/ 

@Override 

public void startElement(String uri, String localName, String qName, 

     Attributes attributes) throws SAXException { 

    elementOn = true; 

    if (localName.equals("application")) 

    { 
     data = new XMLGettersSetters(); 
    } 

} 

/** 

* This will be called when the tags of the XML end. 

**/ 

@Override 

public void endElement(String uri, String localName, String qName) 

     throws SAXException { 

    elementOn = false; 

    /** 

    * Sets the values after retrieving the values from the XML tags 

    * */ 

    if (localName.equalsIgnoreCase("version")){ 

     System.out.println("ststus" + elementValue); 

     d.setIsregi(elementValue); 


    } 

/** 

* This is called to get the tags value 

**/ 

@Override 

public void characters(char[] ch, int start, int length) 

     throws SAXException { 

    if (elementOn) { 

     elementValue = new String(ch, start, length); 

     elementOn = false; 

    } 
} 
} 
0

您必須將正確的DTD添加到您的xml(文檔類型定義)中,嘗試它,您將看到解析將順利進行。 步驟1:生成Correcte DTD 步驟2:將其添加到您的xml文件並保存 步驟3:上傳您的xml文件,解析並享受。