Novas direções para o desenvolvimento de uma plataforma já familiar - é sempre interessante. Por um lado, você está expandindo a base de clientes; por outro lado, não está investindo na criação de software do zero, mas usando desenvolvimentos existentes. Mas se a direção for realmente nova, com suas próprias especificidades, não será possível gerenciar com muito pouco sangue. Na próxima reunião da comunidade Mosdroid em nosso escritório, o desenvolvedor Arthur Vasilov
Arturka falou sobre a adaptação do aplicativo Yandex ao sistema Android Go.
Em média, se você não escrever uma calculadora, um despertador, etc., ou será muito legal, bem-sucedido e fez tudo bem, ou seu aplicativo terá de 150 a 170 megabytes.
- Meu nome é Arthur, sou desenvolvedor Android, estou trabalhando no aplicativo Yandex. Hoje vou compartilhar com vocês uma história sobre como nos adaptamos ao Android Go. Vou lhe dizer que tipo de rake encontramos, o que não deu certo para nós e como tudo funciona, por que é necessário.
Uma pequena digressão sobre o que se trata. O Android Go é uma versão especial do Android projetada para dispositivos de baixo custo. Eles custam de 60 a 100 dólares e, portanto, são muito fracos, lentos, mais lentos. Então, o Google decidiu criar um sistema próprio para que, pelo menos de alguma forma, funcionasse normalmente. Foi anunciado no Google I / O em 2017, ou seja, um ano e vários meses se passaram. Portanto, quando o mitap foi anunciado, uma questão lógica foi levantada: "Você ainda está vivo, ou o quê?" Eu então disse que está tudo bem, tudo está bem, eu direi. E agora, como um herói típico da Internet, responderei ex post por que isso aconteceu.

O que exatamente aconteceu? O Google disse: "Estamos criando esse sistema". Então ele disse: "Ok, precisamos de tempo para finalizar" e tudo mais. Depois disso, os fornecedores sempre têm algum tipo de atraso na adaptação dessa versão para si mesmos. E a nova versão conosco já foi lançada não antes de um ano depois, então não há nada de surpreendente aqui. Além disso, eles precisavam decidir se deveriam ou não fazer isso: estão falando de dispositivos baratos e não está claro se eles lucram com eles ou não. Além disso, este dispositivo deve ser novo, deve ser feito, aprender a vender, entender como ele funcionará.
O primeiro smartphone com Android Go apareceu há não muito tempo. Em algum lugar de abril, as vendas provavelmente começaram, ou talvez em maio. Este é o Nokia 1, é vendido em qualquer lugar. Eu estou deitado por aqui. Agora, na minha opinião, existem apenas nove desses smartphones no mercado, mas até o final do ano eles prometem mais de cem. E, em princípio, nenhum dos principais players, como Huawei, Samsung e outros, disse sua palavra, então eles adicionarão outra coisa, não serão capazes de ficar longe de um mercado tão grande.
Antes do relatório, fui à página do Android Go e vi que eles criaram o Android Pie Go Edition. Mas eles não fizeram nada lá, simplesmente reduziram o número de aplicativos instalados e seu peso antecipadamente. Eles disseram: - "Agora você tem o dobro de espaço livre." E as desculpas padrão: correção de bugs, melhoria de desempenho, tudo. Mas pelo menos eles ligaram, o que significa que não esqueceram.
Quais são as limitações desses dispositivos, especificamente? Em primeiro lugar, eles têm 512 megabytes ou 1 gigabyte de RAM, 8 ou 16 gigabytes de armazenamento. É claro que nessas condições elas são extremamente inibidas e todas as aplicações normais nelas funcionarão aproximadamente da mesma maneira. Para que os aplicativos funcionem com o mínimo de adequação, o Google disse: "Vamos apresentar os seguintes requisitos". Eles são bastante lógicos, seguem o que estava no slide anterior.

