前几天在修复电池项目内存泄漏的地方学到了一个新的知识点.
私有内部类(匿名的私有内部类也算)中会有一个外部类的引用,那么当内部类对象没有被销毁,外部类也不会被销毁,这一点很容易忽略从而造成内存泄漏.
代码如下:这样的匿名内部类使用会导致OutOfMemActivity的内存泄漏
public class OutOfMemActivity extends Activity implements View.OnClickListener{
public static final String ACTION_INTENT_FILTER = "ACTION_INTENT_FILTER";
private Button btn;
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
new Thread(){
@Override
public void run() {
super.run();
while (true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i("tag","running ... "+OutOfMemActivity.this);
}
}
}.start();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_out_of_mem);
btn = (Button)findViewById(R.id.btn_send);
btn.setOnClickListener(this);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ACTION_INTENT_FILTER);
registerReceiver(broadcastReceiver,intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(broadcastReceiver);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_send:
Intent intent = new Intent();
intent.setAction(ACTION_INTENT_FILTER);
sendBroadcast(intent);
break;
}
}
}
我们可用通过弱引用解决该问题(关于强引用,软引用,弱引用,虚引用传送门https://my.oschina.net/ydsakyclguozi/blog/404389),我们改写这个广播接收器使它成为静态内部类如下:
private static class MyBroadcastReceiver extends BroadcastReceiver{
private WeakReference<OutOfMemActivity> outOfMemActivityWeakReference;
public MyBroadcastReceiver(WeakReference<OutOfMemActivity> outOfMemActivityWeakReference) {
this.outOfMemActivityWeakReference = outOfMemActivityWeakReference;
}
@Override
public void onReceive(Context context, Intent intent) {
new Thread(){
@Override
public void run() {
super.run();
while (true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
OutOfMemActivity outOfMemActivity = outOfMemActivityWeakReference.get();
Log.i("tag","running ... "+outOfMemActivity);
}
}
}.start();
}
}
这样如果使用OutOfMemActivity对象,它是以弱引用传送进来,在垃圾回收器扫描到该对象的时候就会回收掉它.
网友评论