Handler写法不当导致的内存泄漏

有强迫症的猿看到这个警告就会感觉别扭,那么这个This Handler class should be static or leaks might occur到底是啥意思呢,为什么会有警告呢?下面就给大家解释一下:在Java中,非静态(non-static)内部和匿名类将会持有外部类的引用。相反,静态的内部类不会持有外部类的引用,而上面的这个明显是匿名内部类,如果Handler位于主线程,则使用的是主线程的Looper和MessageQueue,那么每一个Message的target就是这个Handler,持有这个Handler的引用,假设这个时候GC要回收当前的Activity或者Service,但是由于Message太多处理不过来,或者Message延迟过大导致等待,那么这个Handler则不会被回收,因为它被Message引用,而同时我们的Handler又是个内部类,持有外部Activity或者Service的引用,而且又不是static的,那么外部Activity或者Service也不会被回收,所以就释放不了啦,泄露啦。 使用弱引用之后,Handler和外部的Activity或者Service的引用性变低,就好像以前用钢丝绳困在一起的,现在换棉线了,GC的时候就一定会回收掉弱引用包装的对象。修改方法如下:

class MusicPlayerHandler extends Handler{
		private WeakReference<SnsMusicDetailActivity> mWeakReference;

		public MusicPlayerHandler(SnsMusicDetailActivity reference) {
			mWeakReference = new WeakReference<SnsMusicDetailActivity>(reference);
		}

		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			SnsMusicDetailActivity reference = mWeakReference.get();
			if (reference == null) { // the referenced object has been cleared
				return;
			}
			switch (msg.what){
				case MusicPlayerTimer.MSG_WHAT_MUSIC_PLAYER_TIMER:
					if (!isPlay){
						SnsMusicDetailActivity.this.play_progress_time.setText("00:00");
						SnsMusicDetailActivity.this.detail_play_progress.setProgress(0);
						return;
					}
					long currentTime = (long) msg.obj;
					int progress = (int) (100*currentTime/mAllPlayTime);
					//进度条进度
					SnsMusicDetailActivity.this.detail_play_progress.setProgress(progress);
					//时间进度
					long  progressTime = currentTime/1000;
					int hour= (int) (progressTime/3600);
					int min= (int) ((progressTime%3600)/60);
					int sec= (int) ((progressTime%3600)%60);
					String minute =min>9?""+min:"0"+min;
					String second =sec>9?""+sec:"0"+sec;
					if (hour==0){
						SnsMusicDetailActivity.this.play_progress_time.setText(minute+":"+second);
					}else {
						String hourTime =hour>9?""+hour:"0"+hour;
						SnsMusicDetailActivity.this.play_progress_time.setText(hourTime+":"+minute+":"+second);
					}
					break;
			}
		}
	}

对于MusicPlayerHandler的创建也简单,只要把当前Activity穿进去就行,例如:

MusicPlayerHandler mHandler =new MusicPlayerHandler(SnsMusicDetailActivity.this);

猜你喜欢

转载自blog.csdn.net/qq_14931305/article/details/81539935