UI优化/内存优化/ 大图加载/多图加载/ANR/OOM/GC/Http/Https/ListView优化/fragment/binder底层实现/Service保活/进程

待补充

内存优化:

https://blog.csdn.net/lighthouse666/article/details/70230614

UI优化/内存优化/ 大图加载/多图加载/ANR/OOM/GC/Http/Https/ListView优化/fragment/binder底层实现/Service保活/进程_第1张图片

内存优化分为:【一个本质和三个知识点】 
本质:对象的引用未被释放,导致对象本身无法被有效的回收。 

三个知识点:内存泄漏、内存溢出、内存优化工具。

【内存泄漏】 
1.单例模式引发的内存泄漏: 
原因:单例模式里的静态实例持有对象的引用,导致对象无法被回收,常见为持有Activity的引用 
优化:改为持有Application的引用,或者不持有使用的时候传递。

2.集合操作不当引发的内存泄漏: 
原因:集合只增不减 
优化:有对应的删除或卸载操作

3.线程的操作不当引发的内存泄漏: 
原因:线程持有对象的引用在后台执行,与对象的生命周期不一致 
优化:静态实例+弱引用(Weakrefrence)方式,使其生命周期一致

4.匿名内部类/非静态内部类操作不当引发的内存泄漏: 
原因:内部类持有对象引用,导致无法释放,比如各种回调 
优化:保持生命周期一致,改为静态实例+对象的弱引用方式(WeakReference)

5.常用的资源未关闭回收引发的内存泄漏: 
原因:BraodcastReceiver,File,Cursor,IO流,Bitmap等资源使用未关闭 
优化:使用后有对应的关闭和卸载机制

6.Handler使用不当造成的内存泄漏: 
原因:Handler持有Activity的引用,其发送的Message中持有Handler的引用,当队列处理Message的时间过长会导致Handler无法被回收 
优化:静态实例+弱引用(Weakrefrence)方式 
销毁对象时候清空队列里的Message

内存溢出: 
原因: 
1.内存泄漏长时间的积累 
2.业务操作使用超大内存 
优化: 
1.调整图像大小后再放入内存、及时回收 
2.不要过多的创建静态变量

内存优化工具: 

Square、LeakCanary、MAT(Eclipse内存分析工具)、DDMS、Android Monitor(Android Studio内存分析工具)

TraceView androidsdk自带的工作,用于测量函数耗时的。

ADB介绍

        https://www.jianshu.com/p/0730da7198dd

        Adb的全称为Android Debug Bridge:android调试桥梁 支持TCP/IP  和USB两种连接调试方式

        协助开发人员在开发android应用的过程中更快更好的调试apk,因此adb具有安装卸载apk、拷贝推送文件、查看设备硬件信息、查看应用程序占用资源、在设备执行shell命令等功能

ADB是一个C/S架构的应用程序,由三部分组成:
        1、运行在pc端的adb client:
命令行程序”adb”用于从shell或脚本中运行adb命令。首先,“adb”程序尝试定位主机上的ADB服务器,如果找不到ADB服务器,“adb”程序自动启动一个ADB服务器。接下来,当设备的adbd和pc端的adb server建立连接后,adb client就可以向ADB servcer发送服务请求;
        2、运行在pc端的adb server:
ADB Server是运行在主机上的一个后台进程。它的作用在于检测USB端口感知设备的连接和拔除,以及模拟器实例的启动或停止,ADB Server还需要将adb client的请求通过usb或者tcp的方式发送到对应的adbd上;
        3、运行在设备端的常驻进程adb demon:
程序“adbd”作为一个后台进程在Android设备或模拟器系统中运行。它的作用是连接ADB服务器,并且为运行在主机上的客户端提供一些服务;

  }

    Android Monitor是Android Studio自带的一个强大的性能分析工具,里面一共包含5个模块:Logcat、Memory、CPU、Network、GPU

    }

小伙伴们注意了,在面试的时候千万不能按照上面的逐条背,否则你会被认为为是毕业生的水准,要用一种比较随意、脱口而出的语态来介绍。 
例如以下的表达方式:关于内存泄漏,一般像单例模式的使用不当啊、集合的操作不当啊、资源的缺乏有效的回收机制啊、Handler、线程的使用不当等等都有可能引发内存泄漏。 
这时,面试官就会抽查里面他所感兴趣的知识点,当然,既然你懂,你就牵着他走了,你把原因和解决方案都给他说一下,直击其内心,通过一两个问题,你已经在他内心深处建立了良好的形象,自然接下来他就不会刻意刁难你了。

