如何将XML解析从Main Activity移动到AsyncTask

时间:2014-02-24 12:11:10

标签: android android-listview android-asynctask android-xml

在向我的应用添加Asynctask时遇到了很多困难。我有一个ArticleList Activity,它从文件中提取xml然后填充ListView。 Activity使用外部类,包括LazyAdapter.java,ImageLoader.java和XMLParser.java。如何将从Web获取数据的部分放入AsyncTask类。

以下是主要活动:

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

3 个答案:

答案 0 :(得分:0)

试试这个

在活动中创建

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

}

答案 1 :(得分: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();

答案 2 :(得分:0)

基本上,正如示例所示,您将要执行的内容放在doInBackground()方法中,然后您可以在不同的时间调用您想要执行的任何生命周期方法(在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      
    }

}