Antes de tudo, é um bom desempenho abstrato. Seu aplicativo deve executar bem e rapidamente nesse dispositivo. Nós somos: “Ótimo. Nós estamos trabalhando.
Além disso, já existem números específicos aos quais devemos corresponder. O espaço ocupado após descompactar e instalar o APK não passa de 40 megabytes. Às vezes, isso é um problema, porque alguém e o APK pesam todos os 80 megabytes. Vai doer. Além disso, isso não pode ser tomado e medido adequadamente. Ou seja, você não pode dizer: "Eu sei que meu APK pesa tanto; portanto, após a instalação, o aplicativo levará muito". Tudo isso depende muito do fornecedor, da versão do dispositivo, do Android, etc. Mas se o seu APK demorar 10 megabytes, então, em princípio, está tudo bem e você nunca excederá esse número.
E agora o requisito mais divertido e interessante: a RAM consumida ao trabalhar com o aplicativo não deve exceder 50 megabytes.
Quem sabe quanta RAM o aplicativo dele leva em média durante a operação? Quem já se perguntou sobre esse assunto? Existe alguém com menos de 100 megabytes? Bonito. Mas talvez você esteja mentindo. Em geral, em média, se você não escrever uma calculadora, um despertador e assim por diante, ou será muito legal, bem-sucedido e fez tudo bem, ou seu aplicativo terá 150-170 megabytes. Colocá-lo em 50 megabytes é muito difícil. Portanto, o resto do tempo falaremos sobre isso, discutiremos como colocar o globo em uma coruja etc.

O que inclui nossa conversa sobre memória? É diretamente necessário entender o que exatamente estamos medindo e qual é a melhor maneira de mensurá-lo. Também para dispositivos Android Go, há uma especificidade que precisa ser levada em consideração, e também falaremos sobre isso. E também vou lhe contar algumas coisas gerais, dicas gerais sobre as quais você talvez não tenha adivinhado, mas elas podem realmente comer muita memória de você.
Em 2018, após a E / S do Google, você precisará iniciar a história sobre memória com uma referência a
este relatório . Quem assistiu?
Ótimo. Todas as 180 pessoas restantes sabem o que fazer no futuro próximo. Na minha opinião, este é um dos melhores relatórios de E / S do Google. Cara disse coisas incrivelmente legais. Ele contou tudo nas prateleiras, bem, e com muitos detalhes profundos. Quem assistiu e se lembrou bem, provavelmente notará que eu copiei algumas coisas a partir daí, porque, caso contrário, é impossível, ele contou tudo, então repetirei.
O que medimos? Havia uma coisa chamada PSS (tamanho proporcional do conjunto). Ou seja, a RAM no Android é representada por cerca de 40 kilobytes e esses blocos podem pertencer inteiramente ao aplicativo ou remexer entre processos e aplicativos.
E a pergunta é: como exatamente para entender a qual aplicativo relacionar essa memória compartilhada? Existem várias abordagens, elas são bastante lógicas. O PSS diz que, se a memória estiver atrapalhando entre N processos, assumiremos que seu aplicativo possui 1 / N dessa memória. E exatamente da mesma maneira, há o Tamanho do conjunto residencial e o Tamanho do conjunto exclusivo, que dizem que "Nenhuma memória compartilhada pertence a mim" e "Tudo pertence". Em princípio, o PSS é o mais lógico aqui.
Como exatamente você pode medir a memória consumida? Tudo é simples aqui. Ou é um criador de perfil no Android Studio ou é dumpsys. Existem, é claro, outras ferramentas. Eles podem fornecer resultados mais detalhados, algo mais complicado, mas o problema é que, para entender seus resultados, usá-los, tudo isso é muito, muito difícil. Muitas vezes, você precisa criar uma raiz ou uma versão personalizada do Android. E, em geral, você não precisa delas, as duas primeiras ferramentas são suficientes.

Não vou falar sobre o criador de perfil no Android Studio, acho que muitas pessoas o usaram. Quem não usou, não deixe de cutucar. Em particular, forneci o link abaixo - apenas um bom artigo da documentação com vídeo, como usá-lo, com demos. E, em princípio, tudo está claro. Mostra para onde vai a sua memória, mostra em tempo real. A única coisa a lembrar é que, no entanto, impõe certos erros que surgem do fato de medirmos constantemente essa memória. Mas eles estão dentro de limites aceitáveis.

Dumpsys é uma coisa simples de console que não requer nada de você, apenas um telefone conectado e um adb. E você pode executar este comando: chame dumpsys meminfo, passe o pacote para ele e ele retornará algo assim para você. E se estivermos interessados em quanto nosso aplicativo consome, podemos analisar especificamente o TOTAL, que diz que "seu aplicativo consome cerca de 168 megabytes". Muito, mas o que fazer?

