开发中常会做一些性能优化,主要优化内容包括布局层级优化,绘制优化,内存泄露优化(音频,视频,io等回收),响应速度优化,ListView优化,Bitmap优化,线程优化以及一些性能优化,在面试中面试官也会经常问到该点 . 前面博文我收集的各大厂等面试题
布局优化思想,尽量减少布局文件的层级,层级少,意味Android绘制时的工作量少了,程序的性能自然提高了.
绘制优化是指View的onDraw方法要避免执行大量的操作,如下三点
内存泄露在开发过程中是一个需要重视的问题,但是由于内存泄露问题 对开发人员的经验和开发意识有较高的要求,因此这也是开发人员最容易犯的错误之一.内存泄露的优化分为两个方面,一方面是开发过程中避免写出有内存泄露的代码.另一方面是通过一些分析工具找出潜在的内存泄露
单例模式导致的内存泄露:Activty是间接继承于Context的,当这Activity退出时,Activity应该被回收, 但是单例中又持有它的引用,导致Activity回收失败,造成内存泄漏。
package com.kx.singleinstance;
import android.content.Context;
/**
* @ 创建: kx
* @ 时间: 2018/11/13
* @ 描述:
*/
public class AppManager {
private static AppManager instance;
private Context mContext;
public AppManager(Context context) {
mContext = context;
}
public static AppManager getInstance(Context context){
if(instance == null){
instance = new AppManager(context);
}
return instance;
}
}
单例模式导致的内存泄露改进:使用Applicaton的Context,而我们单例的生命周期和应用的一样长,这样就防止了内存泄漏。
package com.kx.singleinstance;
import android.content.Context;
/**
* @ 创建: kx
* @ 时间: 2018/11/13
* @ 描述:
*/
public class AppManager {
private static AppManager instance;
private Context mContext;
public AppManager(Context context) {
//使用Applicaton的Context,而我们单例的生命周期和应用的一样长,这样就防止了内存泄漏。
mContext = context.getApplicationContext();
}
public static AppManager getInstance(Context context){
if(instance == null){
instance = new AppManager(context);
}
return instance;
}
}
响应速度优化的核心思想是避免在主线程中做耗时操作,这里具体可参考前面的文章.耗时操作放在线程中去执行,即采用异步的方式执行耗时操作.响应速度过慢更多地体现在Activity的启动速度上面,如果在主线中做太多事情,会导致Activity启动时出现黑屏现象,甚至出现ANR, Android规定,Activity如果5秒钟之内无法响应屏幕触摸事件或者键盘输入时间就会出现ANR,而BroadcastReceiver如果10秒钟之内还未执行完操作也会出现ANR.
listview优化
convertView的使用,主要优化加载布局问题
内部类ViewHolder的使用,采用ViewHolder并避免在getView中执行耗时操作
滑动的时候不载入图片
在ListView滑动的时候载入图片,那样会使ListView变得卡顿,所以我们须要再监听器里面监听ListView的状态。假设滑动的时候,停止载入图片,假设没有滑动,则開始载入图片
listView.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView listView, int scrollState) {
//停止载入图片
if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING) {
imageLoader.stopProcessingQueue();
} else {
//開始载入图片
imageLoader.startProcessingQueue();
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
}
});
将ListView的scrollingCache和animateCache设置为false
A.scrollingCache: scrollingCache本质上是drawing cache,你能够让一个View将他自己的drawing保存在cache中(保存为一个bitmap),这样下次再显示View的时候就不用重画了,而是从cache中取出。默认情况下drawing cahce是禁用的。由于它太耗内存了,可是它确实比重画来的更加平滑。而在ListView中,scrollingCache是默认开启的,我们能够手动将它关闭。
B.animateCache: ListView默认开启了animateCache,这会消耗大量的内存,因此会频繁调用GC,我们能够手动将它关闭掉
降低item的布局的深度
尽量降低item布局深度,由于当滑动ListView的时候,这回直接导致測量与绘制,因此会浪费大量的时间。所以我们应该将一些不必要的布局嵌套关系去掉。
分批加载与分页加载相结合
线程优化的核心思想是采用线程池,避免程序中存在大量的Thread.线程池可以重用内部的线程,从而避免了线程的创建和销毁所带来的性能开销,同时线程池还能有效地控制线程池的最大并发数,避免大量的线程因互相抢占系统资源从而导致阻塞现象的发生.因此在实际开发中,我们要尽量采用线程池,而不是每次都要创建一个Thread对象
激励:为自己技术增值,量变引起质变.博主依稀记得当前的语文老师说的一句话:“态度决定高度”,博主想对所有的读者说"过去的已经过去,你的未来由你现在把握".
本文如有错误或不当之处,欢迎读者留言斧正,互相交流学习,博主不胜感激.联系邮箱[email protected]