BT

Disseminando conhecimento e inovação em desenvolvimento de software corporativo.

Contribuir

Tópicos

Escolha a região

Início Artigos Escalando aplicações Android: lições aprendidas

Escalando aplicações Android: lições aprendidas

No último AnDevCon, Doug Bateman, diretor de treinamentos da NewCircle, moderou um painel focado no que é preciso para construir aplicativos Android que escalam até milhões de usuários globais. Isso inclui gerenciamento de equipe, testes e design para testabilidade, funcionalidade de suporte ao gerenciamento de lançamentos, contribuições de código aberto, arquiteturas alternativas e mais.

O evento foi organizado pelo NewCircle Training e reuniu os seguintes especialistas para compartilhar ideias: Howard Harte da Cyanogen, Jake Wharton da Square, Ty Smith do equipe da Fabric do Twitter, Juan Gomez da Eventbrite, Mike Hines da Amazon, Larry Schiefer da HiQES e Dave Smith da Possible Mobile.

Como gerenciar equipes responsáveis por uma grande quantidade de funcionalidades?

Ty Smith descreve rapidamente como o equipe da Fabric do Twitter foi originalmente de uma equipe de 15 pessoas à uma equipe de 60 pessoas responsáveis por várias funcionalidades, após o Twitter adquirir a Crashlytics. De qualquer maneira a organização permaneceu a mesma, com base na criação de pequenas equipes ao redor de funcionalidades individuais e, em seguida, certificando-se de que essas equipes se comunicam ao menos uma vez na semana. Juan Gomez destacou a importância dos testes automatizados e outros processos para assegurar que as contribuições dos membros das novas equipes não quebram nada.

Como é feita a experimentação antes do lançamento de novas funcionalidades para bases de usuários em massa?

De acordo com Mike Hines, não é necessário enviar um conjunto de alterações para todos os usuários de uma única vez. É possível enviar as alterações para um pequeno grupo de usuários. A Amazon usa um framework interno que permite fazer testes A/B para descobrir quais funcionalidades falham, dessa forma é possível decidir o que enviar para todos os usuários. Ty Smith, por outro lado, ressalta que fazer testes A/B não é uma boa opção quando desenvolve um SDK, uma vez que os desenvolvedores esperam algum tipo de estabilidade e não gostariam que os novos recursos fossem adicionados e removidos após algum tempo. Assim, nesse caso, tudo se resume ao feedback dos desenvolvedores e ao trabalho em conjunto com desenvolvedores, grupos de discussão, entre outros.

Quais são as estratégias para testes? Que ferramentas são usadas?

No caso de Howard Harte, sendo o CyanogenMod suportado por mais de cem dispositivos, os testes dependem fortemente de pessoas usando isso em seus dispositivos e enviando relatórios com feedback. Jack Wharton explica que na Square três tipos distintos de testes são usados: testes unitários (milhares) que são aplicados antes de comitar ao repositório principal, testes de instrumentação mais lentos que executam de forma assíncrona para exercer diversos fluxos do aplicativo e finalmente testes manuais. Curiosamente, os desenvolvedores na Square tentam usar o aplicativo para simular o processo de pagamento para todos os cafés, almoços, etc. Juan ressalta novamente a importância de testes automatizados, embora também conte com uma equipe dedicada aos testes. A equipe de testes costuma ter o Robotium como ferramenta, mas estão migrando para o Espresso.

Respondendo a questão da audiência, Jake Wharton forneceu sua visão sobre o Robotium dizendo que ele é implementado como um wrapper ao redor da instrumentação básica da API do Android, e portanto, não resolve as questões básicas quando tem que se testar operações assíncronas. Não é necessário, por exemplo, realizar um novo teste até se ter certeza que todas as tarefas relacionadas ao teste anterior tenham terminado. O Espresso por outro lado, assume uma nova abordagem que permite realizar um novo teste apenas quando o ciclo de eventos principal está limpo de todas as mensagens. Além disso, diz Jake Wharton, se uma biblioteca que usa a rede estiver sendo usada, é possível dizer algo como: não execute novos testes até que não exista mais atividade de rede. O Espresso também tem uma API bastante declarativa que lhe permite escrever testes de alto nível.

