上一節(jié)我們介紹了關(guān)于匿名內(nèi)部類的內(nèi)存泄漏端姚,這一節(jié)我們來看一下單例產(chǎn)生內(nèi)存泄漏的情況
知識點
單例的生命周期和應(yīng)用(Application)的生命周期一樣長
案例
我們先來看一段代碼
public class GlobalManager {
private volatile static GlobalManager instance;
private Context mContext;
private GlobalManager(Context context) {
this.mContext = context;
}
public static GlobalManager getInstance(Context context) {
if (instance == null) {
synchronized (GlobalManager.class) {
if (instance == null) {
instance = new GlobalManager(context);
}
}
}
return instance;
}
}
這段代碼中涩嚣,單例的生命周期和Application是一樣的。
我們看看activity的使用:
public class TestAct extends AppCompatActivity {
private static GlobalManager globalManager = null;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_test);
if (globalManager == null) {
globalManager = GlobalManager.getInstance(this);
}
}
}
我們來分析一下這段代碼:
globalManager = GlobalManager.getInstance(this)铲咨,這里傳入的是Activity的Context玄妈,當(dāng)此Activity退出時茬暇,Activity應(yīng)該被回收霹期,可是這個單例持有這個activity的強引用谆棱,導(dǎo)致回收失敗,所以造成內(nèi)存泄漏圆仔。
解決方法
我們不管傳入的是Context還是ApplicationContext垃瞧,我們都將它轉(zhuǎn)換為ApplicationContext,這樣這個單例就不會持有Activity或其他Context的強引用了坪郭。單例代碼修改如下
public class GlobalManager {
private volatile static GlobalManager instance;
private Context mContext;
private GlobalManager(Context context) {
this.mContext = context.getApplicationContext();
}
public static GlobalManager getInstance(Context context) {
if (instance == null) {
synchronized (GlobalManager.class) {
if (instance == null) {
instance = new GlobalManager(context);
}
}
}
return instance;
}
}
只是修改了構(gòu)造方法:講this.mContext = context;
改成了this.mContext = context.getApplicationContext();
个从,不管傳入什么Context最終將使用Application的Context
ok,單例的內(nèi)存泄漏情況我們就介紹這么多歪沃,下一節(jié)介紹非靜態(tài)內(nèi)部類作為靜態(tài)變量造成的內(nèi)存泄漏情況嗦锐。
上一節(jié):Android內(nèi)存泄漏(二):匿名類
下一節(jié):Android內(nèi)存泄漏(四):非靜態(tài)內(nèi)部類作為靜態(tài)變量