2014-02-24 60 views
0

我遇到了很多困難,添加的AsyncTask我的應用程序的解析來的AsyncTask。我有一個文章列表活動,它從文本中提取xml然後填充ListView。該活動使用外部類,包括LazyAdapter.java,ImageLoader.java和XMLParser.java。我如何將它從Web獲取數據的部分放到AsyncTask類中。如何將XML從主要活動

這裏的主要活動:

package com.jamfactory.articles; 

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.ActionBar; 
import android.app.Activity; 
import android.content.Intent; 
import android.content.SharedPreferences; 
import android.content.SharedPreferences.Editor; 
import android.os.Bundle; 
import android.os.StrictMode; 
import android.util.Log; 
import android.view.Menu; 
import android.view.MenuInflater; 
import android.view.MenuItem; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.AdapterView; 
import android.widget.AdapterView.OnItemClickListener; 
import android.widget.ListView; 
import android.widget.TextView; 
import android.widget.Toast; 

import com.jamfactory.articles.utilities.XMLParser; 

public class ArticleList extends Activity { 
    // All static variables 
    static final String URL = "http://192.168.12.21/sebastian/broadcast/index.php/blog?format=stream"; 
    // XML node keys 
    static final String KEY_ARTICLE = "article"; // parent node 
    static final String KEY_ID = "id"; 
    static final String KEY_TITLE = "title"; 
    static final String KEY_CONTENT = "content"; 
    static final String KEY_THUMB_URL = "thumb_url"; 

    ListView list; 
    LazyAdapter adapter; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     if (android.os.Build.VERSION.SDK_INT > 9) { 
      StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder() 
        .permitAll().build(); 
      StrictMode.setThreadPolicy(policy); 
     } 
     setContentView(R.layout.list); 

     // Set the title 
     ActionBar ab = getActionBar(); 
     ab.setTitle("Latest Articles"); 


     // ArrayList for XML 
     ArrayList<HashMap<String, String>> articlesList = new ArrayList<HashMap<String, String>>(); 
     XMLParser parser = new XMLParser(); 
     String xml = parser.getXmlFromUrl(URL); // getting XML from URL 
     Document doc = parser.getDomElement(xml); // getting DOM element 

     NodeList nl = doc.getElementsByTagName(KEY_ARTICLE); 
     // looping through all song nodes <song> 
     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_ID, parser.getValue(e, KEY_ID)); 
      map.put(KEY_TITLE, parser.getValue(e, KEY_TITLE)); 
      map.put(KEY_CONTENT, parser.getValue(e, KEY_CONTENT)); 
      map.put(KEY_THUMB_URL, parser.getValue(e, KEY_THUMB_URL)); 

      // adding HashList to ArrayList 
      articlesList.add(map); 

     } 

     list = (ListView) findViewById(R.id.list); 

     // Getting adapter by passing xml data ArrayList 
     adapter = new LazyAdapter(this, articlesList); 
     list.setAdapter(adapter); 

     // Click event for single list row 
     list.setOnItemClickListener(new OnItemClickListener() { 

      @Override 
      public void onItemClick(AdapterView<?> parent, View v, int pos, 
        long id) { 

       // Set items to be sent 
       TextView title = (TextView) v.findViewById(R.id.title); 
       TextView content = (TextView) v.findViewById(R.id.content); 
       TextView thumb_url = (TextView) v.findViewById(R.id.thumb_url); 

       // Start the intent 
       Intent i = new Intent(ArticleList.this, Article.class); 

       // Send along intent 
       i.putExtra("title", title.getText().toString().trim()); 
       i.putExtra("content", content.getText().toString().trim()); 
       i.putExtra("thumb_url", thumb_url.getText().toString()); 
       startActivity(i); 

      } 
     }); 

    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     MenuInflater inflater = getMenuInflater(); 
     inflater.inflate(R.menu.article_list, menu); 

     return super.onCreateOptionsMenu(menu); 
    } 

    // Refresh Page 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 
     case R.id.action_refresh: 
      reList(); 
      return true; 
     default: 
      return super.onOptionsItemSelected(item); 
     } 

    } 

    public void reList() { 
     finish(); 
     overridePendingTransition(0, 0); 
     startActivity(getIntent()); 
     Toast.makeText(this, "Reload Complete", Toast.LENGTH_SHORT).show(); 

    } 

} 

這裏是XMLParser.java:

package com.jamfactory.articles.utilities; 