Ty Smith diz que na Fabric estão migrando do JUnit para o Robolectric. O Robolectric fornece um caminho mais rápido para testar código que não requer integração pesada com frameworks Android. Nos locais que é necessário classes do Android, o Robolectric faz um bom trabalho criando classes sombra para interagir com contexts e activities, e assim por diante. O Robolectric permite que os testes executem mais rápido devido ao fato de serem executados na VM local e isso é extremamente importante desde que a equipe do Fabric executa os testes unitários a cada commit dentro do servidor de integração. Do lado do design das coisas, Ty Smith explica seu esforço para arquitetar o código de modo que é altamente testável, basicamente seguindo o princípio da responsabilidade única, e criando classes falses (mock), tais como as classes de comunicação de rede, para testar tudo isoladamente.

Jake Wharton interrompe novamente para dizer que sua equipe também usa o Robolectric em casos que algum código tem que interagir com um bundle, intent ou algumas UI views. Nestes casos, a prática usual é encapsular esse código dentro de uma interface, para que ele possa ser testado com JUnit. O Robolectric, no entanto, faz com que seja possível chamar esse código diretamente através de classes de sombra. Jake Wharton prossegue, estar em contato com o Robolectric e ajudou a reduzir o número de classes de sombra em uma versão futura do Robolectric, com o objetivo de usar o máximo possível de código real Android. O principal benefício disso é que os testes ficam muito próximos do comportamento real no dispositivo Android. Finalmente, Jake Wharton observa como as pessoas sempre pensam no Robolectric como uma forma de executar todos os testes na JVM, devido a velocidade, mas o Robolectric não é realmente para isso. Para Jake Wharton, a grande vantagem é que o Robolectric fornece uma rede de segurança e mais alguns pedaços de código, assim o desenvolvedor pode facilmente executar o código de alguma superclasse Android.

Como tem sido projetada o aplicativo para ser testavél?

Idealmente, diz Juan Gomez, a ideia é projetar as coisas de maneira que se possa automatizar os testes com a ajuda de algum mecanismo de mocking. Existem padrões e bibliotecas que podem ser usadas para desacoplar o código e torná-lo mais testável. Na Eventbrite é usado um framework próprio para mocking e injeção de dependência, e estão de olho no Mockito também. Juan Gomez diz que as vezes não é assim tão fácil de obter uma unidade limpa para testar quando há interações com o framework Android, mas existem maneiras de tornar esse processo menos doloroso.

Sendo o Fabric um SDK, continua Ty Smith, não é possível usar o padrão de injeção de dependência, basicamente devido a intenção de ser tão leve quanto possível, que torna indesejável o uso de uma bela ferramenta de injeção de dependência como o Dagger. O que os desenvolvedores da Fabric fazem quando existem interações com o fragments e activities do Android é tentar desacoplar as regras de negócio das activities, de modo que o primeiro possa ser testado isoladamente. De acordo com Ty Smith, é desejável ter as Activities fora dos testes tanto quanto possível, e isso é o que é feito ligando as activities a suas dependências através de um singleton controller.

Finalmente, Jake Wharton oferece uma visão um pouco diferente, observando que o design para a testabilidade é importante, mas também há um equilíbrio entre as abstrações que são usadas para testes, os mocks, e o objetivo final que é a entrega da aplicação. Então o que se quer fazer é resolver as coisas de uma maneira simples. O que se quer é abstrair, ter uma separação limpa, mas as vezes jogamos o código, entregamos e se sobrar um tempo voltamos e melhoramos. Logo o design para a testabilidade pode ser visto como um processo incremental.

E sobre os testes em níveis embarcados?

Larry Schiefer diz que, quando se trabalha em níveis embarcados, com drivers a nível do kernel, ou HAL, não estão disponíveis os frameworks ou padrões disponíveis na JVM. Em sua empresa tentam usar os mesmos princípios modulares para construir drivers ou bibliotecas e abstrai-los em componentes que podem ser extraídos em um framework proprietário. Para os drivers, eles os deixam no espaço do kernel e contam com uma série de testes de aplicação neste espaço, para saber se os drivers que são confiáveis dentro do espaço do kernel.

