0

所以我设置了这个解析代码,我得到了 NetworkOnMainThreadException,所以我想把它包装在一个 AsyncTask 中,但我不知道该放什么以及放哪里..

我已经阅读了一些关于 AsyncTask 的教程,但它们都有些令人困惑,我想知道是否有人能指出我应该将我现在拥有的块放在哪里:

Noticias.java (MainActivity):

public class Noticias extends ListActivity {



static final String URL = "http://loc.grupolusofona.pt/index.php/?format=feed";

static final String KEY_ITEM = "item"; 
static final String KEY_TITLE = "title";
static final String KEY_DESC = "description";
static final String KEY_LINK = "link";
static final String KEY_PUBDATE = "pubDate";

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_noticias);

    ArrayList<HashMap<String, Spanned>> menuItems = new ArrayList<HashMap<String, Spanned>>();

    XMLParser parser = new XMLParser(); 
    String xml = parser.getXmlFromUrl(URL);
    Document doc = parser.getDomElement(xml); 

    NodeList nl = doc.getElementsByTagName(KEY_ITEM);

    String data[] = new String[nl.getLength()];

    for (int i = 0; i < nl.getLength(); i++) {

        HashMap<String, Spanned> map = new HashMap<String, Spanned>();
        Element e = (Element) nl.item(i);

        //Date Conversion
        data[i] = getTagValue("pubDate", e);
        SimpleDateFormat sdf = new SimpleDateFormat("EE, dd MMM yyyy HH:mm:ss z", Locale.UK);
        Date date = null;

        try {
            date = sdf.parse(data[i]); 
            String timeOfDay = new SimpleDateFormat("HH:mm").format(date); 
            java.sql.Timestamp timeStampDate = new Timestamp(date.getTime());
            java.sql.Timestamp timeStampNow = new Timestamp((new java.util.Date()).getTime()); 

            long secondDiff = timeStampNow.getTime() / 1000 - timeStampDate.getTime() / 1000;
            int minuteDiff = (int) (secondDiff / 60);
            int hourDiff = (int) (secondDiff / 3600);
            int dayDiff = daysBetween(date, new Date()); 
            if (dayDiff > 0) {
                System.out.println("Há " + dayDiff + " dia(s), às " + timeOfDay); 
                data[i] = ("Há " + dayDiff + " dia(s), às " + timeOfDay);


            } else if (hourDiff > 0) {
                System.out.println("Há " + hourDiff + " hora(s), às " + timeOfDay);
                data[i] = ("Há " + hourDiff + " hora(s), às " + timeOfDay);


            } else if (minuteDiff > 0) {
                System.out.println("Há " + minuteDiff + " minuto(s), às " + timeOfDay);
                data[i] = ("Há " + minuteDiff + " minuto(s), às " + timeOfDay);


            } else if (secondDiff > 0) {
                System.out.println("Há " + secondDiff + " segundo(s), às " + timeOfDay);
                data[i] = ("Há " + secondDiff + " segundo(s), às " + timeOfDay);

            }
        } catch (ParseException e1) {
            e1.printStackTrace();
        } catch (java.text.ParseException e1) {
            e1.printStackTrace();
        }

        //Html.fromHtml to get <CDATA> Description          
        map.put(KEY_TITLE, Html.fromHtml(parser.getValue(e, KEY_TITLE)));
        map.put(KEY_DESC, Html.fromHtml(parser.getValue(e, KEY_DESC)));
        map.put(KEY_PUBDATE, Html.fromHtml(data[i]));
        map.put(KEY_LINK, Html.fromHtml(parser.getValue(e, KEY_LINK)));

        menuItems.add(map);

    } //endFOR


    //Using ListAdapter is enough for this, no need for Custom Adapter
    ListAdapter adapter = new SimpleAdapter(this, menuItems, R.layout.linhafeed, 
            new String[] { KEY_TITLE, KEY_DESC, KEY_PUBDATE, KEY_LINK },
            new int[] { R.id.title, R.id.desc, R.id.pub, R.id.link });

    setListAdapter(adapter);


    ListView lv = getListView();

    //Opening Link onClick
    lv.setOnItemClickListener(new OnItemClickListener() {

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

            String link = ((TextView) view.findViewById(R.id.link)).getText().toString();
            System.out.println("Link: " + link);
            Intent in = new Intent(Intent.ACTION_VIEW);
            in.setData(Uri.parse(link));
            startActivity(in);
        }
    });


}

