Trabalhando com XML no Android

Nesse artigo, você irá aprender como criar um aplicação Android que trabalhe com arquivos XML da Internet. As aplicações Android são escritas com a linguagem de programação Java, sendo assim é necessário ter experiência com Java. Para desenvolver para a plataforma Android, você precisará do SDK de Android, Todos os códigos mostrados nesse artigo funcionarão com qualquer versão do SDK, mas a versão 1.5-pre foi usada para desenvolver o código. Você pode desenvolver aplicações Android apenas com o SDK e um editor de texto, mas é muito mais fácil usar o ADT, que é um plugin para o Eclipse. Nesse artigo, a versão 0.9 do ADT foi usada com o Eclipse 3.4.2.

XML no Android

A plataforma Android é uma plataforma de desenvolvimento para dispositivos móveis open-source. Ela lhe dá acesso a todos os aspectos do dispositivo onde ela roda, desde gráficos de baixo nível até hardware como a câmera e o telefone. Com tantas coisas possíveis de serem usadas no Android, você pode se perguntar por quê precisa se incomodar com XML. Não que trabalhar com XML seja tão interessante; é trabalhar com as coisas que estão disponíveis. O XML é normalmente usado como um formato de dados na Internet. Se quiser acessar dados da Internet, existem grandes chances de que esse dado esteja na forma de um arquivo XML. Se quiser enviar dados para um serviço web, pode também ser preciso enviar XML. Em resumo, se sua aplicação Android for tirar vantagem do acesso a Internet, então ela irá provavelmente precisar tarbalhar com XML. Por causa disso, o Android lhe dá várias opções para trabalhar com XML.

Analisadores XML

Uma das grandes forças da plataforma Android é o uso da linguagem de programação Java. O SDK do Android não oferece todas as bibliotecas de seu JRE padrão, mas suporta uma fração significativa dele. A plataforma Java suporta muitas maneiras diferentes de trabalhar com XML, e muitas das APIś do Java relacionadas a XML são completamente suportadas no Android. Por exemplo, o SAX e o DOM são ambas disponíveis no Android. Essas duas API’s são parte da tecnologia Java há muitos anos. A recente StAX não está disponível no Android. Porém, o Android fornece uma biblioteca com funcionalidade equivalente.  Finalmente, a API Java XML Binding não está disponível no Android. Essa API certamente poderia ser implementada no Android. Porém, ela tende a ser uma API pesada, com muitas instâncias de muitas classes diferentes que frequentemente precisam representar um documento XML. Assim, não é a API ideal para um ambiente enxuto como os dispositivos onde o Android é executado. Nas seções seguintes, pegaremos alguns exemplos de arquivo XML, e veremos como analisa-los dentro de uma aplicação Android usando as várias API mencionadas acima. Para começar, vamos dar uma olhada nas partes de uma aplicação simples que usará o arquico XML.

Leitor de feeds RSS para Android

A aplicação pegará um feed RSS do popular site Androidster e gerará uma lista de objetos Java simples que você pode usar em um ListView na aplicação Android (baixe o código-fonte na seção Download). Esse é um comportamento polimórfico clássico – implementações diferentes (algoritmos de análise de XML diferentes) que fornecem o mesmo recursos. A Listagem 1 mostra quão fácil você pode modelar isso em código Java usando uma interface.

Listagem 1. interface do analisador de feeds XML

package org.developerworks.android;
import java.util.List;
public interface FeedParser {
    List<Message> parse();
}

Na Listagem 2, a classe Message é uma classica POJO (Plain Old Java Object) que representa a estrutura do dado.

Listagem 2. POJO Message

