1.布局优化
如果布局中既可以使用RelativeLayout,也可以使用LinearLayout,那么就采用LinearLayout,这是因为RelativeLayout的功能比较复杂,他的布局过程需要花费更多的CPU时间,FrameLayout和LinearLayout一样都是一种简单高效的ViewGroup,但是很多时候单纯的LinearLayout或者FramneLayout无法实现产品的效果,需要通过嵌套的方式来完成,这种情况下还是建议采用RelativeLayout,因为ViewGroup的嵌套相当于增加了布局的层级。
<include>标签、<merge>标签、ViewStub是布局优化的另一种手段。
注意,<include>标签只支持一android:layout_开通的属性,如果<iinclude>标指定了android:layout_*属性,那么要求android:layout_width和android:layout_heigth必须存在,否则其他android:layout_*属性无法生效。
<merge>标签一般和<include>标签一起使用从而减少布局的层级
eg
<LinearLayout xmls:android = "http://schemas.android.com/apk/res/android"
android:orientation = "vertical"
android:layout_width = "match_parent"
android:layout_height = "match_parent"
>
<include layout = "@layout/titlbar">
<TextView android :layout_width = "match_parent"
android:layout_height = "wrap_content"
>
</LinearLayout>
<merge xmls:android = "http://schemas.android.com/apk/res/android">
<Button
android:layout_width = "wrap_content"
android:layout_height = "wrap_content" >
<Button
android:layout_width = "wrap_content"
android:layout_height = "wrap_content" >
</merge>本例中,由于当前布局是一个竖直方向的LinearLayout,这个时候如果被包含的布局文件也采用了竖直方向的LinearLayout,那么显然被包含的文件中的LinearLayout是多余的,通过<merge>标签就可以去掉多余的那一层LinearLayout
ViewStub
ViewStub的意义在于按需加载所需的布局而文件
<ViewStub
android:id = "@+id/stup_import"
android:inflated = "@+id/panel_import"
android:layout = "@layout/layout_network_error"
android:layout_width = "match_parent"
android:layout_height = "match_parent" >
其中stub_import是ViewStub的Id,panel_import是@layout/layout_network_error这个布局元素的根布局元素的Id
在需要加载ViewStub中的布局时的方法
(ViewStub)findViewById(R.id.stub_import).setVisible(View.VISIBLE);
或者View inportPanel = ((ViewStub)findViewById(R.id.stub_import)).inflate();
ViewStub加载后,ViewStub就不再是整个布局结构中的一部分了,另外,目前ViewStub不支持<merge>标签
2.绘制优化
绘制优化是指View的onDraw方法要避免执行大量的操作,
onDraw中不要创建新的局部对象,这是因为onDraw方法可能会被频繁调用,这样就会在一瞬间产生大量的临时对象,不仅用了过多的内存而且还会导致系统更加频繁gc,降低了程序的执行效率
onDrawf方法中不要做耗时的任务,也不能执行成千上万的循环操作,尽管每次都是轻量级的,但是大量的循环仍然抢占CPU的时间片,这会造成View的绘制过程不流畅
3.内存泄漏优化
a.静态变量导致的内存泄漏
eg
activity无法销毁
public class MainActivity extends Activity{
private static final String TAG = "MainActivity";
private static Context sContext;
@override
protected void onCreate(Bundle saveInstanceState){
super.onCreate(saveInstanceState);.
setContentView(R.layout.activity_main);
sContext = this;
}
}
public class MainActivity extends Activity{
private static final String TAG = "MainActivity";
private static View sView;
@override
protected void onCreate(Bundle saveInstanceState){
super.onCreate(saveInstanceState);.
setContentView(R.layout.activity_main);
sView= newView(this) ;
}
}
b.单例模式导致的内存泄漏
静态标量持有Activity,导致activity无法释放
c.属性动画导致的内存泄漏
属性动画有一类无限循环的动画,如果在Activity中播放此类动画且没有在onDestory中去停止动画,那么动画会一直播放下去,尽管已经无法在界面上看到播放效果,并且这个时候Activity的View会只有动画,而View有持有Activity,最终Activity无法释放,解决办法是在Activity的onDestory中调用animator.cancel()
4.响应速度优化
核心思想是避免在主线程中做耗时操作,可以将耗时操作放在线程中去执行,即采用异步的方式执行耗时操作,响应速度额过慢更多的体现在Activity的启动时出现黑屏现象。甚至出现ANR
5.ListView和Bitmap的优化
ListView的优化有:采用ViewHolder并避免在getView中执行耗时操作,根据列表滑动状态来控制任务的执行频率,比如当列表快速滑动时显然不适合开启大量的异步任务
bitmap优化:BitmapFactory.Options来根据需要对图片进行采样,主要用到BitmapFactory.Options的inSampleSize参数
6.线程优化
线程的优化思想是采用线程池,避免程序中存在大量的Thread。线程池可以重用内部的线程,从而避免线程的创建和销毁所带来的性能开销。同时线程池还能有效的控制线程池的最大并发数,避免大量的线程因互相抢占系统资源从而导致的阻塞现象的发生。
7优化的建议
避免创建过多的对象
不要过多的使用枚举,枚举占用的内存空间比整数大
常量要使用static final来修饰
使用Android的数据结构,比如Spar'seAr'ray和Pair等。他们都具有更好的性能
适当使用软引用和弱引用
采用内存缓存和磁盘缓存
尽量采用静态内部类,这样可以避免潜在的由于内部类而导致的内存泄漏