Quais abordagens alternativas de design estão sendo usadas?

Jake Wharton relata como entraram na onda de Fragments para depois gerenciar as próprias interfaces de usuário, mas descobriram que tentaram ser muitas coisas para muitas pessoas, como em não ser o suficiente "opinativos" sobre como fazer as coisas, e sendo complexo e cheio de bugs. Eles finalmente removeram isso, quando entenderam que na verdade estavam abusando do sistema tentando ter uma única activity segurando uma série de fragments. Isso levou o sistema ao limite, então decidiram implementar o próprio código para gerenciar views. Reforçando que fragments não são nada mais que uma maneira de gerenciar views e animá-las. Isso permitiu que os engenheiros da Square simplificassem o código e vissem a taxa de crash caindo a cada nova versão, basicamente agradecendo por terem abandonado os fragments. Fragmentos talvez sejam mais apropriados quando se lida com apenas alguns deles a cada vez, diz Jake Wharton.

Alguém está usando o estilo reativo de programação ou reactive Java para suas aplicações?

Novamente Jake Wharton toma a frente e expressa sua experiência com o RxJava. Sucintamente, o problema é que o RxJava é um framework, não uma biblioteca, o que significa que é necessário bastante trabalho para integrar a API em toda a aplicação e quase nunca queremos isso dentro das activities, views, services, porque isso é simplesmente muito, diz Jake Wharton. Na Square se usa helpers internos e também o RxAndroid, que faz parte do mesmo pacote como o RxJava. O RxAndroid vai tornar isso mais fácil para conectar os modelos observáveis assíncronos do RxJava para o mundo Android.

Como lidar com Android em escala, quando temos uma base de clientes em todo o mundo?

Mike Hines dá sua opinião sobre a importância da localização e internacionalização para fornecer suporte corretamente para a audiência global. Isso se resume a estar preparado para coisas como o suporte a escrita da direita para a esquerda, ou línguas como o Alemão que podem ter palavras extremamente longas que são capazes de derrubar qualquer interface de usuário, etc. Também é importante abstrair as coisas e usar arquivos de recursos. Um lado interessante no suporte a uma grande base de usuários vem da interação entre o suporte as pessoas e engenheiros, diz Mike Hines. Suportar pessoas frequentemente pode vir como histórias de usuário interessantes para as funcionalidades que foram construídas, mas com o aumento em escala, também será sugerido formas de utilizar os recursos que nunca foram pretendidos. Às vezes, porém, essas novas histórias são realmente boas!

Para Ty Smith, quando suportando uma base de usuários global, o dispositivo e a fragmentação do OS se tornam um fator importante, porque é desejado que o SDK suporte o máximo de dispositivos. Portanto é importante ser capaz de degradar de forma incremental os recursos e também executar com o mínimo de recursos, o que é especialmente relevante para mercados emergentes. Juan Gomez reforça o mesmo conceito explicando que sempre se certifica de executar a app em baixa resolução ou em dispositivos lentos porque isso é o que muitos usuários fora dos Estados Unidos vão ter. Além disso, muitas vezes, diz Howard Harte, os dispositivos fora daqui não tem muita memória também.

Podem nos dizer como suas organizações se envolvem com a comunidade open source?

Na Amazon, diz Mike Haynes, existe um grupo responsável por lidar com contribuições open source e também para retribuir a comunidade open source. Existe um processo no qual os engenheiros enviam o que eles gostariam de contribuir para os advogados da Amazon para que seja possível verificar qualquer envolvimento propriedade intelectual. Este é um negócio muito complicado, diz Mike Haynes, por isso não deixe engenheiros serem advogados!

Jake Wharton fornece uma visão um pouco diferente: na Square, o processo é inteiramente guiado pelo engenheiro. Eles também têm um tipo de licença de revisão, mas ninguém está dizendo: "Hey, isso parece legal, você deve abrir esse código". A Square não tem um processo formal, além do uso de revisão em pares para avaliar um código candidato para ser aberto, e finalmente, se for considerado apropriado, então é liberado. A relação entre a Square e a comunidade open source é forte, ambos dão a Square várias contribuições. Jake Wharton cita como eles contrataram pessoas graças a suas requisições pull.

