Upgrade to Pro — share decks privately, control downloads, hide ads and more …

androidperformance.pdf

 androidperformance.pdf

Performance, por que não começar agora? Slides da apresentação feita no Android dev Conference 2017 sobre otimizações de performance em apps Android

Paula Rosa

August 25, 2017
Tweet

More Decks by Paula Rosa

Other Decks in Programming

Transcript

  1. Seu app está ruim e a culpa é sua Otimizações

    de Performance em aplicações android @_paulacr
  2. Um pouco de teoria… 30 frames por segundo convincente sensação

    de movimento 60 frames por segundo Transições suaves (smooth transitions)
  3. Um pouco de teoria… 16ms 16ms 16ms Calculando: 1000ms 60

    frames =16.666ms/frame Em 16ms: • Computação • Desenhar componentes na tela • Atualização de views na tela • Animações • Tempo para o GC recolher objetos
  4. GPU Profiling tool cuidado: acima linha verde = animações sofrem

    pausa Tempo upload Bitmap na GPU atualizando/enviando display list gpu ++ , CPU aguardando measure/layout - hierarquia++ Desenho - métodos desenho sobrecarregado animações - usar outra thread entre frames - usar outra thread 16ms
  5. • Numero de vezes que um pixel é redesenhado (a

    cada frame) • Algumas vezes colocamos background sem precisar • O desenho excessivo (em situações que poderiam ser evitadas) é o overdraw Overdraw
  6. Nome Loren ipsun loren loren ipsun loren favoritar compartilhar Nom

    Loren ipsun loren loren ipsun loren favoritar compartilhar Nome Loren ipsun loren loren ipsun loren favoritar compartilhar Como você vê seu app Como Android vê seu app
  7. Como corrigir overdraw <style> <item name=“android:windowBackground”>…</item> </style> Escolha um tema

    para o background default da aplicação Dica: crie um tema que estender do tema padrão para outras telas (com background diferente)
  8. Como corrigir o overdraw Sem background 
 no layout main

    Sem background 
 no item • Passo 1: Removendo background layout pai • Passo 2: removendo background layout item android:background="@color/white">
  9. Mais dicas • Verificar se o componente precisa de um

    layout extra • Customizar temas da aplicação • Reduzir layouts com transparência (The hidden cost of transparency) 
 https://www.youtube.com/watch?v=wIy8g8yNhNk • Desenhar somente o que está visível para o usuário. Ex: customviews (Udacity) • ConstraintLayout
 https://android-developers.googleblog.com/2017/08/understanding- performance-benefits-of.html
  10. Garbage Collector Garbage Collector Objetos Memória • Gerenciamento de memória

    automático (automatic memory management) • Desenvolvedor não tem controle de quando GC passa
  11. Object Lifecycle Object Object Object Activity Lifecycle LEAK Memory leak

    (vazamento de memória) • Uma porção de memória que não é liberada • Está referenciada por outra instancia/objeto • A referência impede a memória de ser liberada • Todos os itens que estão ancorados à activity também sofrem leaks (adapters, views, etc)
  12. Como um leak surge (não é do além) Device rotacionado

    • A activity é destruída • Outra activity é criada • Se tiver leaks na activity destruída, ela não é coletada • Parabéns: você ganhou uma activity de brinde :)
  13. Como um leak surge (não é do além) • Toda

    vez que a configuração muda, a activity é recriada • Se houver um leak a activity não será desalocada da memória android:configChanges= ["mcc", "mnc", "locale","touchscreen", "keyboard", "keyboardHidden","navigation", "screenLayout", "fontScale","uiMode", "orientation", "screenSize","smallestScreenSize"]
  14. Leak 1 - Contexto estático public class MainActivity extends AppCompatActivity

    { private static Activity activity; @Override protected void onCreate(Bundle onSavedInstance) activity = this; } }
  15. Leak 1 - Solução • Pra que usar contexto estático?

    (se pergunte pelo menos 10 vezes) • Recomendado: não utilizar o contexto estático • Utilizar o contexto da aplicação • Banco de Dados, Singleton, etc • Inicialização libs (Fabric, Crashlytics, facebook)
  16. Inner classes (não estáticas) e classes anônimas • Facilitam a

    implementação • Permitem melhor organização do código • Mas podem trazem um problema: Referência implícita
  17. Leak 2 - Referenciar contexto (direta ou indiretamente) em chamadas

    assíncronas class MainActivity extends AppCompatActivity { ImageView imageView; private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> { ... @Override protected void onPostExecute(Bitmap result) { imageView.setImageBitmap(result); } } } Leak Threads, Callbacks, AsyncTask Leak
  18. @Override protected void onCreate(Bundle savedInstanceState) { ... new Timer().schedule(new TimerTask()

    { @Override public void run() { image.setImageResource(R.drawable.imagem); } }, LONG_TIME); } Leak 3 - Referenciar views em classes anônimas que tem tempo de vida maior Leak Cuidado com Handlers
  19. Solução 1 - Listener private static class DownloadImageTask extends AsyncTask<

    , , > { private Listener listener; interface Listener { void onSuccess(Bitmap bitmap); } public void setListener(Listener listener) { this.listener = listener; } }
  20. Solução 1 - Listener public class SecondActivity extends AppCompatActivity {

    ... downloadImageTaskWithListener = new DownloadImageTask(); downloadImageTaskWithListener.setListener(createListener()); }
  21. Solução 1 - Listener private DownloadImageTask.Listener createListener() { return new

    DownloadImageTask.Listener() { @Override public void onSuccess(Bitmap bitmap) { imageView.setImageBitmap(bitmap); } };
  22. Solução 1 - Listener @Override protected void onDestroy() { downloadImageTask.setListener(null);

    super.onDestroy(); } Dica: se não setar nulo no listener, vai causar leaks
  23. private static MyAsync extends AsyncTask< , , > { private

    final WeakReference<ImageView> imagem; public MyAsync(ImageView image) { this.image = new WeakReference<ImageView>(image) } } Solução 2 - weak reference
  24. Solução 2 - weak reference @Override protected void onPostExecute(Bitmap bitmap)

    { ImageView imageView = imageViewWeakReference.get(); if(imageView != null) { imageView.setImageBitmap(bitmap); } } Dica: nunca esqueça de verificar se o objeto não está nulo
  25. Leak Canary • Adicionado como dependência do projeto • Ao

    usar o app, você recebe uma notificação quando há leaks • Ao clicar na notificação, mostra o ponto que sofreu leak
  26. Dicas • Não referencie views em chamadas assíncronas • Não

    referencie views em classes anônimas que tenham tempo de vida mais longo que a activity • Use as ferramentas de profiling e Leak Canary para detectar leaks e ver o comportamento do seu app
  27. Outras otimizações • AppLaunch • Threads (bibliotecas que usam ThreadPool)

    • Estrutura de dados (SparseArray e ArrayMap) • …tem muita coisa para otimizar!!!!
  28. Referências • https://classroom.udacity.com/courses/ud825 (curso Udacity) • https://www.youtube.com/playlist?list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE 
 (Android Performance

    Patterns) • https://developer.android.com/training/best-performance.html • https://www.youtube.com/watch?v=wIy8g8yNhNk (Custos de transparência) • https://github.com/paulacr/PerformanceApp • https://youtu.be/gwqQT5NrhUg (Loving lean layouts - Huyen Tue Dao)