Também mostra uma análise exata da quantidade de memória necessária nessa memória consumida. Existem várias seções aqui, elas são complexas, falaremos mais sobre elas, mas por enquanto podemos notar o principal - estas são o Java Heap, nossos objetos Java e tudo o mais é mais complicado.
O que mais é importante? A memória é uma coisa muito sensível a todos os tipos de testes e todos os tipos de condições externas. Ou seja, todos os testes que você deve executar o máximo possível nas mesmas condições. É claro que esse ideal deve ser um dispositivo, porque a memória depende da versão do Android. Basta recordar as diferenças entre os quatro e os cinco. Depende do tamanho ou da resolução da tela, porque quanto maior o tamanho da tela, mais conteúdo entra, mais memória você precisa para desenhar tudo. Quanto maior a resolução, mais pixels o seu bitmap ocupa e mais memória é necessária para armazená-los.
O cenário do aplicativo também afeta os testes. Você pode ler o texto ou rolar pela galeria com várias fotos. E está claro onde haverá mais memória.
Outra coisa importante é a carga no dispositivo. Ou seja, você pode ter tudo a mesma coisa, mas, em um caso, seu aplicativo é o único que funciona para você e, no outro, você tem vários aplicativos que fazem algo em segundo plano, baixam algo, excluem, trabalham em primeiro plano e, ao mesmo tempo, sua memória é simplesmente comprimida, porque você precisa entregá-la a outros aplicativos. Portanto, idealmente, é melhor pegar e matar primeiro todos os outros aplicativos que funcionam, não os seus. Tudo o que você pode alcançar e depois matar. Nesse caso, o PSS definitivamente agradecerá, porque não haverá necessidade de atrapalhar a memória entre os processos.

Você pode, por exemplo, obter e ver as informações atuais na memória livre, na memória ocupada. Ele lhe trará algo como um sinal que diz: "Aqui eu tenho muita memória livre, muita memória em cache, muita memória ocupada". E se você tiver entre 200 e 250 megabytes de memória livre para o seu amado, isso é bom, provavelmente, nada afetará seus testes.
Talvez alguém agora tenha a pergunta "Por que preciso de tudo isso?" Este é um disjuntor em que vou dizer adicionalmente a motivação para tudo isso.
Em primeiro lugar, mesmo que você não faça nada com o Android Go agora e pense que ele está morto, ele pode se desenvolver, chegar até você e, em algum momento, você terá que lidar com tudo isso.
A segunda coisa que considero muito importante é que você pode simplesmente fazer testes de regressão a partir da memória. Ou seja, você pode simplesmente escrever um script que execute o aplicativo, faça dumpsys, faça essas medições e observe como esses indicadores mudam entre os lançamentos. Esse script pode ser escrito em algumas horas, a infraestrutura pode ser configurada por mais tempo, mas parece-me que isso é uma coisa boa.
Se falarmos sobre as especificidades do Android Go - nosso terceiro ponto na luta contra a memória -, há boas notícias. Primeiro, ninguém realmente exige que você siga essas restrições. Ou seja, você pode usar o aplicativo como ele é, colocá-lo no dispositivo com Android Go, e está tudo bem. O problema é que é muito provável que o usuário o remova porque você está ocupando muito espaço. Além disso, seu aplicativo pode ser executado lentamente e ter bastante memória, sim. Mas até agora ninguém o proibiu, porque, caso contrário, não haveria outro aplicativo além dos aplicativos do Google no Android Go. Porém, se isso continuar se desenvolvendo, muitos se adaptarão a essas condições e, no final, seu aplicativo poderá simplesmente ser baixado na emissão do Android Go, ou você poderá mostrar Alertar como o usuário instala o aplicativo no smartphone Android Go. : "Cara, o aplicativo não funciona bem com o Android Go. Talvez você não coloque?
Há outro ponto: você pode excluir manualmente os dispositivos Android Go do Google Play, ou seja, dizer que o aplicativo não pode ser instalado nos dispositivos Android Go. Apareceu há não muito tempo.
E o Google também é inteligente o suficiente, e os 50 megabytes que soavam no título do relatório não são um número fixo, dependem da resolução do dispositivo, do tamanho da tela e, além disso, do tipo de aplicativo. Por exemplo, os jogos são alocados mais, na minha opinião, 115 megabytes. Em princípio, isso é compreensível.

