Slide 1

Slide 1 text

OTIMIZAÇÕES DE PERFORMANCE EM APLICAÇÕES ANDROID Paula Caroline da Rosa Desenvolvedora Android @ Concrete @_paulacr (Twitter)

Slide 2

Slide 2 text

RENDERIZAÇÃO NO ANDROID Uma imagem vale mais que mil palavras (às vezes)

Slide 3

Slide 3 text

RENDERIZAÇÃO NO ANDROID 10 a 12 frames por segundo convincente sensação de movimento 60 frames por segundo Transições suaves (smooth transitions) Frames Tempo é vital Dropped Frame GPU Profiling tool

Slide 4

Slide 4 text

RENDERIZAÇÃO NO ANDROID Em 16ms: • Computação • Desenhar componentes na tela • Atualização de views na tela • Animações • Tempo para o GC recolher objetos 16ms 16ms 16ms Calculando: 1000ms 60 frames = 16.666ms/frame Frames Tempo é vital Dropped Frame GPU Profiling tool

Slide 5

Slide 5 text

RENDERIZAÇÃO NO ANDROID 22ms 20ms 8ms Dropped 
 Frame Frames Tempo é vital Dropped Frame GPU Profiling tool • Ocorre quando a execução demora mais que 16ms • Animações/transições sofrem pausa • Pode dar sensação que o app travou

Slide 6

Slide 6 text

RENDERIZAÇÃO NO ANDROID Navigation Performance Active application performance NotificationBar performance 16ms Frames Tempo é vital Dropped Frame GPU Profiling tool

Slide 7

Slide 7 text

RENDERIZAÇÃO NO ANDROID Frames Tempo é vital Dropped Frame GPU Profiling tool

Slide 8

Slide 8 text

RENDERIZAÇÃO NO ANDROID 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 Frames Tempo é vital Dropped Frame GPU Profiling tool

Slide 9

Slide 9 text

…E quando a animação trava…

Slide 10

Slide 10 text

INIMIGOS DA RENDERIZAÇÃO •Hierarquias profundas (hadooken) •Backgrounds desnecessários •Update frequente de views (invalidate e onDraw) •Trabalho excessivo na GPU

Slide 11

Slide 11 text

OVERDRAW: O VILÃO Ah, põe essas views coloridas aí, vai dar mais vida e o usuário vai amar (Com amor, Designer)

Slide 12

Slide 12 text

OVERDRAW Definição Identificando overdraw Corrigindo overdraw • 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

Slide 13

Slide 13 text

OVERDRAW Nome Loren ipsun loren loren ipsun loren favoritar compartilhar Como você vê seu app Como Android vê seu app Nome Loren ipsun loren loren ipsun loren favoritar compartilhar Nome Loren ipsun loren loren ipsun loren favoritar compartilhar Definição Identificando overdraw Corrigindo overdraw

Slide 14

Slide 14 text

OVERDRAW Toolbar 1x Overdraw 2x Overdraw 3x Overdraw 4x Overdraw Definição Identificando overdraw Corrigindo overdraw

Slide 15

Slide 15 text

OVERDRAW Definição Identificando overdraw Corrigindo overdraw fundo branco fundo roxo fundo rosa • Crie um “style” para cada tema da aplicação • No manifest, dentro da tag de cada activity coloque o tema correspondente • Isso evita você precisar colocar background no layout pai de cada layout Temas do seu app

Slide 16

Slide 16 text

OVERDRAW • Veja se é possível simplificar a sua view • Remova backgrounds desnecessários Sem background 
 no layout main Sem background 
 no item Definição Identificando overdraw Corrigindo overdraw

Slide 17

Slide 17 text

MAIS DICAS • Verificar se o componente precisa de um layout extra • Customizar temas da aplicação • Desenhar somente o que está visível para o usuário. Ex: customviews (Udacity) • Reduzir layouts com transparência (The hidden cost of transparency) 
 https://www.youtube.com/watch?v=wIy8g8yNhNk • ConstraintLayout
 https://android-developers.googleblog.com/2017/08/understanding- performance-benefits-of.html

Slide 18

Slide 18 text

MEMORY LEAKS Chama um encanador, porque eu achei um vazamento!!!

Slide 19

Slide 19 text

MEMORY LEAKS Garbage collector Definição de memory leaks Como causamos memory leaks Memória • Gerenciamento de memória automático (automatic memory management) • O garbage collector marca os objetos eleitos como “destruíveis" e posteriormente os recolhe • Desenvolvedor não tem controle de quando GC passa

Slide 20

Slide 20 text

Garbage collector Definição de memory leaks Como causamos memory leaks Object Lifecycle Object Object Object Activity Lifecycle LEAK MEMORY LEAKS • A activity 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)

Slide 21

Slide 21 text

Garbage collector Definição de memory leaks Como causamos memory leaks • A activity atual é destruída • Outra activity é criada • Se tiver leaks na activity destruída, ela não é coletada • Parabéns: você ganhou uma activity de brinde :) Device rotacionado MEMORY LEAKS

Slide 22

Slide 22 text

Garbage collector Definição de memory leaks Como causamos memory leaks • A activity é recriada toda vez que há uma mudança de configuração android:configChanges= ["mcc", "mnc", "locale","touchscreen", "keyboard", "keyboardHidden","navigation", "screenLayout", "fontScale","uiMode", "orientation", "screenSize","smallestScreenSize"] MEMORY LEAKS Bora fazer do jeito certo? #PorFavor Eu nunca te pedi nada…

Slide 23

Slide 23 text