O Cyanogen também tem uma grande relação com a comunidade open source, diz Howard Harte, com aproximadamente 9.000 pessoas que contribuíram da comunidade. Uma coisa legal sobre o open source é que é possível revisar para assegurar que o código é seguro e não abre brechas.

Que bibliotecas open source são consideradas indispensáveis?

Dave Smith explica que sua empresa não contribui muito para o open source, embora consuma muito disso. Claro que ele presta muita atenção a licença do código, logo existem casos que ele não se sente confortável com a licença e tem que reinventar o código. Dave Smith diz que usa fortemente algumas bibliotecas da Square, como Picasso, Retrofit, e Dagger.

No caso de Larry Schiefer, é muito importante fazer os clientes saberem sobre o possível uso de uma determinada biblioteca de código aberto, então eles entendem que implicações isso tem e fornecem a chance de decidirem o que é melhor.

Como análises ajudam na construção de aplicações melhores?

Ty Smith ressalta que há um grande número de diferentes análises. Por exemplo, os testes A/B que mencionamos anteriormente permitem tomar decisões importantes sobre as funcionalidades dos produtos. O Fabric é uma ferramenta de análise muito opinativa, diz Ty Smith, que não é tão flexível como o Google Analytics, mas dá informação suficiente para tomar decisões de alto nível. Por Exemplo, número de usuários, números de falhas, etc.

Para Jake Wharton, análises na aplicação são obviamente excelentes, mas para ele também é importante coletá-las para suporte. Ele explica que gravam a frequência de chamadas para cada funcionalidade, assim quando detectam uma taxa de chamada muito frequente para uma determinada funcionalidade, é possível melhora-la, melhorando assim a aplicação e suporte. Essa abordagem também ajuda o nível de suporte constante de acordo com o crescimento da base de usuários, sem a necessidade de contratar mais pessoas para o suporte.

Finalmente, Dave Smith apresenta seu ponto de vista, observando que as análises são extremamente importantes para seus clientes, basicamente porque as análises ajudam a conduzir as receitas e eles usam até sete pacotes de análise em algumas aplicações. É das análises que são extraídos os dados para basear tomar decisões sobre como será o andamento da aplicação.

Quais são os recursos favoritos para aprender Android?

A documentação do Android é fantástica, de acordo com Ty Smith, que também acredita que existem muitos livros bons disponíveis, um dos favoritos dele é "The Busy Coder's Guide to Android Development". Também abundantes são apresentações sobre vários temas que estão disponíveis on-line, diz Howard Harte.

Para Jake Wharton, é realmente difícil encontrar conteúdo de nível avançado muito bom. Existem muitas coisas boas para iniciantes, mas as vezes não é possível encontrar muita informação sobre novas partes do framework ou ir mais fundo nele. Então é difícil encontrar material quando se está no nível intermediário, para poder avançar mais.

Larry Schiefer, Mike Hines e Dave Smith concordam sobre a importância da orientação para fazer um novo desenvolvedor evoluir rapidamente. O que eles fazem em suas empresas é colocar os desenvolvedores seniors e juniors trabalhando em pares para que os juniors evoluam mais rapidamente.

Como podemos fazer nossos designers entenderem Android? Eles só parecem entender iOS...

Dave Smith tem uma receita bastante radical para isso, sugerindo que várias pessoas do departamento de design usem um smartphone Android por um período de tempo. Essa é a única maneira deles entenderem o modelo de interação além dos screenshots. Juan Gomez por outro lado, apresenta a importância dos desenvolvedores fazerem um esforço para fornecer a informação correta para os designers. Ele se lembra de um caso quando comprou algumas cópias do livro de design do Google e deu para seus designers.

Uma gravação completa do painel está disponível online.

Sobre o autor

Sergio de Simone é um desenvolver iOS independente e consultor. Sergio vem trabalhando como engenheiro de software há mais de quinze anos em diferentes projetos e empresas, incluindo ambientes de trabalho diferentes como a Siemens, HP e pequenas startups. Atualmente, seu foco está no desenvolvimento para plataformas móveis e tecnologias relacionadas.

Avalie esse artigo

Relevância
Estilo/Redação

Conteúdo educacional

BT