E se falarmos diretamente sobre esse teste? Há mais um ponto, que em particular nos preocupa muito - trabalhar com predefinições. Quando os fabricantes criam um telefone novo, geralmente colocam algum conjunto de aplicativos pré-instalados. Em particular, estamos muito envolvidos nisso, e o problema é que eles executam coisas como o Compatibility Test Suite. Estes são os testes do Google, eles os executam. E aí, se o seu aplicativo não corresponder a esses 50 megabytes, tudo estará ruim e o aplicativo não poderá ser pré-instalado em um dispositivo desse tipo.
Infelizmente, os testes que o Google faz não são de código aberto, não sei dizer, eles estão sob o NDA, mas bons desenvolvedores do Google escreveram um artigo sobre o Android Go e, em princípio, existem recomendações que são boas o suficiente
Ou seja, tudo é banal. Iniciamos o aplicativo. Aguardamos 5 segundos para carregar tudo. Fazemos dumpsys, escrevemos o valor TOTAL, executamos várias vezes, obtemos o resultado. Tudo é muito simples e comum.

A única coisa é que eles não levaram em consideração um recurso tão pequeno em seu artigo ou, talvez, não falaram sobre isso - existe algo como trabalhar em outro processo, e geralmente o fazem para combater o consumo de memória.
Quem acredita que isso é bom para o Android Go? E quem acha que isso é ruim? Bravamente.

O problema é que, sim, isso é ruim, porque no final, a memória consumida do aplicativo é contada em todos os processos. Se fizermos um processo vazio sem nada e fizermos dumpsys desse processo em particular, veremos que são necessários 7 megabytes. 5 a 8 megabytes - isso é uma sobrecarga desde a criação do processo. Portanto, quando lutamos por cada megabyte para compactar tudo em 50, isso nos é muito grave. Em particular, digamos que o Yandex tenha a biblioteca Yandex.Metrica mais popular, ela também funciona em um processo diferente, e isso também pode nos causar dor.

Portanto, se algumas bibliotecas externas vierem até você, por exemplo, você pode simplesmente dizer: “Cara, por favor, trabalhe no processo principal. Concordo que isso pode ser mais lento, mas não consome memória desnecessária. ” Portanto, este também é um ponto sutil.

Se falarmos sobre o consumo de memória, vamos para esta placa, que está lá. Nós pegamos um projeto vazio, executamos esse dumpsys, iniciamos esse negócio e vemos que 23 megabytes de 50 já estão ocupados. Vazio "Olá, mundo!" sem nada, basta ativar com o texto. Está ficando muito triste. Fica ainda mais triste com a percepção de que podemos influenciar diretamente um parâmetro como Java Heap, ou seja, esses são diretamente nossos objetos Java que podemos rastrear explicitamente, que podemos excluir, reduzir e, pelo menos, de alguma forma interagir.
E é difícil interagir normalmente com tudo isso, porque esse é qualquer código de estrutura e, diretamente do Java, você simplesmente não possui ferramentas normais para entender como tudo isso é usado. Mas a boa notícia é que podemos influenciar essa coisa toda indiretamente, então vamos falar sobre o que está lá.

O que é o Java Heap é compreensível. O que é o Native Heap também é bastante lógico de se assumir. Essas são as mesmas alocações, apenas positivas. Eles vêm da estrutura e de suas bibliotecas nativas, arquivos .so e muito mais.
O código está diretamente relacionado ao armazenamento de código. Esse é o tamanho do seu .dex, esse é o seu. Então, esses são os recursos, os arquivos mmap e tudo mais. Ou seja, quanto menos código, melhor. A verdade mais simples que funciona em geral sobre tudo.
Stack é uma pilha de encadeamentos Java / C ++. Ou seja, cada thread possui sua própria pilha de chamadas, portanto, cada thread cria uma área de memória específica para armazenar tudo isso.
Gráficos é uma renderização da interface do usuário. Existem bitmaps parcialmente armazenados que são desenhados e o que está conectado a ele.
Outro privado, Sistema - isso é algo que não podemos influenciar e, de fato, tudo o mais que não é muito categorizável.

