本文参考 Android开发艺术与探索
布局优化
绘制优化
内存泄漏优化
响应速度优化
ListView优化
Bitmap优化
线程优化
琐碎的一些优化
1、布局优化
1)选择性能较低的ViewGroup 如RelativeLayout、LinearLayout、FrameLayout.
2)减少嵌套层级 若是布局采用嵌套方式但是可以直接用一个布局实现如RelativeLayout,则建议用RelativeLayout.
3)<Include>、<merge> 这两个都是可以减少布局层级,系统会给自己创建的布局默认套上<merge>标签.
4)ViewStub 当有些布局不需要一开始就加载进来时,可以使用该标签。
2、绘制优化
1)官方推荐View的刷新频率保持在60fps为最佳,即单次刷新事件为16ms,因此在View的onDraw函数内减少耗时操作.
3、内存泄漏优化
1)静态变量导致的内存泄漏
<span style="white-space:pre"> </span>public class MainActivity extends Activity{
<span style="white-space:pre"> </span>public static Context mContext;
<span style="white-space:pre"> </span>@Override
<span style="white-space:pre"> </span>protected void onCreate(Bundle savedInstanceState) {
<span style="white-space:pre"> </span>super.onCreate(savedInstanceState);
<span style="white-space:pre"> </span>setContentView(R.layout.activity_main);
<span style="white-space:pre"> </span> <span style="white-space:pre"> </span>mContext = this;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
如上面代码所示:Context对象为静态,那么Activity就无法正常销毁,会常驻内存
。
2)单例模式导致的内存泄漏
<span style="white-space:pre"> </span>public class DensityConvertUtils {
<span style="white-space:pre"> </span>private DensityConvertUtils() {
<span style="white-space:pre"> </span>/* cannot be instantiated */
<span style="white-space:pre"> </span>throw new UnsupportedOperationException("cannot be instantiated");
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>public static int dp2px(Context context, float dpVal) {
<span style="white-space:pre"> </span>return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
<span style="white-space:pre"> </span>dpVal, context.getResources().getDisplayMetrics());
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>public static int sp2px(Context context, float spVal) {
<span style="white-space:pre"> </span>return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
<span style="white-space:pre"> </span>spVal, context.getResources().getDisplayMetrics());
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
在使用的时候,经常会出现这样的错误:
<span style="white-space:pre"> </span>public class HomeActivity extends Activity {
<span style="white-space:pre"> </span>Button btn_home;
<span style="white-space:pre"> </span>@Override
<span style="white-space:pre"> </span>protected void onCreate(Bundle savedInstanceState) {
<span style="white-space:pre"> </span>super.onCreate(savedInstanceState);
<span style="white-space:pre"> </span>requestWindowFeature(Window.FEATURE_NO_TITLE);
<span style="white-space:pre"> </span>setContentView(R.layout.layout_home);
<span style="white-space:pre"> </span>DensityConvertUtils.dp2px(HomeActivity.this,20);
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
3)属性动画导致的内存泄漏
<span style="white-space:pre"> </span>public class HomeActivity extends Activity {
<span style="white-space:pre"> </span>Button btn_home;
<span style="white-space:pre"> </span>@Override
<span style="white-space:pre"> </span>protected void onCreate(Bundle savedInstanceState) {
<span style="white-space:pre"> </span>super.onCreate(savedInstanceState);
<span style="white-space:pre"> </span>requestWindowFeature(Window.FEATURE_NO_TITLE);
<span style="white-space:pre"> </span>setContentView(R.layout.layout_home);
<span style="white-space:pre"> </span>btn_home = (Button) findViewById(R.id.btn_home);
<span style="white-space:pre"> </span>ObjectAnimator animator = ObjectAnimator.ofFloat(btn_home, "ratation", 0, 360).setDuration(2000);
<span style="white-space:pre"> </span>animator.setRepeatCount(ValueAnimator.INFINITE);
<span style="white-space:pre"> </span>animator.start();
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
解决办法是
在当前Activity的onDestroy()方法中取消动画:animator.cancel()。
4、响应速度优化
1)一般在Activity里在5秒内没响应,BroadcastReceiver在10s内没响应,系统就会爆ANR错误,因此在主线程减少耗时操作,可以的话用异步方式
5、ListView优化
1)布局的复用
2)快速滑动时避免开启大量异步加载线程
3)若是可以,可以开启硬件加速功能。
6、Bitmap优化
1)参考Imageloader的设计理念
7、线程优化
1)减少使用new Thread()方法开启线程而是使用线程池,优点是减少对象创建销毁的所带来性能开销,支持定时、周期开启线程,重用空闲线程,避免大量线程互相抢占系统资源而导致的堵塞。
8、琐碎的一些性能优化建议
1)避免创建过多线程
2)不要过多使用枚举,性能开销比整型更大
3)常量使用static final 修饰
4)使用一些Android的特有数据结构如SparseArray和Pair
5)使用软引用和弱引用
6)采用磁盘缓存和内存缓存
7)尽量采用静态内部类,因为单纯的内部类会隐式的持有外部类的一个引用,尤其是AsyncTask的内部类,生命周期若是比Activity长的话,销毁会导致内存无法释放