private static String getTagValue(String sTag, Element e) { 
    NodeList nlList = e.getElementsByTagName(sTag).item(0).getChildNodes();
    Node nValue = (Node) nlList.item(0);
    return nValue.getNodeValue();
}

public static int daysBetween(Date startDate, Date endDate) { 

    int daysBetween = 0;
    while (startDate.before(endDate)) {
        startDate.setTime(startDate.getTime() + 86400000);
        daysBetween++;
    }
    return daysBetween;

}
}

和 XMLParser.java:

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 ) {

     if( elem != null){
         return elem.getTextContent();
             }


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

谢谢你的时间。

4

1 回答 1

2

简单地说,您应该将进行连接的部分放在 中,doInBackground将修改 ui 的部分放在onPostExecute..

示例(需要仔细检查):

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {

  private Context context;

 public DownloadFilesTask(Context context) {
    this.context = context;
 }

 protected void onPreExecute() {
         progressDialog = ProgressDialog.show(context, "", "msg", true); 
 }
 protected Long doInBackground(URL... urls) {
     XMLParser parser = new XMLParser(); 
String xml = parser.getXmlFromUrl(URL);
Document doc = parser.getDomElement(xml); 

NodeList nl = doc.getElementsByTagName(KEY_ITEM);

String data[] = new String[nl.getLength()];

for (int i = 0; i < nl.getLength(); i++) {

    HashMap<String, Spanned> map = new HashMap<String, Spanned>();
    Element e = (Element) nl.item(i);

    //Date Conversion
    data[i] = getTagValue("pubDate", e);
    SimpleDateFormat sdf = new SimpleDateFormat("EE, dd MMM yyyy HH:mm:ss z", Locale.UK);
    Date date = null;

    try {
        date = sdf.parse(data[i]); 
        String timeOfDay = new SimpleDateFormat("HH:mm").format(date); 
        java.sql.Timestamp timeStampDate = new Timestamp(date.getTime());
        java.sql.Timestamp timeStampNow = new Timestamp((new java.util.Date()).getTime()); 

        long secondDiff = timeStampNow.getTime() / 1000 - timeStampDate.getTime() / 1000;
        int minuteDiff = (int) (secondDiff / 60);
        int hourDiff = (int) (secondDiff / 3600);
        int dayDiff = daysBetween(date, new Date()); 
        if (dayDiff > 0) {
            System.out.println("Há " + dayDiff + " dia(s), às " + timeOfDay); 
            data[i] = ("Há " + dayDiff + " dia(s), às " + timeOfDay);


        } else if (hourDiff > 0) {
            System.out.println("Há " + hourDiff + " hora(s), às " + timeOfDay);
            data[i] = ("Há " + hourDiff + " hora(s), às " + timeOfDay);


        } else if (minuteDiff > 0) {
            System.out.println("Há " + minuteDiff + " minuto(s), às " + timeOfDay);
            data[i] = ("Há " + minuteDiff + " minuto(s), às " + timeOfDay);


        } else if (secondDiff > 0) {
            System.out.println("Há " + secondDiff + " segundo(s), às " + timeOfDay);
            data[i] = ("Há " + secondDiff + " segundo(s), às " + timeOfDay);

        }
    } catch (ParseException e1) {
        e1.printStackTrace();
    } catch (java.text.ParseException e1) {
        e1.printStackTrace();
    }

    //Html.fromHtml to get <CDATA> Description          
    map.put(KEY_TITLE, Html.fromHtml(parser.getValue(e, KEY_TITLE)));
    map.put(KEY_DESC, Html.fromHtml(parser.getValue(e, KEY_DESC)));
    map.put(KEY_PUBDATE, Html.fromHtml(data[i]));
    map.put(KEY_LINK, Html.fromHtml(parser.getValue(e, KEY_LINK)));

    menuItems.add(map);

} //endFOR
 }

 protected void onPostExecute(Long result) {
     progressDialog.dismiss();  

     //Using ListAdapter is enough for this, no need for Custom Adapter
ListAdapter adapter = new SimpleAdapter(this, menuItems, R.layout.linhafeed, 
        new String[] { KEY_TITLE, KEY_DESC, KEY_PUBDATE, KEY_LINK },
        new int[] { R.id.title, R.id.desc, R.id.pub, R.id.link });

setListAdapter(adapter);
 }
}

创建时:

public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_noticias);

ArrayList<HashMap<String, Spanned>> menuItems = new ArrayList<HashMap<String, Spanned>>
();
   new DownloadFilesTask(this).execute();
}
于 2012-12-11T10:55:42.133 回答