Prévia do material em texto
REVISÃO - Desenvolvimento para Dispositivos Móveis - COM450 Esta revisão está fortemente baseada na sequência de conteúdos tratados e discutidos nas videoaulas e nos textos base que compõem o curso, e busca extrair e sintetizar os principais tópicos e conceitos apresentados ao longo do curso. Lembramos que somente a leitura deste material não é suficiente para o seu estudo. Este material deve ser usado mais fortemente como um guia para relembrá-lo(a) dos assuntos tratados. O estudo dos materiais-base é de fundamental importância para que você possa ter um bom aproveitamento nas avaliações. Bons estudos! Dispositivos Móveis (o que são?) De uma forma geral, podemos dizer que dispositivos móveis são dispositivos tecnológicos, que possuem duas características básicas: mobilidade e capacidade de conexão remota. Além dessas, outras características tipicamente encontradas em dispositivos móveis são: • uso de bateria; • dimensões e peso reduzidos; • teclado físico ou tela para inserção/visualização de informações; • capacidade de acesso a internet e de conexão com outros dispositivos através de alguma tecnologia de acesso sem fio (e.g. wifi, celular, bluetooth); Dentro os dispositivos móveis mais encontrados no nosso dia a dia estão: • smartphones; • tables; • wearables ou vestíveis (e.g. smartwatches). Atualmente encontramos diversas aplicações que utilizam dispositivos móveis. Estas aplicações normalmente são oferecidas na forma de aplicativos(apps), que são softwares (programas), que lançam mão dos recursos dos dispositivos móveis (e.g. câmera, GPS, conexão remota, sensores), para oferecer algum serviço/funcionalidade, tais como: • comunicação pessoal - (e.g. Whatsapp, Telegram); • entretenimento - games, filmes, (e.g. Netflix, Amazon) músicas - (e.g. Deezer, Spotify); • localização/deslocamento - (e.g. Waze, Uber); • compras - (e.g. ifood, americanas); • financeira - (e.g. app de bancos, app de corretoras); • saúde - (e.g. apps de relaxamento, monitoramento do sono e de exercícios físicos); • social (e.g ConecteSUS, Educação Conectada, e-Título). A evolução dos recursos tecnológicos presentes nos dispositivos móveis, além da sua miniaturização, tem possibilitado cada vez mais o seu uso na forma de dispositivos vestíveis, além da possibilidade de novas interfaces de interação com o usuário como é o caso do uso da realidade aumentada (AR), que possibilita a integração de informações virtuais com elementos do mundo real através de uma câmera. Além do uso de algoritmos de aprendizado de máquina (ML), incorporados aos aplicativos, fornecendo aos aplicativos a capacidade de aprender e melhorar automaticamente com a experiência, sem serem explicitamente programados para isso. A disseminação do uso de dispositivos móveis tem também contribuído para a chamada computação ubíqua ou pervasiva, que é o termo utilizado para descrever a onipresença de computadores no cotidiano das pessoas. Assim, a domótica que se refere a automação residencial, tem através da presença de dispositivos móveis tais como smartphones e smartwatches (que no fundo são computadores), contribuído para computação ubíqua. Market Share Do ponto de vista do mercado global de vendas de dispositivos móveis, os três principais representados são: • mercado de smartphones; • mercado de tablets; • mercado de smartwatches. Para entendermos o market share entre os diferentes fornecedores de dispositivos móveis e de sistemas operacionais, é importante observarmos alguns aspectos relevantes: Atualmente o mercado de sistemas operacionais está dividido majoritariamente entre dois grandes fornecedores: Google, com o sistema operacional Android para smartphones e tablets, e o WearOs para smartwatches, e Apple, com o sistema operacional iOS para smartphones e tables e watchOS para smartwatches. O sistema Android é um sistema aberto, que é instalado e fornecido em dispositivos de diversos fabricantes, ao passo que o sistema da Apple só é fornecido para os dispositivos fabricados pela própria Apple. Deste fato, resulta que o Android está presente em cerca de 85% dos smartphones, contra 15% de participação da Apple. No entanto, devido a Apple atender a um público em média com maior poder aquisitivo (poder de compra), o faturamento na venda de aplicativos pagos da Apple é significativamente superior à venda de aplicativos do Google. Em relação à venda de smartphones (dispositivo), temos um mercado bastante dividido entre fabricantes, mas com uma ligeira liderança da Huawei (segundo dados de 2020). Uma outra questão relevante, é que o Android lança novas versões do seu sistema operacional com mais frequência que a Apple. Isto muitas vezes pode ser uma limitação do ponto de vista de desenvolvimento de aplicativos para Android, uma vez que diversas versões coexistem na base de usuários. Limitando por vezes as funcionalidades ou a compatibilidade dos apps para diferentes versões de sistema operacional, ou ainda demandando atualizações de aplicativos com maior frequência. No mercado de tablets, temos a liderança da Apple na venda de dispositivos. Já na parte de sistemas operacionais, o sistema Android tem uma ampla liderança, seguido pelo iOS, verifica-se ainda uma presença significativa do sistema operacional Windows. No mercado de smartwatches, a Apple domina tanto na venda de dispositivos como na presença do seu sistema operacional watchOS. Dispositivos móveis e os computadores de uso geral De uma forma geral, dispositivos móveis têm um menor acesso a recursos de hardware e fornecimento de energia que um computador de uso geral, devido as suas características de tamanho reduzido e mobilidade. Em contrapartida, os dispositivos móveis normalmente contam com um maior número de tecnologias de conexão sem fio, além de um grande número de sensores. Estas características somadas a mobilidade, permitem a criação de diversas aplicações (e aplicativos) capazes de interagir com o ambiente externo, que não são possíveis com o uso computadores de uso geral. Finalmente, com a evolução das tecnologias, não apenas de processamento e armazenamento, mas no que se refere à fabricação de baterias e sensores, será cada vez mais possível a realização de tarefas antes restritas aos computadores de uso geral. Recursos de Hardware Os dispositivos móveis contam com diferentes recursos de hardware, principalmente no que se refere a sensores e componentes para diferentes tipos de conexão sem fio. Durante o curso na videoaula "Recursos de Hardware", foram explorados os recursos de um smartphone. Vimos que atualmente, os smartphones podem ser vistos como um "superset" de outros dispositivos móveis em termos de recursos de hardware, ou seja, a grande maioria dos recursos encontrados em outros dispositivos móveis, estão presentes nos smartphones. Entre os recursos de hardware estão: • CPU: Se apresenta na forma de uma SOC (System On a Chip), podem conter diversos componentes internos além do processador (e.g. modem, codificador e decodificador de vídeo); • Módulos Wireless: permitem conexão sem fio utilizando diferentes tecnologias (e.g. transceptor de RF, receptor GPS, módulo NFC, módulo WI-FI, módulo Bluetooth); • câmeras: Atualmente os smartphones apresentam arranjos com mais de uma câmera, tanto frontais como traseiras; • Sensores: smartphones e dispositivos móveis de um modo geral, podem contar com dezenas de sensores. Sensores são dispositivos que respondem a alguma variação de um parâmetro físico no ambiente, como temperatura, pressão, aceleração etc. Alguns sensores normalmente encontrados são: ➢ Giroscópio: permite detectar se o aparelho girou sobre o seu próprio eixo; ➢ Acelerômetro: detecta aceleração; ➢ Magnetômetro: permite detectar campos magnéticos; ➢ Infravermelho: pode ser utilizado como sensor de velocidade. As tecnologias de fabricação de telas utilizadas em dispositivosmóveis também tem evoluído consideravelmente. Tem-se observado aumento significativo na definição, redução de peso e de consumo de energia. Abaixo temos em sequência, a evolução das tecnologias de fabricação de telas, com uma breve descrição das suas características. • LCD: telas de cristal líquido; • IPS: variação da tela de LCD, resultando em uma melhor qualidade de imagem; • OLED: utilizam diodos orgânicos emissores de luz no lugar de cristais líquidos, resultando em um menor consumo de energia, e uma espessura mais fina da tela; • AMOLED: derivada do OLED, esta tecnologia é capaz de melhorar a responsividade permitindo um controle de imagem mais rápido e preciso tornando as imagens mais fluidas; • Super AMOLED: incluem uma camada sensível ao toque, dispensando a camada de vidro do aparelho, com menor consumo e uma estrutura mais leve do aparelho. Também as tecnologias de fabricação de bateria evoluíram ao longo do tempo, tornando as baterias mais leves, com maior capacidade de carga (permitindo um maior tempo de operação dos dispositivos entre intervalos para recarga), e menos poluentes. Abaixo temos em sequência a evolução destas tecnologias, com uma breve descrição das suas características. • Níquel-Híbrido: utilizada nos primeiros aparelhos celulares. Possui uma longa durabilidade, no entanto é grande e pesada; • Níquel-Cádmio: Possui um custo baixo e uma vida útil relativamente longa. No entanto, além de apresentar o efeito de memória, leva na sua composição elementos tóxicos; • Íon-Lítio (Li+): possui a vantagem de não ficar “viciada”, pois não apresenta o efeito de memória. No entanto, é uma tecnologia sensível às altas temperaturas; • Lítio-polímero: apresenta características semelhantes à Li+ com uma redução de cerca de 20% no seu peso. É mais resistente à sobrecarga, o que a torna mais segura. Usabilidade A usabilidade está associada à experiência que um usuário tem quando utiliza um determinado aplicativo. A usabilidade diz respeito ao quão intuitivo, simples, agradável e útil o aplicativo se apresenta ao usuário. Entre as estratégias que podem ser utilizadas com o fim de melhorar a usabilidade de um aplicativo estão: estratégias de conteúdo, estratégias de apresentação e estratégias de desempenho. As estratégias de conteúdo visam: • Adequar a linguagem utilizada de forma conveniente para o público-alvo; • Evitar quantidades exageradas de dados ou informações que podem levar a uma navegação lenta e entediante; • Em muitas situações lançar mão de ferramentas de acessibilidade, incluindo usuários com alguma dificuldade ou deficiência. As estratégias de apresentação, dizem respeito à apresentação da interface de usuário (UI). Algumas técnicas para melhorar usabilidade na apresentação são: • Apresentação dos itens na UI respeitando uma hierarquia de importância; • Apresentação com ordem de foco, ou seja, seguindo o foco de como o usuário caminha ao longo da navegação de layout visual da tela; • Uso de tecnologias assistivas, que auxiliam a acessibilidade para indivíduos com deficiência, ou alguma dificuldade. As estratégias de desempenho, estão associadas ao quão eficiente o aplicativo é para interagir com o usuário. Assim é importante que um aplicativo possua: • Layout responsivo: onde a UI se adequa de forma a evitar “truncar” o conteúdo em dispositivos específicos ou com diferentes resoluções; • Baixa latência: uma quantidade exagerada de dados podem causar alta latência quando o aplicativo precisa baixar esses dados para fornecer informações ao usuário. O uso de cacheamento pode ser útil para aplicativos que acessam dados de websites. O cacheamento permite que parte dos dados dos websites sejam guardados em uma memória temporária, evitando que os dados necessitem ser recarregados em um novo acesso. Testes automatizados Tão importante quanto a etapa de desenvolvimento de um aplicativo móvel, é a etapa de testes e validação, que pode muitas vezes ser mais complexa que a própria etapa de desenvolvimento do código. Os testes realizados para a verificação e validação de um aplicativo irão testar diferentes aspectos relacionados ao seu funcionamento. Dentre as principais categorias de testes realizados para a validação de uma aplicativo estão: • Testes Funcionais: testam as funcionalidades do app, sem se preocupar com o código. Estes testes buscam identificar: erros de interface de usuário, erros de inicialização e término, funções incorretas ou ausentes; • Testes de desempenho: verificam aspectos relacionados à eficiência na realização de tarefas, e no consumo de recursos do dispositivo pelo aplicativo, tais como: desempenho sob tráfego pesado e carga de usuários, consumo de CPU, memória e armazenamento; • Testes de interrupção: testam o comportamento do app em resposta a ocorrência de eventos externos, tais como: bateria fraca, pouca memória, interrupções devido a chamadas ou SMS; • Testes de usabilidade: visam identificar elementos que possam aumentar a usabilidade do app. Como a usabilidade está associada à experiência do usuário, existem empresas que oferecem serviços para realização de testes com usuários humanos; • Testes de instalação: Tem como objetivo verificar se operações de instalação, atualização e desinstalação do aplicativo ocorrem de forma correta. Existem basicamente três abordagens utilizadas para realização de testes automatizados, dependendo das características do aplicativo, e do perfil da equipe que irá realizar os testes: • Codificação: Em algumas situações o código do app pode apresentar alguma função específica que demande a criação de um programa (codificação) para o seu teste; • Ferramentas com Scripts: Algumas ferramentas, apesar de realizarem os testes de forma automatizada, requerem a criação de scripts de entrada fornecendo parâmetros/passos para a testagem; • Ferramentas sem Scripts: Para este tipo de ferramenta, um conhecimento de codificação normalmente não é necessário para realização de testes, no entanto estas ferramentas normalmente fornecem algum nível de customização. Existem diversas empresas e plataformas que fornecem serviços ou softwares destinados à realização de testes automatizados, dentre elas: testIO, Kobiton, Cerberus Testing. Tipos de aplicativos para dispositivos móveis Vimos que existem diferentes abordagens possíveis para o desenvolvimento de aplicativos para dispositivos móveis. A escolha de uma ou de outra abordagem, pode implicar no uso de diferentes ferramentas de desenvolvimento, linguagens distintas, além de resultar em diferentes tipos de aplicativos, com características específicas, demandando custos, esforços de desenvolvimento e manutenção também distintos. Assim, cada abordagem terá suas especificidades, vantagens e desvantagens. Dependendo da abordagem utilizada podemos ter quatro tipos de aplicativos: aplicativos Nativos, aplicativos Híbridos, Web Apps e Progressive Web Apps (PWA). • Aplicativos Nativos: são desenvolvidos utilizando os recursos, o ambiente de desenvolvimento e a linguagem determinada pelo fabricante do sistema operacional do dispositivo móvel. Têm a vantagem de explorar todos os recursos oferecidos pelo sistema operacional do fabricante (APIs) e do dispositivo, podendo atingir um desempenho superior em relação às outras abordagens. No entanto, normalmente não são portáveis para outras plataformas, o que implica em maior custo de desenvolvimento e manutenção se houver necessidade de oferecimento em diferentes sistemas operacionais (e.g. Android e iOS); • Aplicativos Híbridos: híbridos buscam aliar os recursos de navegadores web a alguns recursos nativos do aparelho (o aplicativo é executado em um navegador web oculto). Podem utilizar diferentes ferramentas de desenvolvimento, tais como: Flutter, Ionic, React. Permitem o desenvolvimento utilizando diferentes linguagens, tais como: Dart, JavaScript,CSS, HTML. Possuem portabilidade entre diferentes sistemas operacionais (e.g. Android e iOS). No entanto, não terão acesso a alguns recursos nativos, assim poderão apresentar um desempenho e uma interface de usuário mais pobres em relação a um aplicativo nativo, dependendo da natureza da aplicação; • Web Apps: consiste em um site responsivo se comportando como um aplicativo. São dependentes do acesso à internet, além disso possuem acesso limitado a recursos do dispositivo. Em contrapartida, não ocupam espaço em memória, além de serem uma solução rápida e barata quando o objetivo é apenas ter presença mobile online; • PWA: São uma evolução dos Web Apps. São páginas web que utilizam as últimas tecnologias, que permitem acesso a alguns recursos do dispositivo. Assim é possível em muitas situações, oferecer funcionalidades antes só possíveis em apps Híbridos ou Nativos, tais como: Push Notification, ícone na tela, acesso à câmera e galerias do dispositivo, acesso a geolocalização etc. Java - Estruturas Básicas da Linguagem A linguagem Java é baseada fortemente no uso de classes e métodos e no conceito de objetos. Classes são arquivos que podem ser vistos como “uma receita” para a criação de um objeto. As classes definem atributos (variáveis de instância), e comportamentos (métodos) que o objeto irá possuir. Objetos só existem em tempo de execução, materializando uma entidade capaz de receber atributos e executar tarefas definidas pela sua classe. tipos Em Java variáveis podem ser do tipo primitivo (byte, char, short, int, long, float, double), ou tipo por referência, neste último caso a variável aponta para o objeto de alguma classe. modificadores de acesso Java possui modificadores de acesso a recursos, que definem o acesso a membros externos: • public: qualquer membro tem acesso; • protected: somente membros dentro do mesmo pacote têm acesso; • private: somente membros da própria classe têm acesso. métodos Executam alguma tarefa, possuindo um modificador de acesso. Podem receber uma lista de argumentos (variáveis) como entrada, e podem também retornar algum tipo como saída (como resultado de algum processamento por exemplo). construtores Os construtores são métodos que nos permitem inicializar os valores dos atributos (variáveis de instância) de um objeto no momento da sua criação. Os construtores recebem o mesmo nome da classe, e não possuem nenhum tipo de retorno. Estruturas condicionais Duas estruturas condicionais bastante utilizadas em Java, e também presentes em outras linguagens de programação, são as estruturas: "if/else if/else", e a estrutura "switch/case". if/else if/else: esta estrutura poderá analisar sequencialmente diferentes expressões booleanas. Ao encontrar a primeira expressão booleana "verdadeira"(true) da sequência, o trecho correspondente de código será executado. Caso nenhuma expressão "verdadeira" seja encontrada, ainda é possível executar um trecho específico de código através do uso do "else". Conforme esquematizado abaixo. switch/case: Realiza o teste para valores de variáveis do tipo: int, String e EnumType. Quando o valor testado corresponde ao valor da variável, o trecho de código correspondente é executado. Caso nenhum valor corresponda ao valor da variável testada, ainda é possível executar um trecho específico de código através do uso do "default". Conforme esquematizado abaixo. laços de repetição De maneira similar às estruturas condicionais, os laços de repetição testarão uma expressão booleana. Porém nesse caso, a cada execução do laço, a expressão booleana será novamente testada, e enquanto a expressão permanecer verdadeira, o laço contendo um trecho de código será executado. Três estruturas de laço comumente utilizadas são: "while", "do while" e "for", mostradas abaixo. Obs. Note que no laço "do while" o teste é realizado ao final da execução do código interno ao laço estrutura try/catch/finally Esta estrutura é normalmente utilizada em trechos de código que podem lançar exceções em Java. Assim o trecho de código que pode lançar exceção, é colocado dentro do bloco "try". No caso de lançamento de exceção durante a execução do bloco "try", a mesma pode ser tratada pelo bloco "catch". O bloco "finally" ainda permite que recursos alocados no bloco "try" sejam devolvidos, mesmo com a ocorrência de um lançamento de exceção. Herança A ideia de herança está associada a características comuns que os descendentes carregam (herdam), porém possuindo suas próprias características individuais. Similarmente ao que ocorre no mundo real, na programação orientada a objetos, uma classe (chamada superclasse) define características comuns (atributos e comportamentos) que serão herdados pelas suas classes filhas (subclasses). Através do mecanismo de herança é possível: • que o código escrito em uma classe possa ser automaticamente aproveitado em outras classes; • que novas subclasses trabalhem sobre códigos bem definidos e testados em uma superclasse definida anteriormente; • trabalhar com polimorfismo através do uso de métodos sobrescritos nas classes filhas. Polimorfismo O Polimorfismo possibilita tratar “semelhantes” de uma mesma maneira, permitindo “programar no geral” ao invés de “programar no específico”. Através da sobrescrição de métodos em uma hierarquia de herança, ou ainda de métodos de uma interface (ou mais interfaces) implementada pela superclasse, e herdados por suas classes filhas. Interface Uma interface é basicamente um “contrato” que especifica um conjunto de ações (métodos abstratos) que uma classe que implementa a(s) interface(s) terá que possuir, porém sem especificar a maneira como o método será executado (métodos abstratos não possuem um corpo de instruções). Uma interface pode ainda definir constantes acessíveis aos objetos. Se uma superclasse implementar uma interface, então todas as subclasses obrigatoriamente herdam aquela interface, e precisarão implementar os métodos definidos na interface. Projetando utilizando a plataforma Android Studio Vimos que o site oficial do Google para a plataforma Android é o site developers (https://developer.android.com/). No site developers são encontrados diversas informações e recursos, tanto referente ao desenvolvimento de aplicativos (códigos, exemplos, tutoriais, documentação, ferramenta de desenvolvimento AndroidStudio para download,etc.), como referente a publicação e comercialização de aplicativos (guias, cases, GooglePlay, etc.). AndroidStudio Vimos que a ferramenta AndroidStudio é voltada a projeto, sendo que após o fornecimento de informações iniciais referentes ao projeto, a ferramenta irá criar uma estrutura inicial de diretórios e arquivos para o projeto. Além dos arquivos contendo os código em Java (ou Kotlin) do projeto. O AndroidStudio utiliza arquivos XML, como o arquivo Manifest.xml que contém parâmetros gerais do projeto, e também para definição de recursos de layout. Estes recursos encontram-se dentro de uma estrutura de diretórios abaixo da pasta "res" na estrutura do projeto. Assim abaixo da pasta "res" dependendo do recurso, ele se encontrará dentro de alguma das subpastas a seguir: • drawable: contém arquivos de imagens (como por exemplo para fazer o plano de fundo de uma tela); • layout: contém arquivos XML de layout que definem layouts da(s) tela(s) do aplicativo; • mipmap: contém arquivos especificamente para ícones de aplicações de diferentes tipos de densidade; • values: contém arquivos XML que definem valores de recursos, como por exemplo textos (strings), dimensões e cores. Dentro dessa pasta o nome do arquivo XML corresponde ao tipo e recurso. Por exemplo: ➢ string. xml para strings; ➢ dimens.xml para dimensões; ➢ colors.xml para cores; ➢ styles.xml para estilos. Obs. dependendo da estrutura e dos recursos utilizados porum determinado projeto, pastas adicionais poderão ser criadas. Views, Widgets e Gerenciadores de Layout Para criarmos layouts de tela de um aplicativo na plataforma Android Studio, utilizamos basicamente dois tipos de elementos, os widgets que correspondem aos componentes que normalmente encontramos em uma tela de aplicativo, tais como: caixas de texto, botões, barras de progresso, imagens, listas etc.; e as classes de layout que são classes que gerenciam a apresentação destes elementos dentro do layout. O editor de Layout da ferramenta AndroidStudio, fornece vários atributos que permitem manipular as propriedades dos elementos internos de um layout (e.g posição, dimensão, cor) ou ainda do próprio layout. Dois atributos comumente utilizados para o dimensionamento do layout e de componentes internos do layout são: controle de altura: android:Layout_height e controle de largura: android:layout_width. Podendo assumir valores quantitativos ou ainda qualitativos em referência a outros elementos ou ao seu conteúdo interno, conforme abaixo: • numero (dp): especifica o valor em densidade de pixels; • match_parent: “ocupe todo o espaço do layout pai” – significa que o componente deve “esticar” e ocupar toda a área disponível naquela dimensão do layout no qual ele está inserido; • wrap_content: “utilize apenas o seu espaço padrão na tela” – significa que o componente ocupará o seu tamanho mínimo necessário para acomodar seu conteúdo interno. Alguns exemplos de atributos utilizados para posicionamento são: • gravity-> Permite posicionar o conteúdo interno de um componente ou o conteúdo interno do layout de acordo com a orientação da referência de gravidade informada; • layout_weight-> permite utilizar uma distribuição de pesos para as áreas internas do layout utilizadas por cada componente interno. Layouts As classes de Layout possuem regras para gerenciamento e posicionamento de componentes dentro de um layout. Abaixo alguns exemplos. • TableLayout: gerencia a disposição dos componentes de uma janela através de uma disposição que agrupa as exibições em linhas e colunas. Esse tipo de layout é bastante utilizado na criação de telas de login e formulários; • RelativeLayout: permite organizar os componentes internos de maneira relativa uns em relação aos outros ou em relação ao Layout; • ConstraintLayout: permite criar layouts grandes e complexos. É semelhante a classe RelativeLayout, onde os elementos são dispostos de acordo com as posições relativas entre widgets e o layout. Classe Activity Em Java, uma Activity corresponde a uma classe responsável por tratar eventos gerados por uma tela de um aplicativo. Assim, podemos associar a palavra "Activity" à idéia de "Tela". As Activities possuem um ciclo de vida, em que à medida que a Activity passa por diferentes estados, métodos são evocados pelo sistema operacional (callbacks). O diagrama abaixo ilustra as diferentes etapas do ciclo de vida de uma Activity, associadas aos callbacks. Classe Intent Em Java, uma Intent corresponde a uma classe que representa uma "ação" que a aplicação deseja executar. Na prática, a Intent será enviada ao sistema operacional em um mecanismo de broadcast, e dependendo do seu conteúdo, pode ser interceptada por qualquer aplicação. Intents podem ser explícitas ou implícitas: • Intent explícita: A classe para a qual a Intent se destina é declarada de forma explícita na Intent; • Intent implícita: Somente o mnemônico da ação é declarado na Intent. Neste caso qualquer componente que aceite a ação, poderá processar a solicitação da Intent. Para que uma classe possa responder a uma Intent implícita, esta deverá possuir um "Intent Filter" declarado no arquivo AndroidManisfest contendo o mnemônico da correspondente ação. Classe R A classe R é responsável por fazer a ligação entre os recursos localizados no diretório res, e o código da aplicação. Essa classe é gerada automaticamente no momento em que o build do projeto é executado. Para cada tipo de recurso há uma subclasse R, e para cada recurso daquele tipo há um número inteiro estático. Esse número inteiro é o ID do recurso e pode ser usado para acessá-lo. No entanto, a referência no código para o programador, pode ser feita utilizando-se a letra "R" seguida do tipo de recurso, que coincide com o nome da pasta, e o nome do recurso (sem extensão). Assim por exemplo para acessarmos o recurso de layout de uma tela (arquivo activity_main.xml). No código, teríamos a seguinte identificação: R.layout.activity_main Threads Threads consistem em linhas de execução dentro de um aplicativo. Por padrão todos os componentes de um aplicativo são executados na mesma linha de execução (thread principal). No entanto, há situações em que a criação de linhas de execução paralelas (threads secundárias) é importante. Em especial, em situações em que o aplicativo pode ter parte do seu código realizando algum processamento pesado, ou demorado, é interessante colocar este processamento em uma linha paralela, pois como a interface de usuário (UI) é sempre executada na thread principal, uma demora no processamento poderia tornar lenta ou ainda "travar" a interface de usuário. Além disso, o sistema Android reage a aplicativos que não respondem à entrada do usuário por um determinado período, exibindo uma caixa de diálogo ANR (Application Not Responding). AsyncTask Uma maneira de criar uma linha de execução secundária para o processamento pesado, ou em que não se saiba previamente o tempo que será gasto na execução, é através do uso da classe AsyncTask. A classe AsyncTask permite a criação de uma thread secundária (paralela) para realizar um processamento em segundo plano. Assim, a classe AsyncTask possui métodos que serão herdados por uma classe filha (normalmente escrita como uma classe interna de uma Activity), e que poderão ser sobrescritos para execução da tarefa de interesse em segundo plano. Estes métodos são: • onPreExecute(): Método executado na thread da interface de usuário antes que a tarefa em segundo plano seja executada; • doInBackground(): Método executado na thread secundária em background imediatamente após a execução do método onPreExecute(). Responsável por realizar a parte pesada do processamento; • onProgressUpdate(): Método executado na thread da interface de usuário. Usado para exibir o progresso do processamento (o progresso é informado em background dentro do método doInBackground() através da chamada do método publishProgress(); • onPostExecute(): Método executado na thread da interface de usuário. O resultado do processamento em background é passado para este método como parâmetro. Obs. Na prática, somente o método doInBackground() tem sua implementação obrigatória de forma explícita na classe filha (método abstrato). Na criação de uma subclasse de uma AsyncTask três argumentos genéricos, que definem os tipos que serão utilizados pelos métodos internos, são informados: • Params: define o tipo genérico da lista de argumentos que são passados para a execução da tarefa; • Progress: define o tipo genérico utilizado para receber um valor, que representa o progresso da execução da tarefa; • Result: define tipo genérico de retorno do método doInBackground() interno à AsyncTask. Extraindo informações de conteúdos XML A linguagem Extensible Markup Language (XML) é muito utilizada para codificação de documentos em um formato legível por máquinas. A interface XmlPulParser oferece um conjunto de métodos que permitem analisar e extrair conteúdos XML de forma eficiente. Um conteúdo XML é composto por "tags" e campos de conteúdo que podem ser identificados pelos métodos da interface, para extração de informações de interesse. A figura abaixo mostra um exemplo de um conteúdo XML com a identificação dos seus campos/tags, e utilização dos métodosgetName() e getText() que permitem a identificação de tags, e a extração do conteúdo correspondente. Além disso, durante a análise de um conteúdo XML, o método next() permite avançar a analise evento a evento dentro do conteúdo XML, e o método getEventType() é capaz de determinar qual foi o evento encontrado. Classe HttpUrlConnection A classe HttpURLConnection pode ser usada para enviar e receber dados pela internet na forma de streaming, cujo comprimento não é conhecido antecipadamente. Para fazer download de dados da internet, basicamente dois passos são necessário: • Abertura de um conexão utilizando o método openConnection(); • Obtenção do conteúdo utilizando o método getInputStream(). A classe HttpUrlConnection também disponibiliza diversos métodos que podem ser utilizados para parametrização e obtenção de informações durante o processo de conexão e download, tais como: • setConnectTimeout(tempo): Define o tempo máximo em milissegundos para aguardar o estabelecimento da conexão; • setReadTimeout(tempo): Define o tempo máximo em milissegundos para aguardar a conclusão de um download antes de abortar a conexão; • getResponseCode: Retorna o código de resposta retornado pelo servidor HTTP remoto. Banco de Dados Um banco de dados pode ser visto como uma coleção de dados que podem ser armazenados em um computador ou dispositivo (e.g. contatos, receitas, músicas etc.). Para criação de bancos de dados para aplicativos Android, o Google disponibiliza a API android.database.sqlite para SQLite. O SQLite pode ser visto como uma versão free do SQL, para utilização em ambientes em que os recursos de memória são limitados, como dispositivos móveis. Para a criação de um banco de dados utilizando a API, é necessário criar uma classe filha da classe SQLiteOpenHelper. O banco de dados é formado por tabelas, que se constituem de coleções de dados correlacionados. As tabelas são formadas por campos, que podem ser vistos como as unidades básicas de armazenamento de algum tipo de dado, sendo ainda que um conjunto de dados relacionados em uma tabela é denominado registro, ou linha. A declaração de tabelas para criação do banco de dados é realizada dentro do método onCreate(). Esse método é evocado quando o banco de dados é criado pela primeira vez. A criação de uma tabela normalmente é realizada através do uso do método execSQL (statement). Onde o "statement" consiste em uma String que define os parâmetros da tabela (colunas e tipos de dados). Uma vez criado o banco de dados, a interação com ele pode ser realizada através da utilização do método getWritableDatabase(). Esse método retorna um objeto do tipo SQLiteDatabase, que representa a conexão com o banco de dados. Com a utilização desse objeto dentro de um método definido pelo desenvolvedor, é então possível fazer diversas manipulações. Uma vez finalizadas as manipulações, fecha-se então a conexão com o banco de dados através do método close(). Abaixo temos um exemplo dos possíveis métodos que podem ser utilizados para interação/manipulação de dados em uma tabela no banco de dados. Normalmente estes métodos estarão dentro de uma estrutura try/finally, pois como se trata da abertura de conexão com um banco de dados, a ocorrência de algum evento (lançamento de exceção) que impeça o fechamento da conexão, pode corromper o banco de dados. Assim, o uso da estrutura try/ finally garante que a conexão será fechada ao final da transação, através do método close() dentro do bloco finally. public void meuMetodo(){ SQLiteDatabase db = getWritableDatabase(); //abre a conexão… try{ db.insert(...); // inserir dados db.update(...); //atualizar dados db.delete(…); //apagar um registro db.query(…); //consulta de registros db.execSQL(“sql aqui”); //executar comando SQL (“SQL STATEMENT”) } finally{ db.close(); }} //fecha a conexão Obs. O método query que permite a consulta de campos/registros de uma tabela do banco de dados, retorna um objeto da classe Cursor. Este objeto contém os campos/registros especificados na lista de argumentos do método query. A classe Cursor disponibiliza diversos métodos que permitem navegar pelo conteúdo retornado por este objeto. Assim é possível acessar por exemplo no objeto retornado, um campo específico de interesse. Aqui terminamos o nosso material de revisão, lembre-se que este material não deve ser utilizado como única fonte de estudos, e que o estudo dos materiais-base/textos-base são de fundamental importância para que você possa ter um bom aproveitamento nas avaliações.