Exemplos de ajuste de desempenho do Android (5)

Este artigo foi reproduzido de: Trinea

Incluindo síncrono para assíncrono, cache, otimização de layout, otimização de banco de dados, otimização de algoritmo, execução atrasada, etc.

1. Ponto de gargalo de desempenho
A página inteira é composta principalmente de 6 Page ViewPagers, cada página é um GridView e o GridView exibe aproximadamente 4 * 4 informações de item em uma tela (há uma imagem no final deste artigo). Devido à grande quantidade de aquisição de dados de rede e à necessidade de manter o progresso e o status do download do aplicativo na página a qualquer momento, ocorrem os seguintes problemas de desempenho: a. O ViewPager desliza para a esquerda e para a direita
e fica
obviamente travado. O GridView rola para cima e para baixo.
c. Outras atividades retornam lentamente à atividade do ViewPager.
d. A velocidade de aquisição e exibição da rede é lenta


2. Depuração e posicionamento de desempenho

Use principalmente Traceview , macaco, macaco runner para depuração. Traceview é semelhante ao visualvm para ajuste da web java. O método de uso é o seguinte:
adicione a função onCreate da atividade que precisa ser ajustada.

Adicionar função onDestrory

Após a saída do programa, o arquivo Entertainment.trace será gerado no diretório raiz do cartão SD. Vá para o diretório de ferramentas do SDK do Android usando cmd e execute traceview.bat Entertainment.trace. A captura de tela é a seguinte

A partir disso, você pode ver o tempo de chamada, o número de chamadas, o tempo médio de chamada, a porcentagem de tempo ocupado, etc. de cada função para localizar operações demoradas. Para obter mais detalhes sobre macaco e macaco corredor, consulte a seguinte introdução do blog.


3. As vantagens do ajuste de desempenho

incluem principalmente síncrono para assíncrono, cache, otimização de layout, otimização de banco de dados, otimização de algoritmo e execução atrasada.
1. Mudança de síncrono para assíncrono.

Escusado será dizer que operações demoradas são executadas em threads para evitar a ocupação do thread principal, o que resolve anr até certo ponto.
Mas você precisa prestar atenção à combinação de threads e serviços (para evitar que o thread seja reciclado após a reciclagem da atividade) e ao número de threads. O pool de threads
usa um pool de threads java visível.


2.

A criação de objetos Java em cache requer alocação de recursos e é demorada. Além disso, quanto mais objetos criados, mais frequente o GC afetará a resposta do sistema. Use principalmente o modo singleton, cache (cache de imagem, pool de threads, cache de visualização, cache de IO, cache de mensagens, cache de notificação da barra de notificação) e outros métodos para reduzir a criação de objetos.
(1) Modo Singleton
Este método pode ser usado para classes cuja criação é cara para garantir que haja uma instância global.Durante a execução do programa, a classe não incorrerá em sobrecarga devido à criação de objetos adicionais. O código de exemplo é o seguinte:


(2). 缓存
程序中用到了图片缓存、线程池、View缓存、IO缓存、消息缓存、通知栏notification缓存等。
a. 图片缓存:ImageCacheImageSdCache


b. 线程池:
使用Java的Executors类,通过newCachedThreadPool、newFixedThreadPool、newSingleThreadExecutor、newScheduledThreadPool提供四种不同类型的线程池


c. View缓存:

可见ListView缓存机制

通过convertView是否为null减少layout inflate次数,通过静态的ViewHolder减少findViewById的次数,这两个函数尤其是inflate是相当费时间的


d. IO缓存:

使用具有缓存策略的输入流,BufferedInputStream替代InputStream,BufferedReader替代Reader,BufferedReader替代BufferedInputStream.对文件、网络IO皆适用。


e. 消息缓存:
通过Handler的obtainMessage回收就的Message对象,减少Message对象的创建开销
handler.sendMessage(handler.obtainMessage(1));


f. 通知栏notification缓存:
下载中需要不断改变通知栏进度条状态,如果不断新建Notification会导致通知栏很卡。这里我们可以使用最简单的缓存
Map<String, Notification> notificationMap = new HashMap<String, Notification>();如果notificationMap中不存在,则新建notification并且put into map.


(3). 其他
能创建基类解决问题就不用具体子类:
除需要设置优先级的线程使用new Thread创建外,其余线程创建使用new Runnable。因为子类会有自己的属性创建需要更多开销。
控制最大并发数量:使用Java的Executors类,通过Executors.newFixedThreadPool(nThreads)控制线程池最大线程并发
对于http请求增加timeout

 

3. Layout优化
使用抽象布局标签(include, viewstub, merge)、去除不必要的嵌套和View节点、减少不必要的infalte及其他Layout方面可调优点,顺带提及布局调优相关工具(hierarchy viewer和lint)。具体可见性能优化之布局优化
TextView属性优化:TextView的android:ellipsize=”marquee”跑马灯效果极耗性能,具体原因还在深入源码中

 

4. 数据库优化
主要包括索引和事务及针对Sqlite的优化。具体可见性能优化之数据库优化


5. 算法优化

这个就是个博大精深的话题了,只介绍本应用中使用的。
使用hashMap代替arrayList,时间复杂度降低一个数量级


6. 延迟执行

对于很多耗时逻辑没必要立即执行,这时候我们可以将其延迟执行。
线程延迟执行 ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(10);
消息延迟发送 handler.sendMessageDelayed(handler.obtainMessage(0), 1000);


四、本程序性能调优结果
1. ViewPager左右滑动明显卡顿
2. GridView上下滚动明显卡顿

(1). 去掉TextView的android:ellipsize=”marquee”
(2). 修改图片缓存的最大线程数,增加http timeout
(3). 修改设置app是否已安装的状态,具体代码修改如下:

修改为

从每次获取List<PackageInfo> installedAppList = getPackageManager().getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);修改为只在有应用安装或卸载广播时获取应用列表,并且用hashMap代替installedAppList减少查询时间。

将平均执行时间从201ms降低到1ms。


3. 其他Activity返回ViewPager Activity较慢

定位:在onStart函数
解决:使用延迟策略,具体代码修改如下:

改为


4. 网络获取到展现速度较慢

定位:在HttpURLConnection.getInputStream()之后的处理
解决:使用BufferedReader替代BufferedInputStream获取时间从100ms降低到3ms,具体代码修改如下:

改为


Acho que você gosta

Origin blog.csdn.net/skylovesky/article/details/26463017
Recomendado
Clasificación