public class Message implements Comparable<Message>{
    static SimpleDateFormat FORMATTER =
        new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z");
    private String title;
    private URL link;
    private String description;
    private Date date;
      // getters and setters omitted for brevity
    public void setLink(String link) {
        try {
            this.link = new URL(link);
        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        }
    }
    public String getDate() {
        return FORMATTER.format(this.date);
    }
    public void setDate(String date) {
        // pad the date if necessary
        while (!date.endsWith("00")){
            date += "0";
        }
        try {
            this.date = FORMATTER.parse(date.trim());
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }
    @Override
    public String toString() {
             // omitted for brevity
    }
    @Override
    public int hashCode() {
            // omitted for brevity
    }
    @Override
    public boolean equals(Object obj) {
            // omitted for brevity
    }
      // sort by date
    public int compareTo(Message another) {
        if (another == null) return 1;
        // sort descending, most recent first
        return another.date.compareTo(date);
    }
}

A classe Message, na Listagem 2, é bem direta. Ela esconde seu estado interno  permitindo que datas e links sejam acessadas como strings simples, mas representa esses dados como objetos de tipagem mais forte (java.util.Date e java.net.URL). É um clássico Value Object, que permite implementar equals() e hasjCode() baseado no seu estado interno. Também implementa a interface Comparable, de forma que você pode classificar os dados por algum tipo de ordenação (por data, por exemplo). Na prática, os dados vem ordenados do feed, de forma que isso não é necessário.
Cada uma das implementações do analisador precisará pegar uma URL do Androidster e usa-la para abrir uma conexão HTTP com o site. Esse comportamento é naturalmente modelado em código Java usando a classe abstrata da Listagem 3.

Listagem 3. Classe do analisador básico de feeds

public abstract class BaseFeedParser implements FeedParser {
    // names of the XML tags
    static final String PUB_DATE = "pubDate";
    static final  String DESCRIPTION = "description";
    static final  String LINK = "link";
    static final  String TITLE = "title";
    static final  String ITEM = "item";
    final URL feedUrl;
    protected BaseFeedParser(String feedUrl){
        try {
            this.feedUrl = new URL(feedUrl);
        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        }
    }
    protected InputStream getInputStream() {
        try {
            return feedUrl.openConnection().getInputStream();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

A classe base armazena a feedUrl e usa-a para abrir um java.io.InputStream. Se alguma coisa der errado, simplesmente dispara uma RuntimeException, de forma que a aplicação falha rapidamente. A classe base define algumas constantes simples para os nomes das tags. A Listagem 4 mostra o conteúdo do feed, de forma que você pode ver o significado dessas tags.

Listagem 4. Exemplo de feed XML

<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="FeedCreator 1.7.2" -->
<rss version="2.0">
  <channel>
    <title>android_news</title>
    <description>android_news</description>
    <link>http://www.androidster.com/android_news.php</link>
    <lastBuildDate>Sun, 19 Apr 2009 19:43:45 +0100</lastBuildDate>
    <generator>FeedCreator 1.7.2</generator>
    <item>
      <title>Samsung S8000 to Run Android, Play DivX, Take Over the
World</title>
      <link>http://www.androidster.com/android_news/samsung-s8000-to-run-android-
play-divx-take-over-the-world</link>
      <description>More details have emerged on the first Samsung handset
to run Android. A yet-to-be announced phone called the S8000 is being
reported ...</description>
      <pubDate>Thu, 16 Apr 2009 07:18:51 +0100</pubDate>
    </item>
    <item>
      <title>Android Cupcake Update on the Horizon</title>
      <link>http://www.androidster.com/android_news/android-cupcake-update-
on-the-horizon</link>
      <description>After months of discovery and hearsay, the Android
build that we have all been waiting for is about to finally make it
out ...</description>
      <pubDate>Tue, 14 Apr 2009 04:13:21 +0100</pubDate>
    </item>
  </channel>
</rss>

Como você pode ver na Listagem 4, um ITEM corresponde a uma instância de Message. O nó filho de item(TITLE,LINK,e assim em diante) corresponde as propriedades da instância de Message. Agora que você sabe como o feed se aprece, e tem todas as partes comuns no lugar, vamos ver como analisar esse feed usando as diversas tecnologias disponíveis no Android. Vamos começar com o SAX.

Usando SAX

No ambiente Java, você pode sempre usar a API do SAX quando você precisar de um analisador rápido e quiser minimizar o uso da memória por sua aplicação. Essa caracteristica torna a API bastante adequada para um dispositivo móvel que roda Android. Você pode usar a API do SAX de forma analoga ao uso no ambiente Java, sem nenhuma modificação especial necessária para executa-la no Android. A Listagem 5 mostra uma implementação SAX da interface FeedParser.

Listagem 5. Implementação do SAX

public class SaxFeedParser extends BaseFeedParser {
    protected SaxFeedParser(String feedUrl){
        super(feedUrl);
    }
    public List<Message> parse() {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        try {
            SAXParser parser = factory.newSAXParser();
            RssHandler handler = new RssHandler();
            parser.parse(this.getInputStream(), handler);
            return handler.getMessages();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

Se você já tiver usado o SAX antes, essa implementação lhe será bastante familiar. Como qualquer implementação do SAX, muitos dos detalhes são internos do manipulador SAX. O manipulador recebe eventos do analisador que percorreu o documento XML. Nesse caso, você tem que criar uma classe chamada RssHandler e registra-la como manipulador para o analisador, como na Listagem 6.

Listagem 6. O manipulador do SAX

import static org.developerworks.android.BaseFeedParser.*;
public class RssHandler extends DefaultHandler{
    private List<Message> messages;
    private Message currentMessage;
    private StringBuilder builder;
    public List<Message> getMessages(){
        return this.messages;
    }
    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        super.characters(ch, start, length);
        builder.append(ch, start, length);
    }
    @Override
    public void endElement(String uri, String localName, String name)
            throws SAXException {
        super.endElement(uri, localName, name);
        if (this.currentMessage != null){
            if (localName.equalsIgnoreCase(TITLE)){
                currentMessage.setTitle(builder.toString());
            } else if (localName.equalsIgnoreCase(LINK)){
                currentMessage.setLink(builder.toString());
            } else if (localName.equalsIgnoreCase(DESCRIPTION)){
                currentMessage.setDescription(builder.toString());
            } else if (localName.equalsIgnoreCase(PUB_DATE)){
                currentMessage.setDate(builder.toString());
            } else if (localName.equalsIgnoreCase(ITEM)){
                messages.add(currentMessage);
            }
            builder.setLength(0);
        }
    }
    @Override
    public void startDocument() throws SAXException {
        super.startDocument();
        messages = new ArrayList<Message>();
        builder = new StringBuilder();
    }
    @Override
    public void startElement(String uri, String localName, String name,
            Attributes attributes) throws SAXException {
        super.startElement(uri, localName, name, attributes);
        if (localName.equalsIgnoreCase(ITEM)){
            this.currentMessage = new Message();
        }
    }
}

A classe RssHandler é herdeira da classe org.xml.sax.helpers.DefaultHandler. Essa classe fornece implementações padrões para todos os métodos que correspondem aos eventos disparados pelo analisador SAX. Isso permite que a sub-classe sobrecarregue apenas os métodos necessários. A classe RssHandler possui uma API adicional, getMessages. Ela retorna a lista de objetos Message que o manipulador coleciona a medida que recebe eventos do analisador. Ela possui duas variáveis internas, uma currentMessage para a instância de Message que está sendo analisada, e uma variável StringBuilder  que armazena os dados dos nós textuais. Essas duas variáveis são inicializadas quando o método startDocument é invocado quando o analisador envia o evento correspondente para o manipulador.

Dê uma olhada no método startElement na Listagem 6. Esse método é chamado a cada vez que uma tag de abertura é encontrada no dicumento XML. Você apenas deve cuidar disso quando essa tag pe uma tag ITEM. Nesse caso, deve ser criado uma nova instância de Message. Agora olhe para o método character. Esse método é chamado quando um dado textual do nó é encontrado. O dado é simplesmente adicionado a variável builder. Finalmente, olha para o método endElement. Esse método é chamado  quando uma tag de encerramento é encontrada. Para as tags correspondentes a propriedades de Message, como TITLE e LINK, a propriedade adequada é configurada em currentMessage usando o dado da variável builder. Se a tag de encerramento for um ITEM, então currentMensage é adicionada a lista de Messages. Isso tudo é bem típico da análise SAX; nada aqui é único para o Android. Assim, se você sabe escrever um analisador SAX em Java, então sabe como escrever um analisador SAX para Android. Porém, o SDK do Android adiciona alguns recursos convenientes a API do SAX.

Análise fácil de SAX

O SDK do Android contém uma classe utilitária chamada android.util.Xml. A Listagem 7 mostar como criar um analisador SAX com essa classe utilitária.

Listagem 7. Analisdor SAX do Android

public class AndroidSaxFeedParser extends BaseFeedParser {
    public AndroidSaxFeedParser(String feedUrl) {
        super(feedUrl);
    }
    public List<Message> parse() {
        RssHandler handler = new RssHandler();
        try {
            Xml.parse(this.getInputStream(), Xml.Encoding.UTF_8, handler);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return handler.getMessages();
    }
}

Observe que essa classe ainda usa um manipulador SAX padrão, assim você pode re-utilizar a classe RssHandler mostrada acima na Listagem 7.  Poder reutilizar o manipulador SAX é muito útil, mas é de qualquer forma um pedaço complicado de código. Você pode imaginar que se tiver de analisar um documento XML mais complexo, que o manipulador pode tornar-se suscetivel a bugs. Por exemplo, olhe no método endElement na Listagem 6. Observe como ele checa se currentMessage é null antes de tentar configurar a propriedade? Agora olhe para o exemplo de arquivo XML da Listagem 4. Observe que existem tags TITLE e LINK fora de tags ITEM. Essa situação é o motivo da checagem pelo valor null. De outra forma a primeira tag TITLE poderia causar um NullPointerException. O ANdroid inclui a sua prórpia variação da API do SAX (veja a Listagem 8) que remove a necessidade da escrita de seu próprio manipulador SAX.

Listagem 8. Analisador SAX simplificado

public class AndroidSaxFeedParser extends BaseFeedParser {
    public AndroidSaxFeedParser(String feedUrl) {
        super(feedUrl);
    }
    public List<Message> parse() {
        final Message currentMessage = new Message();
        RootElement root = new RootElement("rss");
        final List<Message> messages = new ArrayList<Message>();
        Element channel = root.getChild("channel");
        Element item = channel.getChild(ITEM);
        item.setEndElementListener(new EndElementListener(){
            public void end() {
                messages.add(currentMessage.copy());
            }
        });
        item.getChild(TITLE).setEndTextElementListener(new EndTextElementListener(){
            public void end(String body) {
                currentMessage.setTitle(body);
            }
        });
        item.getChild(LINK).setEndTextElementListener(new EndTextElementListener(){
            public void end(String body) {
                currentMessage.setLink(body);
            }
        });
        item.getChild(DESCRIPTION).setEndTextElementListener(new
EndTextElementListener(){
            public void end(String body) {
                currentMessage.setDescription(body);
            }
        });
        item.getChild(PUB_DATE).setEndTextElementListener(new EndTextElementListener(){
            public void end(String body) {
                currentMessage.setDate(body);
            }
        });
        try {
            Xml.parse(this.getInputStream(), Xml.Encoding.UTF_8,
root.getContentHandler());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return messages;
    }
}

Como prometido, o código do novo analisador SAX não usa um manipulador SAX. Ao invés disso ela usa as classes do pacote android.sax do SDK. Isso permite que você modele a estrutura de seu documento XML e adicione um evet listener quando necessário. No código acima, você declara que seu documento terá um elemento raiz chamado rss  e esse elemento terá um elemento filho chamado channel. Então você  diz que esse channel terá um elemento filho chamado ITEM e começa a adicionar listeners. Para cada listener, você usa uma classe interna anônima que implementa a interface que você estar interessado (EndElementListner ou EndTextElementListener). Observe que não existe necessidade de mencionar os dados textuais. Não apenas isso é mais simples, mas é mais eficiente. Finalmente, quando você invocar o método utilitário Xml.parse, você precisa passar agora um manipulador que é gerado a partir do elemento raiz.

Tudo o que foi mostrado no código da Listagem 8 é opcional. Se você estiver confortável com o código de análise padrão do SAX do ambiente Java, então você pode usa-lo. Se quiser usar os empacotadores convencionais fornecidos pelo SDK do Android, você pode usar também. E se você não quiser usar o SAX? Algumas alternativas estão disponíveis. Uma delas é o DOM.

Trabalhando com DOM

A análise DOM é completamento suportada no Android. Funciona exatamente como em um código Java que você executaria em uma máquina desktop ou em um servidor. A Listagem 9 mostra uma implementação baseada no DOM de uma interface de análise.

Listagem 9. Implementação baseada em DOM do analisador de feeds

public class DomFeedParser extends BaseFeedParser {
    protected DomFeedParser(String feedUrl) {
        super(feedUrl);
    }
    public List<Message> parse() {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        List<Message> messages = new ArrayList<Message>();
        try {
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document dom = builder.parse(this.getInputStream());
            Element root = dom.getDocumentElement();
            NodeList items = root.getElementsByTagName(ITEM);
            for (int i=0;i<items.getLength();i++){
                Message message = new Message();
                Node item = items.item(i);
                NodeList properties = item.getChildNodes();
                for (int j=0;j<properties.getLength();j++){
                    Node property = properties.item(j);
                    String name = property.getNodeName();
                    if (name.equalsIgnoreCase(TITLE)){
                        message.setTitle(property.getFirstChild().getNodeValue());
                    } else if (name.equalsIgnoreCase(LINK)){
                        message.setLink(property.getFirstChild().getNodeValue());
                    } else if (name.equalsIgnoreCase(DESCRIPTION)){
                        StringBuilder text = new StringBuilder();
                        NodeList chars = property.getChildNodes();
                        for (int k=0;k<chars.getLength();k++){
                            text.append(chars.item(k).getNodeValue());
                        }
                        message.setDescription(text.toString());
                    } else if (name.equalsIgnoreCase(PUB_DATE)){
                        message.setDate(property.getFirstChild().getNodeValue());
                    }
                }
                messages.add(message);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return messages;
    }
}

Como no exemplo SAX, nada é especifico para o Android nesse código. O analisador DOM lê todo o documento XML na memória e depois permite usar as API´s do DOM para percorrer pela árvore XML, recuperando os dados que você quiser. Esse código é bem direto, e, em alguns casos, mais simples que a implementação baseada no SAX. Porém, o DOM geralmente consume mais memória pois todo o documento é carregado na memória primeiro. Isso pode ser um problema em dispositivos móveis que rodam Android, mas pode ser satisfatório em certos casos onde o tamanho do documento XML nunca ficará grande. Pode-se dizer que os desenvolvedores Android usam mais a análise SAX em aplicações Android, por isso existem utilitários extras para o SAX. Um outro tipo de analisador XML disponível no ANdroid é Analisador de arranque (pull parser).

Analisador de arranque (pull parser) XML

Como mencionado antes, o Android não fornece suporte para a API StAX do Java. Porém, o Android vem com um analisador de arranque que funciona de modo parecido com o StAX. Ele permite que o código de sua aplicação puxe ou busce eventos do analisador, ao contrário do analisador SAX que empurra os eventos para o manipulador automaticamente. A Listagem 10 mostra uma implementação de um analisador de arranque para a interface do analisador de feeds.

Listagem 10. Implementação base do analisador de arranque

public class XmlPullFeedParser extends BaseFeedParser {
    public XmlPullFeedParser(String feedUrl) {
        super(feedUrl);
    }
    public List<Message> parse() {
        List<Message> messages = null;
        XmlPullParser parser = Xml.newPullParser();
        try {
            // auto-detect the encoding from the stream
            parser.setInput(this.getInputStream(), null);
            int eventType = parser.getEventType();
            Message currentMessage = null;
            boolean done = false;
            while (eventType != XmlPullParser.END_DOCUMENT && !done){
                String name = null;
                switch (eventType){
                    case XmlPullParser.START_DOCUMENT:
                        messages = new ArrayList<Message>();
                        break;
                    case XmlPullParser.START_TAG:
                        name = parser.getName();
                        if (name.equalsIgnoreCase(ITEM)){
                            currentMessage = new Message();
                        } else if (currentMessage != null){
                            if (name.equalsIgnoreCase(LINK)){
                                currentMessage.setLink(parser.nextText());
                            } else if (name.equalsIgnoreCase(DESCRIPTION)){
                                currentMessage.setDescription(parser.nextText());
                            } else if (name.equalsIgnoreCase(PUB_DATE)){
                                currentMessage.setDate(parser.nextText());
                            } else if (name.equalsIgnoreCase(TITLE)){
                                currentMessage.setTitle(parser.nextText());
                            }
                        }
                        break;
                    case XmlPullParser.END_TAG:
                        name = parser.getName();
                        if (name.equalsIgnoreCase(ITEM) &&
currentMessage != null){
                            messages.add(currentMessage);
                        } else if (name.equalsIgnoreCase(CHANNEL)){
                            done = true;
                        }
                        break;
                }
                eventType = parser.next();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return messages;
    }
}

Um analisador de arranque funciona de forma similar a um analisador SAX. Tem eventos similares (iniciar elemento, encerrar elemento) mas você tem que puxar eles (parser.next()). Os eventos são enviados como códigos numéricos, de forma que você pode usar uma estrutura case-switch. Observe que, ao invés de ficar esperando pelo final do elemento como na análise SAX, nesse tipo de analisador, a maior parte do processamento é feito no inicio. No código da Listagem 10, quando um elemento inicia, vocÊ pode chamar parser.nextText() par apuxar todos os dados de documento XML. Isso oferece uma simplificação da análise SAX. Observe também que você configura uma flag (a variavel booleana done) para identificar quando o final do conteúdo de interesse é alcançado. Isso deixa que você pare a leitura do documento do documento XML mais cedo, se você soubver que o código não irá tratar do resto do documento. Isso pode ser bastante útil, especialmente se você precisa apenas de uma porção pequena do documento XML a ser acessado. Você pode reduzir bastante o tempo de análise pelo interrompimento da análise o mais cedo possível. O analisador de arranque pode ter algumas vantagens de performance assim como algumas facilidades de uso. Ele pode ser usado para escrever XML também.

Criando XML

Até agora, nos concentramos na análise de XML da Internet. Porém, algumas vezes sua aplicação pode precisar enviar um documento XML para um servidor remoto. Você pode obviamente usar um StringBuilder ou algo similar para criar uma string contendo o conteúdo do documento XML. Uma outra alternativa vem do analisador de arranque da Listagem 11:

Listagem 11. Escrevendo XML com o analisador de arranque

private String writeXml(List<Message> messages){
    XmlSerializer serializer = Xml.newSerializer();
    StringWriter writer = new StringWriter();
    try {
        serializer.setOutput(writer);
        serializer.startDocument("UTF-8", true);
        serializer.startTag("", "messages");
        serializer.attribute("", "number", String.valueOf(messages.size()));
        for (Message msg: messages){
            serializer.startTag("", "message");
            serializer.attribute("", "date", msg.getDate());
            serializer.startTag("", "title");
            serializer.text(msg.getTitle());
            serializer.endTag("", "title");
            serializer.startTag("", "url");
            serializer.text(msg.getLink().toExternalForm());
            serializer.endTag("", "url");
            serializer.startTag("", "body");
            serializer.text(msg.getDescription());
            serializer.endTag("", "body");
            serializer.endTag("", "message");
        }
        serializer.endTag("", "messages");
        serializer.endDocument();
        return writer.toString();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

A classe XmlSerializer é parte do mesmo pacote de XmlPullParser usada na seção anterior. Ao invés de puxar eventos, ela empurra eles para um stream. Nesse caso, ele simplesmente empurra os dados para uma instãncia de java.io.StringWirter. É fornecida uma API direta com métodos para iniciar e encerrar um documento, processar um elemento, e adicionar texto ou atributos. Essa pode ser uma alternativa melhor do que usar um StringBuilder, pois garante que seu documento XML esteja bem formatado.

Sumário

Que tipo de aplicação você quer criar para dispositivos Android? Qualquer que seja, se ela precisar trabalhar com dados oriundos da Internet, então ela provavelmente precisa trabalhar com XML. Nesse artigo, vimos que o Android vem com várias ferramentas para lidar com XML. Você pode escolher uma delas de acordo com sua vontade ou casio de uso. Na maior parte de tempo a escolha segura é usar SAX, e o Android fornece a você tanto a abordagem tradicional quanto um empacotador conveniente para a API do SAX. Se seu documento for pequeno, então talvez o DOM seja uma maneira mais simples. Se seu documento for grande, mas você precisa de apenas parte dele, então o analisador de arranque pode ser uma maneira mais eficiente. Finalmente, para escrever XML, o pacote do analisador de aaranque fornece um jeito conveniente para fazer isso. Assim, qualquer que seja sua necessidade relacionada a XML, o SDL do Android tem algo para você.

Download

Name Size Download method
AndroidXml.zip 70KB HTTP

 Recursos

Obtenha produtos e tecnologias

Discussão

Traduzido de