Android performance tuning examples (5)

This article is reproduced from: Trinea

Including synchronous to asynchronous, caching, layout optimization, database optimization, algorithm optimization, delayed execution, etc.

1. Performance bottleneck point
The entire page is mainly composed of 6 Page ViewPagers, each Page is a GridView, and the GridView displays approximately 4*4 item information on one screen (there is a picture at the end of this article). Due to the large amount of network data acquisition and the need to maintain the download progress and status of the app on the page at any time, the following performance problems occur. a
. The ViewPager slides left and right and is
obviously stuck. b. The GridView scrolls up and down.
c. Other activities return to the ViewPager Activity slowly.
d. Network acquisition and display speed is slow


2. Performance debugging and positioning

Mainly use Traceview , monkey, monkey runner for debugging. Traceview is similar to visualvm for java web tuning. The usage method is as follows:
add in the activity onCreate function that needs to be tuned.

Add in onDestrory function

After the program exits, the file Entertainment.trace will be generated in the root directory of the sd card. Go to the tools directory of the android sdk using cmd and run traceview.bat Entertainment.trace. The screenshot is as follows

From this, you can see the calling time, number of calls, average calling time, time occupied percentage, etc. of each function to locate time-consuming operations. For more details about monkey and monkey runner, see the following blog introduction.


3. Performance tuning advantages

mainly include synchronous to asynchronous, caching, Layout optimization, database optimization, algorithm optimization, and delayed execution.
1. Change from synchronous to asynchronous.

Needless to say, time-consuming operations are executed in threads to prevent occupying the main thread, which solves anr to a certain extent.
But you need to pay attention to the combination of threads and services (to prevent the thread from being recycled after the activity is recycled) and the number of threads. The thread
pool uses a visible java thread pool.


2. Cache

java object creation requires allocating resources and is time-consuming. In addition, the more objects created, the more frequent gc will affect the system response. Mainly use singleton mode, cache (picture cache, thread pool, View cache, IO cache, message cache, notification bar notification cache) and other methods to reduce object creation.
(1). Singleton mode
This method can be used for classes that are expensive to create to ensure that there is a global instance. During the running of the program, the class will not incur overhead from creating additional objects. The sample code is as follows:


(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,具体代码修改如下:

改为


Guess you like

Origin blog.csdn.net/skylovesky/article/details/26463017