import java.io.IOException; 
import java.io.StringReader; 
import java.io.UnsupportedEncodingException; 

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.ClientProtocolException; 
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 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(); 
      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; 
    } 

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

你不應該這樣做'StrictMode.ThreadPolicy政策=新StrictMode 。.ThreadPolicy.Builder()permitAll()建立();'。有什麼理由呢? – nikis

+0

我用它由於Android不停地扔錯誤強迫我使用的AsyncTask。這條線的力量機器人忽略,繼續做在主線程 –

+0

再使用的AsyncTask聯網,這是很好的做法 – nikis

回答

0

您可以嘗試如下...

public class ArticleLoaderTask extends AsyncTask<Void, Void, Void> { 

    // ArrayList for XML 
    ArrayList<HashMap<String, String>> articlesList = new ArrayList<HashMap<String, String>>(); 
    LazyAdapter adapter; 
    Context mContext; 

    public ArticleLoaderTask(Context context) { 

     mContext.this = context; 

    } 

    @Override 
    protected Void doInBackground(Void... params) { 

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

     NodeList nl = doc.getElementsByTagName(KEY_ARTICLE); 
     // looping through all song nodes <song> 
     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_ID, parser.getValue(e, KEY_ID)); 
      map.put(KEY_TITLE, parser.getValue(e, KEY_TITLE)); 
      map.put(KEY_CONTENT, parser.getValue(e, KEY_CONTENT)); 
      map.put(KEY_THUMB_URL, parser.getValue(e, KEY_THUMB_URL)); 

      // adding HashList to ArrayList 
      articlesList.add(map); 

     } 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Void result) { 
     super.onPostExecute(result); 

     adapter = new LazyAdapter(mContext, articlesList); 
     list.setAdapter(adapter); 
    } 

} 

MainActivity.java ......

new ArticleLoaderTask(MainActivity.this).execute(); 
+0

感謝你好,在的getValue拋出**的方法GetValue(ORG .w3c.dom.Element,java.lang.String中)在類型XMLParser的不適用的參數(android.renderscript.Element,java.lang.String中)**和mContext不能被解析到一個變量 –

0

試試這個

在活動的OnCreate

new AppDownloader(this).execute(""); 

內部類

class AppDownloader extends AsyncTask<String, String, String> { 

    Context mContext; 
    ArrayList<HashMap<String, String>> articlesList= new ArrayList<HashMap<String, String>>(); 

public AppDownloader(Context context) { 

     mContext = context; 
    } 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 

      // show dialog here 

    } 

    @Override 
    protected String doInBackground(String... params) { 

    // ArrayList for XML 

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

    NodeList nl = doc.getElementsByTagName(KEY_ARTICLE); 
    // looping through all song nodes <song> 
    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_ID, parser.getValue(e, KEY_ID)); 
     map.put(KEY_TITLE, parser.getValue(e, KEY_TITLE)); 
     map.put(KEY_CONTENT, parser.getValue(e, KEY_CONTENT)); 
     map.put(KEY_THUMB_URL, parser.getValue(e, KEY_THUMB_URL)); 

     // adding HashList to ArrayList 
     articlesList.add(map); 

    } 
     return null; 
    } 

    @Override 
    protected void onPostExecute(String result) { 
     super.onPostExecute(result); 

    adapter = new LazyAdapter(mContext, articlesList); 
    list.setAdapter(adapter); 
    } 

} 
0

基本上,作爲例子表明,你把東西你想在doInBackground()方法中執行,那麼你可以調用你想在不同時間執行任何事情的生命週期方法(befor或者在doInBackground方法中的東西之後)。

所以一個一個簡單的模板,將使用此命令啓動:

new MyAsyncTask.execute(); 

和類會是什麼樣子:

class MyAsyncTask extends AsyncTask<String, String, String> { 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     // do stuff before 
    } 

    @Override 
    protected String doInBackground(String... params) { 
     // Do stuff here (off the UI thread) 
     // In your case, you can just cut and paste all your XML parsing logic here  
    } 

    @Override 
    protected void onPostExecute(String result) { 
     super.onPostExecute(result); 
     // Things you do after  
    } 

} 
+0

謝謝,但問題是我已排序的碼到不同的類別,一個用於XMLParser的,一個用於ImageLoader的,一個爲ListView適配器。當我將它粘貼到像你這樣的簡單模板中時,我最終會遇到一堆錯誤。此外,我不知道要粘貼在MainActivity什麼代碼以及如何填充從onPostexecute列表視圖,因爲XML是在一個複雜的ArrayList –

相關問題