Se falamos de bibliotecas nativas, então, digamos que você pode pegar um aplicativo vazio ... você pode pegar o aplicativo habitual que temos e tirar dumpsys dele, veja que são necessários 146 megabytes. E se você cortar algo ... em particular, eu peguei e vi as duas maiores bibliotecas nativas, que temos um total de 15 megabytes, e usamos dumpsys depois disso, você pode ver facilmente que perdemos o consumo do Native Heap e do código. Ou seja, com um gesto tão simples, economizamos cerca de 35 megabytes. Não é ruim o suficiente.

Streams. Vamos fazer o teste mais fácil. Há um aplicativo vazio, e existe o mesmo aplicativo vazio, onde pegamos e fazemos um loop que fará o novo Thread (), durma nele por cinco segundos e inicie esse thread. Você pode ver que, nesse caso, a pilha é muito reabastecida. Ou seja, podemos influenciar tudo isso, mas indiretamente, reduzindo o número de encadeamentos no código Java. Ou seja, por meio de objetos Java, incluindo a influência de todos esses locais que estão em outros elementos.

Se você continuar falando sobre threads, poderá ver facilmente o que possui para threads, o que eles fazem no aplicativo. Existem ferramentas diferentes. Você pode usar o mesmo systrace, basta usar o console para encontrar o ID do seu processo e obter ps de acordo com quais threads estão no sistema.
Se você se sair bem e usar todos os tipos de ThreadFactory para nomear seus threads, poderá entender o que deveria ter, o que não deveria ser e, assim, reduzir tudo, porque ter 100 threads no aplicativo é especialmente sem sentido.
O que mais pode ser feito? Há um conjunto bem conhecido de dicas de sanfona: observe vazamentos, use piscinas, não crie objetos quando você não precisar, e toda essa bobagem, tudo isso se aplica. Ótimo.
Existe uma boa correlação entre quanto seu aplicativo consome memória e qual o tamanho. Ou seja, quanto maior o seu aplicativo, mais memória ele consumirá e, de maneira simples, reduza o peso do APK, reduza o peso de .dex, reduza .so, remova tudo o que puder ser removido.
. , , , . , ? — — , . , , . . — .

dumpsys, , , . , , View, WebView, Assets, .

, , , , , SharedPreference SQLite - , , , .

, , Assets. , , – . 1,5 . -, , . .

— WebView. , WebView, , dumpsys, 100 , . , , - , , 300 — . , WebView , . -.

Google . . WebView, Google, - . WebView. .

Google Go, Android Go-. , - layout , . , , , Chrome Tabs, Chrome . .
Android Go, ? , Android Go, .

Existem várias maneiras. -, , , Android Go . , , . , , , - build , - , , - . APK, , — uses-feature «low-memory», APK.
, , Android Go. Google. , , Go- .
, ? , , - , : «, - . ». . , , , , , - , , - . , , , , Google, Google , . , , , Android Go , , .
, , , -. .

, Google I/O: , - . , , , , , - , . , « , . ». . , . , .
? , . — , , 98% . , , , . . - Android Go-. , YouTube Go . YouTube , , , . Eu não sei , Android Go , , , — . — Facebook Lite, Twitter Lite, . Lite, - . -, , . Facebook, . , , . , — , Android Go.
?
Stack Overflow, 1000 . . , , , . , , — dumpsys.
, Android , 512 , Android 4.4.
API , .
, . , . — , .
, : « ». : «». . — , . - 170 . . - . ? , , , , - . - — . 105 . .

. build- -. densitySplit, , resConfig, . , , — . ProGuard . , ProGuard , , , , , stacktraces.
. , , Android Go- .
- 64 . : «, ». 14 , 4 , 60 . , . . , . — , , , , . , , , Android Go, . 10 , APK , , . , , .
Portanto, a melhor solução é a segunda aplicação. No entanto, poucas pessoas gastarão recursos nele, enquanto o lucro real não é claro. Talvez sua história não seja tão triste, porque eu tinha um pouco de esforço, teria escalado, mas já era insuportável. Mas que história. Nesta nota relativamente positiva, você provavelmente pode terminar. Obrigado a todos.