Android中的几种内存泄露情况总结
来源:互联网 发布:达德网络 编辑:程序博客网 时间:2024/05/17 01:21
Handler使用不当导致的内存泄露(用这个来作为非静态内部类造成内存泄露的代表)
这种情况比较常见,经典的例子如下所示:
import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.widget.ImageView;import java.io.IOException;import java.io.InputStream;import java.net.MalformedURLException;import java.net.URL;import java.net.URLConnection;public class MainActivity extends AppCompatActivity { private ImageView mImageView; Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (msg.what == 1) { mImageView.setImageBitmap((Bitmap) msg.obj); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mImageView = (ImageView) findViewById(R.id.imageView); new Thread(new Runnable() { @Override public void run() { Bitmap bitmap = null; try { URL url = new URL("http://img0.imgtn.bdimg.com/it/u=3527986333,3942718311&fm=21&gp=0.jpg"); URLConnection urlConnection = url.openConnection(); InputStream inputStream = urlConnection.getInputStream(); bitmap = BitmapFactory.decodeStream(inputStream); } catch (IOException e) { e.printStackTrace(); } Message message = new Message(); message.what = 1; message.obj = bitmap; handler.sendMessage(message); } }).start(); }}
开了个线程从网络中获取资源(我这里下了张图片),下完了,通过Handler发个消息回UI线程,然后在handleMessage方法中更新UI。当然,犯这种错误,Android Studio马上会提醒,Handler那一块代码会有一块阴影,鼠标光标点在哪,左下角也会出现提示:
This Handler class should be static or leaks might occur (null)
处理方式嘛,提示信息也说了,要把Handler应该声明为静态类,否则内存泄露,因为在Java中非静态内部类会持有外部类的引用,而那个网络请求的线程又持有Handler的引用,所以假如此时用户按了返回键,这个Activity占用的内存本来应该可以被回收的,可是现在却不行了,于是发生了内存泄露。
解决方法,仅仅加static是不够的,因为这样Handler类没有了外部类的引用,那么也就没法更新UI了,所以完整的解决方法如下所示:
static class MyHandler extends Handler { WeakReference<MainActivity> mWeakReference; MyHandler(MainActivity mainActivity) { mWeakReference = new WeakReference<>(mainActivity); } @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (mWeakReference.get() != null) { if (msg.what == 1) { mWeakReference.get().mImageView.setImageBitmap((Bitmap) msg.obj); } } }}
这样的话,Handler持有的是MainActivity的弱引用,当Activity被销毁,GC需要回收内存的时候便可以顺利回收。
静态变量导致的内存泄露
我们知道在Java中静态变量的生命周期起始于类的加载,终止于类的释放(不过好像在哪看到Android中静态变量好像比较不稳定,不知道什么时候就会被置空的,有时间去求证下),不过不管怎么样,让一个静态变量持有Activity引用,肯定不是一个好的选择。所以可以看到在上面的例子中,虽然我们可以将ImageView设为static来在static class中进行更新,但我们并没有这样做。
今天先写到这,下次接着写。。。。
0 0
- Android中的几种内存泄露情况总结
- Android内存泄露情况总结
- iOS ARC内存泄露的几种情况总结
- js内存泄露的几种情况
- 内存泄露的几种情况
- 内存泄露的几种情况
- js内存泄露的几种情况
- js内存泄露的几种情况
- C++ 内存泄露的几种情况
- java中的内存泄露情况
- js内存泄露的几种情况详细探讨
- js内存泄露的几种情况详细探讨
- js内存泄露的几种情况详细探讨
- ARC下导致内存泄露的几种情况
- js内存泄露的几种情况详细探讨
- android内存泄露的情况
- Android内存泄露的情况
- android 分析内存泄露情况
- Spring Boot 菜鸟教程 23 站点地图sitemap.xml
- div style常用属性介绍及使用示例
- myeclipse2015修改web项目部署名
- 数据存储:从pickle到sqlite 《Head First Python》第九章
- oj-1-蛇形填数
- Android中的几种内存泄露情况总结
- ViewPager+Fragment
- 1029. Median (25)
- myblog 目录
- 有放回抽签求和解法的层层优化
- hello world
- 【Maven】项目打包-war包-Jar包[IDEA将项目打成war包]
- 飞行员配对方案问题 洛谷2756 网络流
- 设计模式-适配器模式