Geração Automática de Código Android Eficiente a partir de Modelos UML Abilio Gambim Parada, Aline Rodrigues Tonini, Lisane Brisolara de Brisolara Ciência da Computação, Grupo de Arquiteturas e Circuitos Integrados, Centro de Desenvolvimento Tecnológico, Universidade Federal de Pelotas, Brasil {agparada, artonini, lisane}@inf.ufpel.edu.br Resumo. Dispositivos móveis vêm substituindo computadores para uma série de aplicações. Um grande número destes aparelhos utilizam a plataforma Android da Google. Este crescimento na utilização de dispositivos móveis tem impulsionado o mercado de desenvolvimento de aplicações para estes dispositivos. Entretanto, devido ao curto tempo de lançamento do produto no mercado, abordagens que visam acelerar o desenvolvimento são necessárias. Para diminuir o tempo de desenvolvimento e ao mesmo tempo suportar projetos complexos, abordagens de engenharia baseada em modelos, ou MDE (ModeldrivenEngineering), estão sendo utilizadas. No entanto, os desenvolvedores devem se preocupar também em atender requisitos não funcionais relacionadas a desempenho e consumo de energia inerentes ao domínio. Neste contexto, a Google propôs um conjunto de boas práticas e técnicas de programação para aplicações Android, tendo como principal objetivo o desempenho das aplicações. Este artigo propõe uma abordagem MDE para geração automática de código, a qual aplica boas práticas Android, visando à geração de código eficiente. A abordagem é demonstrada através de um estudo de caso, no qual a melhoria obtida com as práticas adotadas pode ser observada. Palavras Chaves: Android, UML, boas práticas, desempenho, geração de código, MDE. 1 Introdução A crescente utilização de dispositivos móveis, como smartphones e tablets, tem se tornado uma alternativa à utilização de computadores de uso pessoal, impulsionado assim o mercado destes eletrônicos. Dentre as várias plataformas disponíveis no mercado surge a plataforma Android [1], como uma solução completa de código livre com um amplo suporte aos mais diversos dispositivos, bem como ferramentas de apoio ao desenvolvimento e sistema operacional. Aplicativos Android trazem novas características para a programação tanto no estilo quanto em peculiaridades que devem ser observadas. Uma destas características é a programação orientada a eventos, pois estes aplicativos devem constantemente reagir a interações do usuário [2], e também conceitos adicionais como ciclo de vida e a utilização de determinada estrutura de acordo com o comportamento da aplicação.Estas novas características aumentam a dificuldade do desenvolvimento de aplicativos Android. Além disso, desenvolvedores devem se preocupar também com a eficiência e um melhor aproveitamento dos recursos do dispositivo. Considerando estas particularidades e o fato de existir pessoas de vários lugares do mundo com maneiras diferentes de programar desenvolvendo aplicações para Android, a Google propõe o uso de “Boas Práticas” no processo de desenvolvimento [3], para assim viabilizar um melhor desempenho das aplicações Android. Além de todas as características de desenvolvimento e de boas práticas que devem ser consideradas, as aplicações Android estão fortemente ligadas ao mercado possuindo um curto tempo de desenvolvimento. Tradicionalmente, abordagens de Engenharia Dirigida por Modelos ou MDE (do inglês, Model Driven Engineering) vem sendo adotadas, principalmente por que oferecem abstração através do uso de modelos e automação através de transformação de modelos, facilitando e acelerando o desenvolvimento [4]. Segundo um estudo realizado na Motorola, a MDE pode reduzir em até 70% o tempo de produção de software [5]. Entretanto o uso efetivo do paradigma MDE no desenvolvimento Android, requer uma abordagem dedicada para a modelagem dos aplicativos e ferramentas capazes de transformar modelos UML em código Android. Para resolver este problema, em [6], foi proposta uma abordagem para modelagem e geração de código. Entretanto esta abordagem não aplica técnicas de otimização de código, dessa forma, este artigo estende esta abordagem para a geração de código Android eficiente através da aplicação das boas práticas propostas pela Google. Nossa abordagem é demonstrada e os resultados de desempenho são discutidos através de um estudo de caso. Este artigo está organizado da seguinte forma. A Seção 2 apresenta a fundamentação teórica, enquanto a Seção 3 apresenta e discute trabalhos relacionados. Na seção 4, a abordagem proposta para geração de código eficiente é detalhada e o estudo de caso que demonstra resultados de seu emprego é apresentado na Seção 5. As conclusões do trabalho são discutidas na Seção 6. 2 Boas práticas Android A Google sugere uma série de “Boas Práticas” para o desenvolvimento de aplicativos Android. Estas boas práticas são dicas simples de programação que aplicadas aos hábitos de codificação proporcionam um melhor desempenho geral da aplicação. Esta seção introduz estas boas práticas bem como destaca o seu impacto no desempenho, segundo o estudo realizado pela Google em [3]. Uma das boas práticas indicadas pela Google é evitar a criação de objetos desnecessários, pois a criação destes é sempre custosa. A alocação de objetos em excesso faz com que a coleta de lixo seja realizada periodicamente, o que tem um impacto negativo no desempenho da aplicação. Outra prática sugerida é preferir o uso de métodos estáticos ao invés de virtuais. Desta forma, métodos que não irão acessar campos do objeto devem ser declarados como estáticos. De acordo com o estudo da Google, invocações estáticas serão de 15% a 20 % mais rápidas. Neste conjunto de boas práticas, é recomendado o uso de static final para constantes, pois ao usar a palavra reservada final na definição de constantes os acessos serão mais rápidos. Isso se deve ao fato da classe não requerer o método <clinit>, visto que constantes são armazenadas em um campo do arquivo .dex responsável pela inicialização das constantes. Porém, esta recomendação é válida somente para tipos primitivos e Strings constantes. Em linguagens orientadas a objeto como C++ e Java é comum o uso de getter para acessar atributos ao invés de acessá-los diretamente. Porém esta não é uma prática recomendável para Android, pois as chamadas a métodos virtuais são muito mais caras do que o acesso direto ao campo. Desta forma, é recomendado que o uso de getters e setters seja evitado. De acordo com a Google, o tempo para acessar um atributo diretamente é três vezes mais rápido do que através de um getter sem o recurso de JIT (Just-in-time) e cerca de sete vezes mais rápido com o uso do JIT. A sintaxe do for aprimorado ou for-each pode ser usada para definir coleções que implementam uma interface iterativa para Arrays. Com as coleções é alocado um iterador que faz chamadas a hashNext e next. De acordo com a Google o uso da sintaxe aprimorada do for em Arrays é três vezes mais rápido (com ou sem o uso de JIT) comparado com o uso do for com iterador explícito. É possível iterar uma matriz de três maneiras, como mostram os trechos de código abaixo. A maneira como zero itera a matriz é mais lenta, pois o JIT não otimiza a maneira de obter o comprimento da matriz a cada iteração do laço. A iteração usada em one é mais rápida, pois utiliza variáveis locais e o comprimento da matriz oferece um beneficio de desempenho. A implementação da sintaxe aprimorada do for, introduzida no Java 1.5, realizada em two é a mais rápida em dispositivos sem JIT e indiferente de one para dispositivos com JIT. É possível iterar uma matriz de três maneiras, como mostra o trecho de código abaixo: Códigos com várias implementações de for static class Foo { intmSplat; } Foo[] mArray = ... public void zero(){ int sum = 0; for (int i = 0; i<mArray.length; sum + = mArray[i].mSplat; } } ++i){ public void one(){ int sum = 0; Foo[] localArray = mArray; intlen = localArray.length; for (int i = 0; i<len; ++i){ sum + = localArray[i].mSplat; } } public void two(){ int sum = 0; for( Foo : a ){ sum + = a.mSplat; } } As boas práticas também indicam o uso de acesso do tipo pacote (package) ao invés do tipo privado (private) em classes internas privadas. Esta prática se aplica quando uma classe interna a outra (inner class) precisa acessar atributos da classe externa. A máquina virtual considera o acesso direto da classe interna a membros privados da classe externa como sendo ilegal, porque são classes diferentes. Para evitar esse problema atributos e métodos que devem ser acessados por classes internas devem ter visibilidade do tipo pacote, indicada pelo modificador public, protected ou sem nenhum modificador [7]. Ao aplicar a prática sugerida, evita-se uma sobrecarga em aplicações que utilizam classes internas em pontos críticos de desempenho. Outra boa prática é evitar o uso de Ponto Flutuante, pois de acordo com a Google, o seu uso em dispositivos Android é cerca de duas vezes mais lento do que o uso de inteiros. 3 Trabalhos Relacionados Muitos trabalhos preocupam-se com a eficiência de aplicações para dispositivos móveis [8][9][10]. Em [8] os autores discutem a sobrecarga no desempenho induzida pelo uso da abstração em camadas para software embarcado, usando como plataforma alvo o Android. Em [9], um conjunto de benchmarks foram implementados de diferentes formas no Android e avaliados quanto ao desempenho. Os resultados mostraram uma sobrecarga do Java-Android comparado a implementações C rodando na mesma plataforma. Da mesma forma, em [10] são realizados experimentos com diferentes implementações de algoritmos e são analisados resultados de desempenho e energia consumida pelas implementações quando executadas no Android. Porém, nenhum destes trabalhos considera as boas práticas. Apenas em [11] o impacto destas práticas no desempenho do software foi avaliado através de experimentos. Como este ainda é um campo de atuação novo, há um número bastante reduzido de ferramentas que proveem a geração automática de código para dispositivos Android a partir de modelos de alto nível de abstração. A IBM recentemente adicionou à ferramenta Rational Rhapsody [12] um perfil para aplicações Android. No entanto, sua abordagem exige que a aplicação seja definida em um nível baixo de detalhe para que a geração de código seja realizada. Além da IBM, observam-se esforços da Google e da Eclipse. A Google propôs o App Inventor [13] e a Eclipse, o AndroMate [14], ambas focam na modelagem gráfica e geração para Android. No entanto, tanto o AndroMate como o App Inventor poderiam ser classificados como programação visual ao invés de orientados a modelos. Ainda deve-se ressaltar que nenhuma destas abordagens considera boas práticas ou inclui passos de otimização no momento da geração de código. Nossa abordagem difere-se das abordagens utilizadas por estas ferramentas, pois procura minimizar os detalhes que devem ser inseridos pelo projetista no modelo e aplica boas práticas automaticamente durante a geração de código, suportando assim a geração de código eficiente para a plataforma Android. 4 Geração de Código Android Eficiente A geração automática de código Android eficiente proposta neste trabalho baseia-se na aplicação das boas práticas propostas pela Google para dispositivos Android. Assim como proposto em [6], nossa abordagem gera código Java-Android a partir de modelos UML construídos usando suas notações padrão, sendo esta transformação suportada por uma ferramenta em desenvolvimento pelo grupo. Durante a geração de código, a ferramenta aplica as boas práticas, visando a obtenção de código otimizado para a plataforma Android, evitando que o projetista tenha que refatorar o código para incluir estas otimizações manualmente. Estas otimizações são opcionais de forma que o usuário pode escolher quais otimizações serão aplicadas, para assim observar os impactos destas otimizações de forma isolada. A entrada da ferramenta de geração de código é um modelo UML, composto de diagramas de classe e de sequência, construídos de acordo com a abordagem apresentada em [6]. O diagrama de classe oferece a visão estrutural, a partir da qual código estrutural pode ser gerado. Já os diagramas de sequência são usados na geração de código comportamental. A Seção 4.1 apresenta a geração estrutural de código eficiente para a plataforma Android, enquanto a geração comportamental é detalhada na Seção 4.2. Atualmente, nossa ferramenta implementa três das boas práticas sugeridas pelo Google. Destas, uma afeta apenas a geração estrutural, outra apenas a geração comportamental e outra modifica ambas as gerações. 4.1 Geração Estrutural Na geração de código estrutural, são geradas definições de atributos (nome, tipo e visibilidade), de métodos (nome, parâmetros e visibilidade) e importação de pacotes. Duas das boas práticas são aplicadas na geração do código estrutural. A primeira delas se refere a geração dos atributos e se baseia na boa prática que sugere o uso dos modificadores static e static final para constantes. Quando um atributo tem um valor de inicialização, este é classificado como constante pela ferramenta. Neste caso, a ferramenta aplica a boa prática, gerando a declaração com o modificador mais apropriado. Se a constante for do tipo primitivo ou String, é usado o static final, caso contrário, apenas o modificador static é usado. Esta boa prática traz benefícios na velocidade de acesso a estas constantes, proporcionando assim um melhor desempenho para o sistema, como discutido na Seção 2. A segunda boa prática aplicada na geração refere-se à definição e geração de métodos de acesso a atributos, os métodos getters e setters. Na primeira versão da ferramenta, sem foco na otimização, para todo o atributo era gerado um método getter e um método setter, mesmo que estes métodos não estivessem explicitados no modelo da classe. No entanto, esta prática é contrária a uma das boas práticas do Google que propõe o acesso direto aos atributos sem métodos getters e setters como forma de melhorar o desempenho do código. A eliminação destes métodos pode requerer mudanças na visibilidade do atributo para permitir que o mesmo seja acessado diretamente, e também a eliminação da invocação do método de acesso. Desta forma, esta boa prática não afeta apenas a geração do código estrutural, mas também afeta a geração de código comportamental (discutida na Seção 4.2). Na geração estrutural, nossa ferramenta realiza a análise dos atributos e métodos de acesso descritos no modelo antes da geração propriamente dita do código. Caso seja identificado um atributo privado (private ou protect) para o qual métodos de acesso tenham sido definidos no modelo, a ferramenta irá gerar a definição do atributo como público (public) e não fará a definição dos métodos de acesso correspondentes. Para isto é necessário que o projetista siga a boa prática indicada para programação em geral, de utilizar nomes para métodos de acesso contendo o nome do atributo a ser acessado [15] com prefixo get ou set. 4.2 Geração Comportamental Na geração do código comportamental das aplicações Android, a aplicação da boa prática de eliminação de chamadas aos métodos getters e setters deve ser concluída. Para tal, a ferramenta deve analisar os diagramas de sequência para identificar onde são utilizados estes métodos de acesso, para posteriormente substituir a invocação do método por uma atribuição ou leitura do atributo. Neste trabalho, também propomos a aplicação da boa prática relativa à utilização da sintaxe do for apropriada, apresentada na Seção 2. Para aplicação desta boa prática, a ferramenta deve analisar os diagramas de sequência do modelo, com especial atenção naqueles onde um fragmento do tipo loop é usado, o qual representa uma iteração. A análise para determinar a melhor sintaxe do for considera o que está sendo utilizado dentro da estrutura de iteração.Caso seja iterado uma coleção de objetos é indicado pelas boas práticas a utilização da sintaxe for-each, enquanto que para a manipulação de um simples vetor é indicado a utilização do for-lenght. Desta forma, com base nas características do modelo, a ferramenta escolhe a melhor sintaxe de acordo com as boas práticas para o uso do for apresentadas na Seção 2. 5 Estudo de Caso Para demonstrar a nossa abordagem bem como os resultados obtidos pelo uso das boas práticas, esta seção apresenta um estudo de caso. Neste estudo, primeiramente, a aplicação Snake é modelada em UML, seguindo a nossa abordagem de modelagem proposta em [6] e realizando a engenharia reversa do código original da aplicação. Posteriormente, este modelo é usado como entrada para a ferramenta GenCode, a qual gera o código a aplicação. A aplicação escolhida está disponível no site de apoio ao desenvolvedor Android [16]. Apesar de ser uma aplicação simples, ela permite a demonstração dos principais aspectos da abordagem, bem como apontar as melhorias alcançadas com a aplicação das boas práticas. Neste estudo é demonstrada a geração de trechos de código da aplicação, focando nos pontos do código onde as práticas foram aplicadas. Primeiramente, será demonstrada a aplicação da eliminação de getters e setters, que conforme explicado na Seção 4, é realizada pelas duas rotinas de geração de código, estrutural e comportamental. Após, será demonstrada a aplicação da boa prática do for. Para facilitar a visualização das melhorias aplicadas pela geração, o código original será comparado com o código automaticamente gerado pela ferramenta. O código gerado inclui a aplicação de boas práticas (em separado) e a comparação entre estes dois códigos permite observar o impacto das otimizações. Além disso, análises de desempenho também foram realizadas, permitindo a comparação entre os códigos. A Figura 1 ilustra a visão estática da aplicação, representada pelo diagrama de classes. Nesta figura são destacadas as classes Activity, View e Handler, pertencentes ao Android. A partir das informações obtidas neste diagrama, o código estrutural foi gerado. Como a eliminação de getters e setters foi habilitada, a ferramenta realizou a análise de atributos e de seus métodos de acesso. Esta busca identificou o método setTextView da classe Snake, contexto onde a boa prática que evita getters e setters deveria ser aplicada. Abaixo, são apresentados os trechos do código original e do código gerado, após a captura e análise do diagrama. O código original define o atributo como privado (modificador private) e declara o método de acesso, bem como o corpo deste método. Já o código gerado automaticamente declara este atributo como público (usando o modificador public) e não faz a declaração do método setTextView. Fig. 1. Diagrama de classe, representação estrutural da aplicação Snake. Trecho de código original da aplicação Snake utilizando setter private TextView textView; public void setTextView(TextView textView) { this.textView = textView; } Trecho de código da aplicação Snake utilizando a prática que evita getters e setters public TextView textView; Para a eliminação do método setTextView, porém, a ferramenta realizou uma busca entre os diagramas de sequência a fim de identificar onde este método era invocado. Para então, substituir esta invocaçãopor uma atribuição. Sem a otimização, o código que seria gerado a partir do modelo comportamental, incluiria a invocação do método setTextView(), conforme trecho de código abaixo. Trecho de código original da classe SnakeView, invocação do método de acesso mSnakeView.setTextView(findViewById(R.id.text)); Enquanto que com a aplicação da boa prática, a rotina de geração do código comportamental faz a busca pela invocação do método a ser eliminado e substitui a sua chamada pelo acesso direto ao atributo, gerando o trecho de código abaixo. Trecho de código da classe SnakeView, utilizando a prática que evita getters e setters mSnakeView.textView = findViewById(R.id.text); Para a comparação da eficiência do código gerado pela nossa ferramenta com o código original do aplicativo, foi utilizada a ferramenta DDMS (Dalvik Debug Monitor Server) [17], que fornece resultados relativos ao tempo de execução de códigos Android. A DDMS gera CPU Include Time, o qual considera o tempo de execução do método analisado incluindo o tempo dos métodos chamados por este, e o CPU Exclude Time, que por sua vez, considera apenas o tempo de execução do método em análise. Todos os experimentos realizados e discutidos nesta seção foram repetidos 30 vezes, e a partir dos tempos de execução obtidos, uma média foi calculada, a qual é utilizada nas comparações realizadas. Os resultados obtidos pela análise de desempenho dos dois códigos são apresentados no gráfico ilustrado na Fig. 2, onde o eixo y representa o tempo da CPU em milissegundos (ms). Esta análise de desempenho considera o CPU Include Time fornecido pela DDMS, pois o custo da chamada do método de acesso deve ser contabilizado, neste caso. O tempo médio de execução do fragmento do código original (Fig. 2) foi de 0,8444 ms e o desvio padrão foi de 0,0276 ms, enquanto o tempo de execução do código gerado foi de 0,8030 ms e o desvio padrão de 0,30 ms. Foi utilizado o teste estatístico “t de student” para comparação de médias, sendo a diferença entre as médias considerada estatisticamente significativa. Neste gráfico, observa-se que o tempo de execução foi reduzido em 4,9029% pela aplicação da boa prática que evita o uso de getters e setters, o que demostra o impacto real da utilização desta boa prática. Incl CPU Time (ms) Comparação Com Setter - Sem Setter 0,88 0,86 0,84 0,82 0,8 0,78 0,76 0,74 0,72 Com Setter Sem Setter Fig. 2. Gráfico representando a diferença de desempenho na utilização de métodos de acesso. Neste estudo de caso, a aplicação da boa prática da escolha da sintaxe do for também é demonstrada. Esta boa prática é tratada apenas pela rotina de geração de código comportamental. Durante esta rotina, laços devem ser identificados nos diagramas de sequência. Para demonstrar sua aplicação é usada a representação de uma pequena parcela do modelo comportamental do Snake ilustrado na Figura 3. Este diagrama de sequência se refere ao detalhamento do método enqueueDirection proveniente da classe SnakeView. Neste diagrama pode-se observar o uso de um laço de iteração no qual o objeto mNextDirectionArray é iterado. O laço é representado pelo fragmento loop. Outro fragmento interno a este, do tipo opt, representa uma condicional, que restringe a invocação do método add(direction). Fig. 3. Diagrama de sequência do método enqueueDirection da classe SnakeView. Com base nas informações contidas neste diagrama, a ferramenta aplica a boa prática e determina qual a sintaxe apropriada para a implementação da manipulação do Array mNextDirectionArray. Neste caso, a ferramenta escolhe o uso do for-each, devido ao uso de um Array junto a um laço. Abaixo são apresentados os fragmentosreferente ao laço. No código original o for normal é usado, enquanto no código gerado pela ferramenta, o for-each é usado. Trecho de código original da aplicação Snake, utilizando a sintaxe normal do for private void enqueueDirection(int direction) { int c=mNextDirectionArray.size(); for (int i=0; i<c; i++) { if (mNextDirectionArray.get(i)==0) { mNextDirectionArray.add(i,direction); break; } } } Trecho de código gerado aplicando a boa prática do for-each private void enqueueDirection(int direction) { for (Integer c : mNextDirectionArray) { if (c.equals(0)) { mNextDirectionArray.add(direction); break; } } } Para demonstrar a melhoria em desempenho obtida pela aplicação desta otimização, foram realizados experimentos após a geração do código (considerando apenas esta otimização). Os resultados de desempenho do código original e código gerado são ilustrados no gráfico da Fig. 4. A análise de desempenho neste caso, considera o CPU Exclude Time fornecido pela DDMS, pois apenas o custo do laço deve ser contabilizado, não incluindo o custo da chamada do método addDirection(). Pode-se observar que o tempo médio de execução com o for normal (código original) foi de 59,0882 mscom desvio padrão de 1,5526 ms, enquanto o resultado utilizando o for-each (código gerado), foi de 12,4501ms, tendo o desvio padrão de 0,5249 ms. Valores médios de tempo de execução foram usados nestacomparação e a diferença entre as médias também foi considerada estatisticamente significativa. Excl CPu Time (ms) Comparação For Normal - For Each 70 60 50 40 30 20 10 0 For Normal For - Each Fig. 4. Desempenho obtido pelo for normal e pelo for-each 6 Conclusões Este artigo apresenta uma abordagem MDE para geração automática de código Android eficiente a partir de modelos UML. A geração de código aplica automaticamente boas práticas do Google, com o objetivo de melhorar o desempenho do código gerado. Esta geração foi prototipada em uma ferramenta de geração de código chamada GenCode [6]. A automatização destas otimizações evita que o projetista tenha de estudar as boas práticas e refatorar o código implementado para que este faça uso destas práticas e, portanto, tenha o desempenho melhorado. A abordagem é demonstrada com um estudo de caso, que também é usado para evidenciar as melhorias no desempenho obtidas com a geração de código proposta. Além da eficiência do código gerado, outros benefícios podem ser vinculados ao emprego desta abordagem, dentre estes destaca-se a abstração oferecida pelo uso de modelos UML e a automação provida pela ferramenta de geração. Além disso, a abordagem proposta utiliza notações padrão da UML, o que evita a necessidade do uso de uma ferramenta de modelagem específica. O uso do diagrama de sequência limita a geração de código comportamental proposta até o nível de chamada de métodos, que é o que pode ser expresso neste diagrama. Para obter código completo, outros diagramas precisam ser considerados na geração de código. Atualmente, nossa ferramenta implementa três das boas práticas sugeridas pelo Google. Como trabalhos futuros, pretendemos analisar a viabilidade de estender esta abordagem para outras boas práticas, priorizando aquelas que apresentam maior impacto no desempenho. Referências 1.Google. (2012) Fundamentos de uma aplicação Android. Disponível em: http://developer.android.com/guide/components/fundamentals.html. Acesso em: Dezembro, 2012. 2.Kraemer, F. A. et al., “Engineering android applications based on UML activities”, Proceedings of the 14th international conference on Model driven engineering languages and systems (MODELS’11), Jon Whittle, Tony Clark, and Thomas Khne (Eds.). SpringerVerlag, Berlin, Heidelberg, pp. 183–197, 2011. 3.Google. (2012) Boas práticas para performance. Disponível em: http://developer.android.com/training/best-performance.html. Acesso em: Dezembro, 2012. 4.Selic, B. “Models, software models, and UML”, UML for real: Design of embedded real time systems, vol. Boston: Kluwer Academic Publishers, pp. 1–16, 2003. 5.Weigert, T. “Practical experiences in using model-driven engineering to develop trustworthy,” Computing Systems. IEEE International Conference on Sensor Networks, Ubiquitous, and Trustworthy Computing, vol. 1 (SUTC’06), 2011. 6.Parada, A., Brisolara, L.: A model driven approach for Android application development. SBESC, Brazilian Symposium on Computing System Engineering, Natal, 2012. 7.Oracle. (2012) Controlling Access to Members of a Class. http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html. Dezembro, 2012. Disponível Acesso em: em: 8.Camara, V. B., Corrêa, U. B. Performance Overhead from the Usage of Software Abstraction on Complex Embedded Systems. SBESC, Brazilian Symposium on Computing System Engineering, Florianópolis, 2011. 9.Batyuk, L., et al. (2009) “Developing and Benchmarking Native Linux Applications on Android” in Mobile Wireless Middleware, Operating Systems, and Applications. 2009. 10.Vieira et al. Análise de desempenho e consumo energético para aplicações embarcadas na Plataforma Android. SBESC, Brazilian Symposiumon Computing System Engineering, Natal, 2012. 11.Beckmann, M. Avaliação das Boas Práticas de Codificação para Plataforma Android. Trabalho de conclusão de curso. UFPel. 12.IBM. (2012) Rational Rhapsody. Disponível http://www.ibm.com/software/awdtools/rhapsody/. Acesso em: Dezembro, 2012. em: 13.MIT. (2012) App Inventor. Disponível em: http://appinventor.mit.edu/. Acesso em: Dezembro, 2012. 14.Telematica Instituut. (2012) The android modeller and code generator. Disponível em: http://www.lab.telin.nl/_msteen/andromate/. Acesso em: Dezembro, 2012. 15.Martin, R..: Clean Code: A hand book of Agile Software Craftsmanship, , Pearson, Boston, (2009). 16.Google. (2012) Exemplos de Aplicações Android http://developer.android.com/tools/samples/index.html. Acesso em: Dezembro, 2012. em: 17.Google. (2012) Using DDMS. Disponível em: http://developer.android.com/tools/debugging/ddms.html. Acesso em: Dezembro, 2012