内存优化在安卓里是个比较重要的事情,安卓手机出厂时就已经设定应用最大可用RAM,如24M、128M、384M,具体值取决与手机厂商设定,应用在运行过程中占用内存过大超过最大限制就会造成内存溢出OOM,特别是一些加载大量图片视频的应用容易造成内存溢出影响用户体验,所以在平常开发中按规范正确的编写代码以严谨对待内存泄漏。
1.图片加载
Bitmap是个体积很大的东西,如果应用页面加载大量的图片的会对内存造成很大的占用,甚至OOM,所以Bitmap使用完之后需要释放它bitmap.recycler(),以便给其余的执行留出内存空间。
2.对象引用
如果对象的引用赋予静态变量、单例对象、常驻服务或者耗时任务会导致垃圾回收机制不能回收这个对象,从而也不会释放所占内存,还有一种是内部类对象,它持有外部类对象的强引用,如果不先释放内部类对象也会造成内存溢出,常见的如Activity里创建Handler内部类对象,如果在此handler里做耗时操作,且还没执行完时就退出Activity,如不先停止handler的任务会造成handler任务继续执行并持有外部类引用而导致垃圾回收机制不能回收Activity,还有Activity的Context不能随便传给别的别的对象,尽量用ApplicationContext。
解决方法:第一,Hanlder声明为静态类,不让其持有外部类的引用。第二,销毁Activity时结束hanldler所执行的任务。第三,在onDestroy里添加handler.removeCallbacksAndMessages(null)。
3.集合中的对象未清理造成内存泄露
这个比较好理解,如果一个对象放入到ArrayList、HashMap等集合中,这个集合就会持有该对象的引用。当我们不再需要这个对象时,也并没有将它从集合中移除,这样只要集合还在使用(而此对象已经无用了),这个对象就造成了内存泄露。并且如果集合被静态引用的话,集合里面那些没有用的对象更会造成内存泄露了。所以在使用集合时要及时将不用的对象从集合remove,或者clear集合,以避免内存泄漏。
4.资源未关闭或释放导致内存泄露
在使用IO、File流或者Sqlite、Cursor等资源时要及时关闭。这些资源在进行读写操作时通常都使用了缓冲,如果及时不关闭,这些缓冲对象就会一直被占用而得不到释放,以致发生内存泄露。因此我们在不需要使用它们的时候就及时关闭,以便缓冲能及时得到释放,从而避免内存泄露。
5.属性动画造成内存泄露
动画同样是一个耗时任务,比如在Activity中启动了属性动画(ObjectAnimator),但是在销毁的时候,没有调用cancle方法,虽然我们看不到动画了,但是这个动画依然会不断地播放下去,动画引用所在的控件,所在的控件引用Activity,这就造成Activity无法正常释放。因此同样要在Activity销毁的时候cancel掉属性动画,避免发生内存泄漏。
6.WebView造成内存泄露
关于WebView的内存泄露,因为WebView在加载网页后会长期占用内存而不能被释放,因此我们在Activity销毁后要调用它的destory()方法来销毁它以释放内存。
Webview下面的Callback持有Activity引用,造成Webview内存无法释放,即使是调用了Webview.destory()等方法都无法解决问题(Android5.1之后)。