Question

I am having a lot of difficulty adding a Asynctask to my app. I have a ArticleList Activity which pulls xml from the wen then populates a ListView. The Activity uses external classes including a LazyAdapter.java, ImageLoader.java and XMLParser.java. How do i put the part where it fetches the data from the web into an AsyncTask class.

Here is the Main Activity:

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

    }

}

Here is the 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));
    }
}
Was it helpful?

Solution

You can try as follows...

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

}

In MainActivity.java...

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

OTHER TIPS

Try this

In activity oncreate

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

Inside class

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

}

Basically, as the examples suggest, you put the things you want to execute in the doInBackground() method, then you can call whatever lifecycle methods you want to do things at different times (before or after the things in your doInBackground method).

So a an simple template would be started using this command:

new MyAsyncTask.execute();

and the class would look like:

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      
    }

}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top