启动黑白屏
安装app后,启动时会有短暂的白屏,这大大影响整体的美观,姑且在这里也给算在性能优化这一块
出现白屏原因:
系统加载布局文件是需要时间的,在刚启动时布局文件还没加载完毕(即setContentView(int)之前)显示的是window背景,出现的白屏(或黑屏)是window的背景色
解决办法
替换window的背景(可为图片或纯色)
只需在启动activity界面根标签下设置android:theme="@style/MyTheme"属性
自定义一个style
<style name="Mytheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowBackground">@mipmap/ic_launcher</item>//设置图片
<item name="ndroid:windowBackground">@color/fireBar</item>//设置纯色
<item name="android:windowNoTitle">true</item>//去title
</style>
注意事项
设置属性只能设置在启动页,不能设置在application标签下,此标签代表全局
设置图片最好是.9.png类型图片(此种图可适配机型),若使用.png图片需考虑不同机型适配问题(切多种分表率的图)
布局优化
减少嵌套的层级(可使用约束布局),减少嵌套层级可加快加载效率,
使用style提取相同view的公共属性,减少重复代码
使用include标签
合理使用ViewStub
图片的优化
android中图片的使用是非常占用内存资源的。
①:在图片未使用时,及时recycle()回收
②:使用三级缓存,内存-sd卡-网络
内存中再次获取最快,由于内存有限可能被gc回收,sd卡中的图片不会回收,当前面两种都不存在所需图片时,才去网洛下载
③:将大图片进行压缩处理再放到内存中,用到BitmapFactory类
/**创建缩略图方法
*filepath 图片路径
i 压缩比例,最终为原图的1/(i^2)
*/
private Bitmap onCreateThumbnail(String filePath, int i) {
BitmapFactory.Options options=new BitmapFactory.Options();
//设置为不读内容,值读取边界值
options.inJustDecodeBounds=true;
//通过编辑,得到边界值,并存入到option中
BitmapFactory.decodeFile(filePath,options);
//赋值缩放比例
options.inSampleSize=i;
//设置显示的图片格式
options.inPreferredConfig=Config.RGB_565;
//设置为读取内容,
options.inJustDecodeBounds=false;
//得到缩略图
return BitmapFactory.decodeFile(filePath2, options);
}
④:尽量不在Button上使用selector来设置点击与正常时背景图,因为在button初始化时会将选中状态与正常状态的两张图都加载都内存中,无疑在无意中加大了内存的占用,可xml中设置正常的背景,在setOnTouchListener监听中通过代码动态改变,在按下时显示选中状态北京,抬起恢复
final Button button=new Button(this);
button.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
//手指按下
button.setBackgroundResource(R.mipmap.down);
break;
case MotionEvent.ACTION_UP:
//手指抬起,恢复
button.setBackgroundResource(R.mipmap.up);
break;
}
//为了监听事件的分发,返回false
return false;
}
});
图片解码率也会影响图片所占内存
常见的png,JPG,webp等格式的图片在设置到UI上之前需要经过解码过程,而图片采用不同的码率,也会造成对内存的占用不同。
ARGB_4444 格式的解码率,这种格式的图片,看起来质量太差,已经不推荐使用。 而强烈推荐使用ARGB_8888来代替。一个像素占用2个字节,alpha(A)值,Red(R)值,Green(G)值,Blue(B)值各占4个bites 。 共16bytes,即2个字节
ARGB_8888 格式的解码率,一个像素占用4个字节,alpha(A)值,Red(R)值,Green(G)值,Blue(B)值各占8个bytes , 共32bytes , 即4个字节。这是一种高质量的图片格式,电脑上普通采用的格式。它也是Android手机上一个BitMap的默认格式。
RGB_565格式的解码率,一个像素占用2个字节,没有alpha(A)值,即不支持透明和半透明, Red(R)值占5个bytes ,Green(G)值占6个bytes ,Blue(B)值占5个bytes,共16bytes,即2个字节。 对于半透明颜色的图片来说,该格式的图片能够达到比较好的呈现效果,相对于ARGB_8888来说也能减少一半的内存开销,因此它是一个不错的选择。推荐使用
大量数据优化
分页加载
缓存方式
列表项优化
listview的优化
convertview的复用(View的复用)
viewholder类的使用,减少查找控件的次数(findviewbyid()次数),将holder与view绑定来实现(.setTag()、.getTag())
数据分页加载
RecycleView的优化
其他优化
网络优化
同一个页面数据尽量放到一个接口中去处理
使用Application Context代替Activity Context
谨慎使用static 关键字
static使用不当容易造成内存泄漏
数据库优化
电量优化
多线程并发引发的性能等
anr异常面试问题讲解
a) 什么是anr?
应用程序无响应对话框
b) 造成anr的原因?
主线程中做了耗时操作
c) android中那些操作是在主线程呢?
activity的所有生命周期回调都是执行在主线程的
Service默认是执行在主线程的
BroadcastReceiver的onReceiver回调是执行在主线程的
没有使用子线程的Looper的Handler的handlerMessage,post(Runnable)是执行在主线程的
AsyncTask的回调中除了doInBackground,其它都是执行在主线程
d) 如何解决anr
使用AsyncTask处理耗时IO操作
使用Thread或者HandlerThread提高优先级
使用handler来处理工作线程的耗时任务
activity的onCreate和onResume回调中尽量避免耗时的代码
oom异常面试问题讲解
a) 什么是oom ?
当前占用的内存加上我们申请的内存资源超过了Dalvik虚拟机的最大内存限制就会抛出的Out of memory异常
b) 一些容易混淆的概念
内存溢出 / 内存抖动 / 内存泄漏
内存溢出:就是oom
内存抖动:短时间内大量对象被创建然后马上被释放
内存泄漏:当程序不再使用到的内存时,释放内存失败而产生了无用的内存消耗
d) 如何解决oom
1.有关bitmap优化
图片显示(比如监听listview滑动,停止的时候加载大图)
及时释放内存
bitmap的够着方法都是私有的,通过BitmapFactory生成Bitmap到内存中都是通过jni实现的,简单点说会有俩部分区域,一部分是java区,一部分是C区,但是Bitmap是通过java分配的,不用的时候也是由java的gc机制回收的。对应C区域不能及时回收的,所以这里说的释放内存就是释放的c的那块区域(通过
recycle方法,该方法内部调用了jni的方法)。要是不释放只能等进程死了以后就会被释放
图片压缩
inBitmap属性(图片复用)
捕获异常
2.其它方法
listview:convertview / lru(三级缓存)
避免在onDraw方法里面执行对象的创建
谨慎使用多进程