public class MyClass {
private static MyClass instance = null;
private MyActivity myActivity;
private Button button;
public static MyClass getInstance(){
if (instance == null){
instance = new MyClass();
}
return instance;
}
private MyClass(){};
public void initialize(MyActivity activity){
myActivity = activity;
}
public void releaseMemory(){
instance = null;
}
}
当我的应用程序退出时,这种方法就在这里 我可以通过调用releaseMemory()来释放内存,以便myActivity 实例不会泄露。
public class MyClass {
private static final MyClass instance = new MyClass();
private MyActivity myActivity;
private Button button;
private MyClass(){};
public void initialize(MyActivity activity){
myActivity = activity;
}
public void releaseMemory(){
instance = null; //Can't make it null
//Can do for individual variables
myActivity = null;
button = null;
}
}
在这种方法中,MyClass实例是final,我不能使它为null 相反,我可以将单个变量设为null。
我的理解是正确的还是我错过了与内存泄漏相关的任何内容?
答案 0 :(得分:0)
第一个问题,为什么需要在Activity
对象上保留引用?
对于大多数用法,您只需要一个Context
对象。因此,如果您想避免泄露您的Activity
,请习惯通过更换以下内容来执行以下操作:
private MyActivity myActivity;
public void initialize(MyActivity activity){
myAcitivity = activity;
}
with:
private Context myContext;
public void initialize(Context context){
myContext = context.getApplicationContext();
}
由于Activity是Context的一个实现,因此您的代码应该继续工作。方法getApplicationContext()
将始终返回一个应用程序上下文,您可以泄漏所有内容。
现在,如果应用程序上下文不够,并且您确实需要一个Activity对象(如果您需要启动其他Activity而不为exemple创建新任务),请首先问问自己为什么不能直接在Activity类中执行此操作。如果你做不到,那么也许你对你的代码架构做出了错误的决定。
如果您确实需要将Activity
对象存储在其他对象(单身或非单身)中,请记住活动有生命周期,您需要Activity
通知您的MyClass
它将不再可用(如果你没有,你忘记调用releaseMemory(),那么你的Activity
将在它转到后台时泄漏):
public class MyActivity {
MyClass myClass; // instance initialize somewhere in your code
onPause() {
myClass.setActivity(this);
}
onResume() {
myClass.setActivity(null);
}
}
public class MyClass {
@Nullable Activity myActivity; // tha @Nullable annotation helps you remember to do null checks before using this field.
public void setActivity(Activity activity) {
myActivity = activity;
}
}
如果您的MyClass
也是Fragment
,您可以在方法Activity
和onAttach()
中设置和发布onDetach()
(这些方法是由Android自动调用的,因此您无需尝试在Activity
中调用它们。
最后,我建议不要使用您的第一个代码示例,因为即使您调用方法releaseMemory()
并确保您的对象A
中没有任何引用,您也无法确保对象B
仍然没有对您的班级MyClass
的引用。
答案 1 :(得分:0)
最终字段无法修改。这就是最终修饰符存在的原因。
你的单身的第二个版本在conccurency方面更好。但在关闭应用程序之前,它永远不会被gc'ed。