一、xml文件布局优化
1.使用include 标签
抽取多个布局文件共用的代码块,在需要的位置使用include标签添加进去。
减少代码量,提高代码维护性
2.使用merage标签
降低UI布局的嵌套层次。
使用情景:
a.布局根结点是FrameLayout且不需要设置background或padding等属性,可以用merge代替,因为Activity内容布局的parent view就是个FrameLayout(就setContentView),所以可以用merge消除只剩一个
b.某布局作为子布局被其他布局include时,使用merge当作该布局的顶节点,这样在被引入时顶结点会自动被忽略,而将其子节点全部合并到主布局中。
3.使用ViewStub标签
Viewstub标签同include标签一样可以用来引入一个外部布局,不同的是,viewstub引入的布局默认不会扩张,即既不会占用显示也不会占用位置,从而在解析layout时节省cpu和内存。 viewstub常用来引入那些默认不会显示,只在特殊情况下显示的布局
注意:Viewstub控制的是一个布局文件,而非某个View。
某些布局属性要加在ViewStub而不是实际的布局上面,才会起作用,比如android:layout_margin*系列属性,如果加在TextView上面,则不会起作用,需要放在它的ViewStub上面才会起作用。而ViewStub的属性在inflate()后会都传给相应的布局。
使用方法:
通过(ViewStub)findViewById(id)找到ViewStub,通过stub.inflate()展开ViewStub,然后得到子View。
private View errorView;
private void showError() {
// not repeated infalte
if (errorView != null) {
errorView.setVisibility(View.VISIBLE);
return;
}
ViewStub stub = (ViewStub)findViewById(R.id.error_layout);
errorView = stub.inflate();
Button networkSetting = (Button)errorView.findViewById(R.id.network_setting);
Button refresh = (Button)errorView(R.id.network_refresh);
}
private void showContent() {
if (errorView != null) {
errorView.setVisibility(View.GONE);
}
}
/--------------------------------------------/
ViewStub使用,展开方式:
ViewStub stub = (ViewStub)findViewById(R.id.network_error_layout);
networkErrorView = stub.inflate();
或者
View viewStub = findViewById(R.id.network_error_layout);
viewStub.setVisibility(View.VISIBLE); // ViewStub被展开后的布局所替换
networkErrorView = findViewById(R.id.network_error_layout); // 获取展开后的布局
虽然把View的初始可见View.GONE但是在Inflate布局的时候View仍然会被Inflate,也就是说仍然会创建对象,会被实例化,会被设置属性。也就是说,会耗费内存等资源。
ViewStub是一个轻量级的View,它一个看不见的,不占布局位置,占用资源非常小的控件。可以为ViewStub指定一个布局,在Inflate布局的时候,只有ViewStub会被初始化,然后当ViewStub被设置为可见的时候,或是调用了ViewStub.inflate()的时候,ViewStub所向的布局就会被Inflate和实例化,然后ViewStub的布局属性都会传给它所指向的布局。
4.尽量为所有分辨率创建资源,减少不必要的硬件缩放,这会降低UI的绘制速度
二、性能优化
1.数据库优化
a.为数据建立索引---------------------------------------------------->>>>需要去查资料怎么建立和使用,没有使用过,在数据库没有达到几万条数据时,效果貌似不是很明显,不过是个很好的习惯,以后需要注意
b.使用事务
同一事务内的所有修改要么都完成要么都不做,如果某个修改失败,会自动回滚使得所有修改不生效。
Sqlite默认会为每个插入、更新操作创建一个事务,并且在每次插入、更新后立即提交。
显示的创建事务->执行100条语句->提交会使得这个创建事务和提交这个过程只做一次,通过这种一次性事务可以使得性能大幅提升。
2.代码优化
a.算法优化,逻辑优化
b.缓存
缓存主要包括对象缓存、IO缓存、网络缓存、DB缓存。
对象缓存能减少内存的分配,IO缓存减少磁盘的读写次数,网络缓存减少网络传输,DB缓存较少Database的访问次数。
方式:
文件IO缓存
使用具有缓存策略的输入流,BufferedInputStream替代InputStream,BufferedReader替代Reader,BufferedReader替代BufferedInputStream.对文件、网络IO皆适用。
网络缓存:okhttp设置。
数据存储优化
包括数据类型、数据结构的选择。
a. 数据类型选择
字符串拼接用StringBuilder代替String,在非并发情况下用StringBuilder代替StringBuffer。如果你对字符串的长度有大致了解,如100字符左右,可以直接new StringBuilder(128)指定初始大小,减少空间不够时的再次分配。
64位类型如long double的处理比32位如int慢
使用SoftReference、WeakReference相对正常的强应用来说更有利于系统垃圾回收
final类型存储在常量区中读取效率更高
LocalBroadcastManager代替普通BroadcastReceiver,效率和安全性都更高
SparseArray、SparseBooleanArray、SparseIntArray、Pair。
Sparse系列的数据结构是为key为int情况的特殊处理,采用二分查找及简单的数组存储,加上不需要泛型转换的开销,相对Map来说性能更优。
异步,利用多线程提高TPS
提前或延迟操作,错开时间段提高TPS
不在Activity、Service、BroadcastReceiver的生命周期等对响应时间敏感函数中执行耗时操作,可适当delay。
Java中延迟操作可使用ScheduledExecutorService,不推荐使用Timer.schedule;
Android中除了支持ScheduledExecutorService之外,还有一些delay操作,如
handler.postDelayed,handler.postAtTime,handler.sendMessageDelayed,View.postDelayed,AlarmManager定时等。
对于第一次调用较耗时操作,可统一放到初始化中,将耗时提前。