当然,这里只是为了应付与面试官的沟通提供一种思路,至于详细的知识点需要各位同学对思维导图里的知识点查阅专家博客等相关资料逐个击破,只有做到心中有剑,才能做到斩杀面试官于无形。 

UI优化

Hierarchy Viewer 可以看到View的布局层次,以及每个View刷新加载的时间。

1.Android系统每隔16ms发出VSYNC信号,触发对UI进行渲染,如果每次渲染都成功,这样就能够达到流畅的画面所需要的60fps,为了能够实现60fps,这意味着程序的大多数操作都必须在16ms内完成。Android性能优化典范(胡凯译)。
在此,我们需要明白一个概念。如果一次UI渲染不能在16ms内完成,那么将会出现丢帧的现象,从而产生卡顿。譬如,ListView的item布局很复杂,当滑动ListView时,就可能发生卡顿的情况。

2.Overdraw(过度绘制)描述的是屏幕上的某个像素在同一帧的时间内被绘制了多次。在多层次的UI结构里面,如果不可见的UI也在做绘制的操作,这就会导致某些像素区域被绘制了多次。这就浪费大量的CPU以及GPU资源。

其实在系统中还有一个Z轴的概念。由WindowManagerService来控制View在Z轴的位置,Z轴“位置高”的View显示在“位置低”的View之上。如果某一个像素点有很多View都“路过”,那么就会导致过度绘制的发生。

ui优化方案

1.减少布局 层次

2.减少过度绘制

1.merge标签的使用。

使用merge可以减少不必要的层级。

2.ViewStub标签的使用

ViewStub标签使我们很少使用,但又是很重要的一个标签,该标签的作用是用于懒加载布局,当系统碰到ViewStub标签的时候是不进行任何处理(measure、layout等),比设置View隐藏、不可见更高效。当我们真正需要显示某一个布局的时候才去渲染。

3.include标签

重用布局 壁面重复加载

4.自定义控件

当布局比较复杂是可以自定义控件

5.使用手机系统调试自带的调试工具 解决 overdraw问题

Bitmap

加载方式

Bitmap decodeFile(...)
Bitmap decodeResource(...)
Bitmap decodeByteArray(...)
Bitmap decodeStream(...)

Bitmap decodeFileDescriptor(...)

Bitmap的优化策略
经过上面的分析,我们可以得出Bitmap优化的思路: 
1、BitmapConfig的配置 
2、使用decodeFile、decodeResource、decodeStream进行解析Bitmap时,配置inDensity和inTargetDensity,两者应该相等,值可以等于屏幕像素密度*0.75f 
3、使用inJustDecodeBounds预判断Bitmap的大小及使用inSampleSize进行压缩 
4、对Density>240的设备进行Bitmap的适配(缩放Density) 
5、2.3版本inNativeAlloc的使用 
6、4.4以下版本inPurgeable、inInputShareable的使用 
7、Bitmap的回收
所以我们根据以上的思路,我们将Bitmap优化的策略总结为以下3种: 
1.对图片质量进行压缩   只是压缩存储控件但不改变原图
2.对图片尺寸进行压缩   改变原图
3.使用libjpeg.so库进行压缩

Bitmap格式

ALPHA_8 
表示8位Alpha位图,即A=8,一个像素点占用1个字节,它没有颜色,只有透明度 
ARGB_4444 
表示16位ARGB位图,即A=4,R=4,G=4,B=4,一个像素点占4+4+4+4=16位,2个字节 
ARGB_8888 
表示32位ARGB位图,即A=8,R=8,G=8,B=8,一个像素点占8+8+8+8=32位,4个字节 
RGB_565 
表示16位RGB位图,即R=5,G=6,B=5,它没有透明度,一个像素点占5+6+5=16位,2个字节

多图加载

内存缓存技术对那些大量占用应用程序宝贵内存的图片提供了快速访问的方法。其中最核心的类是LruCache (此类在android-support-v4的包中提供) 。这个类非常适合用来缓存图片,它的主要算法原理是把最近使用的对象用强引用存储在 LinkedHashMap 中,并且把最近最少使用的对象在缓存值达到预设定值之前从内存中移除。

当向 ImageView 中加载一张图片时,首先会在 LruCache 的缓存中进行检查。如果找到了相应的键值,则会立刻更新ImageView ,否则开启一个后台线程来加载这张图片。

https://blog.csdn.net/u012426327/article/details/78088104


你可能感兴趣的:(Java学习笔记,Android学习笔记)