• Android学习-Handler内存泄漏


    2016/08/20

    最近轻微强迫症又犯了,看着编译器上的那些带有黄色感叹号警告就十分难受,于是就下定决心清除我能看到的所有黄色感叹号,一般我不会用像图1中系统提示那些处理方法,


    我觉得那是在欺骗自己,可能在处理这些警告上有些费时,但是不管怎样,自己开心就好,得意.前几天在写一个线程实例的时候

    用到了Handler 来传递数据,我之前都是像图2那样写的,图2上已然出现了一个傲娇的黄色感叹号,警告的内容是 This Handler class should be static or leaks might occur (com.example.ndktest.MainActivity.1) 我把我那蹩脚英语能力和有道词典有机统一的结合之后,笼统的明白的这句话的意思是:这个Handler 类应该是静态的,否则可能引起内存泄漏问题,在我颇有成就感的品味被我翻译出来的译文的同时,我又开始蒙圈了,到底是什么原因出现这样奇葩的警告呢,我之前都是这么写的,从来都没有出现过内存泄漏的现象,那这个发生内存泄漏的概率岂不是很低,知其然而不知其所以然,苦恼数微秒之后,我就打开了浏览器,开始刨根问底,许久之后有了些收货.先附上我的测试代码

    public class MainActivity extends Activity {
    
    	public TextView tv;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		tv = (TextView) findViewById(R.id.tv);
    	}
    
    	Handler handler = new Handler() {
    
    		public void handleMessage(android.os.Message msg) {
    
    			tv.setText("我收到了message");
    
    		};
    	};
    }


    根据代码可以看出 handler 是一个内部类,内部类分两种,一种是普通内部类,也就是像上面代码里handler这个类那样,另一种是加static关键字的静态内部类,就是那段警告所说的改正后的类的类型.普通内部类隐含保存了外部类的引用,静态内部类就不是这样了,静态内部类只能访问外部类的静态成员.那这跟内存泄漏有什么关系呢,其实思考到这里,答案就已经很明朗了,关键点就在于普通内部类隐含保存了外部类的引用,如果我在上面代码的oncreate函数里添加finish()方法之后,在运行到finish()后,本应该进行对MainActivity 垃圾回收的,但是由于handler内部类有对MainActivity  的引用,所以是MainActivity 对象是不会被回收的,这就造成了内存的泄漏.要解决这样的问题,就要用到弱引用,在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,就会回收它的内存,不会考虑内存的充足与否。这样就解决了内存泄漏问题

    改后的代码

    public class MainActivity extends Activity {
    
    	public TextView tv;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		tv = (TextView) findViewById(R.id.tv);
    	}
    
    	// Handler handler = new Handler() {
    	//
    	// public void handleMessage(android.os.Message msg) {
    	//
    	// tv.setText("我收到了message");
    	//
    	// };
    	// };
    
    	MyHandler handler = new MyHandler(this);
    
    	static class MyHandler extends Handler {
    		WeakReference<MainActivity> mActivity;
    
    		public MyHandler(MainActivity activity) {
    
    			mActivity = new WeakReference<MainActivity>(activity);
    		}
    
    		@Override
    		public void handleMessage(Message msg) {
    			// TODO Auto-generated method stub
    			super.handleMessage(msg);
    			MainActivity a = mActivity.get();
    
    			if (a != null) {
    				a.tv.setText("我收到了message");
    			}
    
    		}
    
    	}
    
    }
    





  • 相关阅读:
    十五行Python代码实现批量下载好看的视频,嘎嘎好看
    利用PYTHON实现科学占卜
    如何开发一个分布式内存数据库(一)
    AE中的线符号渲染
    AE中的面符号(填充符号)渲染
    Excel批量转Word
    AE中的点符号渲染
    搭建nuget服务器(三):使用nuget下载制作的package
    搭建nuget服务器(二):制作package
    搭建nuget服务器(一):搭建nuget应用服务
  • 原文地址:https://www.cnblogs.com/WK-can-do-anything/p/5792221.html
Copyright © 2020-2023  润新知