TIPOS DE MEMORY LEAKS E COMO CORRIGÍ-LOS Yes, yes, show me the code!!!

Slide 24

Slide 24 text

TIPOS DE MEMORY LEAKS Contexto estático Classes anônimas e inner classes Referenciar views em chamadas assíncronas Soluções public class MainActivity extends AppCompatActivity { private static Activity activity; @Override protected void onCreate(Bundle saveState) activity = this; } }

Slide 25

Slide 25 text

• Pra que usar contexto estático? (se pergunte pelo menos 10 vezes) • Nunca passe o contexto, views ou referências da activity para um Singleton (ou qualquer outro recurso que irá viver mais tempo que a activity) • 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) Contexto estático Classes anônimas e inner classes Referenciar views em chamadas assíncronas Soluções TIPOS DE MEMORY LEAKS

Slide 26

Slide 26 text

Contexto estático Classes anônimas e inner classes Referenciar views em chamadas assíncronas Soluções • Facilitam a implementação • Permitem melhor organização do código • Mas podem trazem um problema: Referência implícita TIPOS DE MEMORY LEAKS

Slide 27

Slide 27 text

Contexto estático Classes anônimas e inner classes Referenciar views em chamadas assíncronas Soluções class MainActivity extends AppCompatActivity { ImageView imageView; private class DownloadImage extends AsyncTask<..,..,..>{ ... @Override protected void onPostExecute(Bitmap result) { imageView.setImageBitmap(result); } } } Leak Threads, Callbacks, AsyncTask Leak TIPOS DE MEMORY LEAKS

Slide 28

Slide 28 text

Contexto estático Classes anônimas e inner classes Referenciar views em chamadas assíncronas Soluções @Override protected void onCreate(Bundle savedInstanceState) { ... new Timer().schedule(new TimerTask() { @Override public void run() { image.setImageResource(R.drawable.imagem); } }, LONG_TIME); } Leak Cuidado com Handlers TIPOS DE MEMORY LEAKS

Slide 29

Slide 29 text

Contexto estático Classes anônimas e inner classes Referenciar views em chamadas assíncronas Soluções • Chamadas assíncronas podem ter mais vida que a activity • Ao referenciar uma view numa chamada assíncrona pode ocorrer dois problemas: • A view pode não existir mais (a activity que possui a view pode ter sido destruída) (NullPointerException) • Pode estar causando um memory leak TIPOS DE MEMORY LEAKS

Slide 30

Slide 30 text

SOLUÇÃO 1 LISTENERS private static class DownloadImageTask extends AsyncTask< , , > { private Listener listener; interface Listener { void onSuccess(Bitmap bitmap); } public void setListener(Listener listener) { this.listener = listener; } }

Slide 31

Slide 31 text

SOLUÇÃO 1 LISTENERS public class SecondActivity extends AppCompatActivity { ... downloadImageTaskWithListener = new DownloadImageTask(); downloadImageTaskWithListener.setListener(createListener()); }

Slide 32

Slide 32 text

SOLUÇÃO 1 LISTENERS private DownloadImageTask.Listener createListener() { return new DownloadImageTask.Listener() { @Override public void onSuccess(Bitmap bitmap) { imageView.setImageBitmap(bitmap); } };

Slide 33

Slide 33 text

SOLUÇÃO 1 LISTENERS @Override protected void onDestroy() { downloadImageTask.setListener(null); super.onDestroy(); } Dica: se não setar nulo no listener, vai causar leaks

Slide 34

Slide 34 text

SOLUÇÃO 2 WEAK REFERENCE private static MyAsync extends AsyncTask< , , > { private final WeakReference imagemWeak; public MyAsync(ImageView image) { this.imagemWeak = new WeakReference(image) } }

Slide 35

Slide 35 text

SOLUÇÃO 2 WEAK REFERENCE @Override protected void onPostExecute(Bitmap bitmap) { ImageView imageView = imagemWeak.get(); if(imageView != null) { imageView.setImageBitmap(bitmap); } }

Slide 36

Slide 36 text

RENDERIZAÇÃO NO ANDROID Contexto estático Classes anônimas e inner classes Referenciar views em chamadas assíncronas Soluções • IntentServices • RxJava (com cuidado) • EventBus • Architecture Components

Slide 37

Slide 37 text

PROFILING TOOLS Mãos à obra

Slide 38

Slide 38 text

PROFILING TOOLS Leak canary Profiling tools Profiling de memória Profiling de CPU Profiling de rede • 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

Slide 39

Slide 39 text

PROFILING TOOLS Leak canary Profiling tools Profiling de memória Profiling de CPU Profiling de rede

Slide 40

Slide 40 text

PROFILING TOOLS Leak canary Profiling tools Profiling de memória Profiling de CPU Profiling de rede

Slide 41

Slide 41 text

PROFILING TOOLS Leak canary Profiling tools Profiling de memória Profiling de CPU Profiling de rede GC / Dump / Record Alloc Count Arrange by package

Slide 42

Slide 42 text

PROFILING TOOLS Leak canary Profiling tools Profiling de memória Profiling de CPU Profiling de rede Thread Ativa Ativa, aguardando Sleeping thread Total de threads

Slide 43

Slide 43 text

PROFILING TOOLS Leak canary Profiling tools Profiling de memória Profiling de CPU Profiling de rede

Slide 44

Slide 44 text

MAIS 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

Slide 45

Slide 45 text

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)

Slide 46

Slide 46 text

CONTATO @_paulacr (Twitter) [email protected] https://www.linkedin.com/in/paularosa/