AS: 3.5.3; Plug-in Android Gradle: 3.5.0; Gradle: 5.6.2;
Observamos um aumento drástico no número de métodos mencionados em nosso aplicativo após dividir o módulo 'app' em vários pequenos módulos. Mas o estranho é que a adição de métodos referenciados por cada classe é menor que o total mencionado no Android Apk Analyzer Tool.
Para fins de teste, mudei o WebActivity.class do módulo 'app' para o módulo 'adaptators' e a contagem de métodos referenciados aumentou em 181 métodos.
Para resumir:
app / WebActivity = 63546 Métodos reais referenciados, mas mostrando 65394 métodos. adapter / WebActivity = 63543 Métodos reais referenciados, mas mostrando 65575 métodos.
Temos observado 'contagem método referenciado' aumentou quase 10k após a adição / divisão 4 novos módulos.
Qual é o problema exato?
Como a modularização de aplicativos pode aumentar drasticamente a contagem de métodos referenciados?
A seguir, estão as capturas de tela que tirei de duas diferenças diferentes de apenas APKs: o WebActivity foi movido do módulo 'app' para o módulo 'adapter' e aumentaram os 181 métodos referenciados:
Movido a WebActivity para o módulo 'adaptador'
Nas capturas de tela, por que a adição de métodos referenciados por cada classe (marcada em vermelho) não é igual ao total fornecido no Apk Analyzer?
fonte
Respostas:
Estou lendo sobre o desempenho do código e os parâmetros de ajuste há muito tempo. Na verdade, os programas Android são um dos meus focos.
Vamos apresentar primeiro os conceitos básicos ou mais importantes nos quais nos ajudam a alcançar uma solução.
Como o desenvolvedor do Android declarou
Portanto, os módulos têm seu próprio Gradle & Dependencies . E você pode explorá-lo no projeto
Hierarchy Viewer
.De fato, a ênfase da modularização em manutenção é importante. Ao contrário do Performance Matters, a modularização tem esse impacto importante:
Aqui está um diagrama que eu plotei para deixar claro. Como você pode ver, ao usar o módulo discreto, para invocar o Método A, ele é
2N micro secs
comparado com oN micro secs
módulo discreto.Esta questão me veio à sua mente que os métodos referenciados contam o que se refere à profundidade da herança?
A resposta é: Embora o uso da modularização aumente os Métodos referenciados, na verdade, ele não afeta o desempenho do aplicativo e o principal problema possível é Profundidade de herança, na qual na maioria dos casos é ignorável .
Eu enfatizo que o aumento de métodos referenciados na modularização é devido a cada módulo Gradle & Dependencies
Condições em que o analisador de impacto APK é importante Métodos referenciados
Além da declaração oficial acima, quero adicionar outra condição na qual o analisador de impacto APK é:
quanto o desenvolvedor tem experiência em modularização?
a modularização é como uma casa que a arquitetura (desenvolvedor) define onde deve ser a cozinha e onde deve ser o banheiro e onde deve ser o banheiro. E se a arquitetura decidir combinar WC e cozinha? Sim, isso é um desastre.
Isso pode acontecer durante a modularização se o desenvolvedor não tiver muita experiência.
Respondendo às perguntas do OP, além de informações adicionais
Aqui eu respondo às perguntas mais frequentes nos comentários
Como os módulos podem ser construídos, testados e depurados, DEVEM ter o seu próprio Gradle & Dependencies.
Enquanto o projeto de vários módulos estiver sendo cumprido, o compilador gera vários
.dex
arquivos, incluindo:.dex
arquivo para dependências totalmente integradas.dex
s.dex
arquivo de dependências é uma integração de todos os módulos gradlesVejamos como um gradle de módulo afeta a contagem final de Mothods referenciados ?!
existem 2
APK
s com o mesmo resultado, mas a diferença na contagem de métodos referenciados.Ambas são atividades vazias com
1.7k
diferença na Contagem de Métodos Referenciados muito alta, dependendo de sua funcionalidade. A principal diferença está no Gradle de seu módulo, um deles foi configurado paraOutro configurado para
Embora sejam apenas atividades vazias, uma diferença mínima em Gradle causou
1.7k
diferença nas contagens de métodos referenciados.E App Gradle é
Este é apenas o filtro IDE, nada mais. com certeza, se você selecionar apenas um
.dex
arquivo Contagens de método de referência é igual a SOMA de cada linha Contagens de métodos referenciados, mas se selecionar vários.dex
arquivos, verá uma diferença em SUM e na contagem real devido à igualdade nas referências que o Analyzer preferiu filtrá-los.nas capturas de tela, você selecionou vários
.dex
arquivos e, em seguida, o Analyzer filtra a igualdade.Teoricamente, NÃO deve aumentar a contagem de métodos referenciados. MAS , como expliquei, a Experiência do desenvolvedor afeta fortemente o resultado final.
O Team Analyzer deve verificar e corrigir problemas de desempenho antes do lançamento, como
Agora, quero esclarecer como a Experiência do desenvolvedor e a manutenção do código afetam o resultado final. MESMO se o seu APK usar dependências centralizadas
no exemplo acima, eu aumentei a
5.1k
contagem de métodos referenciados, mesmo que eu tivesse dependências centralizadas !!!!!Como é possível ?
A resposta é: acabei de adicionar um
.jar
arquivo inútil e oculto nolibs
diretório do projeto. tão fácil quanto você pode ver, eu afetei o resultado final.Como você pode ver Desenvolvedor Experiência afeta result.as finais resultado, Praticamente é possível que métodos referenciados contagens de ser aumentado Embora Teoricamente Should NÃO .
compilação não tem nenhuma relação com os métodos referenciados count.it está de acordo com o que o desenvolvedor deseja cumprir.
Conclusão
Eu cobri todas as possibilidades em torno da questão. De fato, pode surgir de diferentes situações e um desenvolvedor, usando essa diretriz, pode corrigir o problema.
NOTA IMPORTANTE: quase todas as declarações são de minha investigação e pesquisa. de fato, pode haver erros e falhas e será atualizado para adicionar muito mais informações no futuro.
fonte
Respondendo à minha própria pergunta, a solução acabou de aparecer em minha mente, embora isso não seja tentado, mas funcionaria, definitivamente ou muito provavelmente. :) A resposta dada por Mr.AF foi muito útil para chegar a uma solução final. Ele fala sobre o porquê? mas não como evitá-lo ou como melhorar isso.
Aqui está uma maneira de recuperar a contagem de métodos referenciados original / real -
Não depende de como modularizamos o aplicativo, mas de como adicionamos dependências. Se adicionarmos uma dependência usando ' implementação ', essa dependência permanecerá privada no módulo e nenhum outro módulo poderá usá-lo. E se adicionarmos a mesma dependência usando ' api ' (igual a 'compilação' obsoleta), ela se tornará pública e outros módulos dependentes poderão usá-la. Como estamos usando 'implementação' para adicionar dependências em cada módulo em um projeto de vários módulos, cada módulo possui todas as dependências necessárias como independentes, e é por isso que ele pode ser compilado individualmente. Isso resulta em menor tempo de compilação / compilação, pois apenas módulos modificados podem ser compilados. Mas, o uso de 'implementação' aumenta a contagem de métodos referenciados pois existem muitos métodos referenciados duplicados.
Portanto, se o tempo de construção não é da sua conta, mas a contagem de métodos referenciados é possível, você pode desenhar a árvore de dependências de todos os módulos e evitar adicionar dependência duplicada usando 'api' no módulo base. Dessa forma, mesmo o módulo superior pode usar a dependência adicionada pelo módulo base, o que evitará duplicatas. Lembre-se de que isso aumentaria o tempo de construção.
Podemos alcançar ambos se pudermos distinguir dependências para depuração e versão de compilação . Adicione todas as dependências usando 'implementação' para compilação de depuração e adicione apenas dependências necessárias e otimizadas para compilação de versão usando 'api' . Dessa forma, a compilação de depuração será mais rápida e a compilação de versão será mais lenta e acessível.
Nota: Eu atualizaria esta resposta assim que descobrir como fornecer dependências separadas para depuração e versão de compilação.
fonte
Eu vejo toda a diferença no seu pacote 'com'. Você pode expandir e comparar quais classes exatas foram reduzidas. Se você criar com o R8 mais recente, poderá remover algum código por padrão. Quando você coloca algumas classes no encolhedor de módulos, não sabe se as classes / métodos públicos podem ser removidos ou devem permanecer para uso em outro módulo.
fonte