context 和 INSTANCE 静态声明的内存泄漏,我该如何改变它?
Memory leak for static declaration of context and INSTANCE , how do I alter it?
目前在我的代码库中,我有以下 class(部分),它向我显示了 2 条内存泄漏消息“不要将 Android 上下文 classes 放入静态字段(对 Myclass 的静态引用,其中字段上下文指向 Context);这是内存泄漏(并且还会破坏 Instant 运行)”
我不确定替代方案是什么。这是 100% 的内存泄漏吗?我在上下文的 "INSTANCE;" 和 "static" 声明中收到泄漏警告。知道如何解决它吗?
public enum Myclass {
INSTANCE;
public static final boolean TLS_ENABLED = true;
private static final String TAG = Myclass.class.getSimpleName();
private static final String SP = "My_class";
private static Context context;
public void init(Context context, String appKey, String appSecret) {
init(context, null, appKey, appSecret);
}
/**
* Initialize class
*
* @param context Application level context.
* @param apiUrl API url of backend server
* @param appKey Application key
* @param appSecret Application secret
* @throws IllegalArgumentException If activity instance will be passed as the context
* @throws IllegalArgumentException If application key is empty or null
* @throws IllegalArgumentException If application secret is empty or null
*/
public void init(Context context, String apiUrl, String appKey, String appSecret) {
if (null == context) { throw new NullPointerException(); }
if (!(context instanceof Application)) { throw new IllegalArgumentException("Supply my class with application context"); }
// if (TextUtils.isEmpty(apiUrl)) { throw new IllegalArgumentException("Api url can't be null or empty string"); }
if (TextUtils.isEmpty(appKey)) { throw new IllegalArgumentException("App key can't be null or empty string"); }
if (TextUtils.isEmpty(appSecret)) { throw new IllegalArgumentException("App secret can't be null or empty string"); }
this.apiUrl = apiUrl;
this.appKey = appKey;
this.appSecret = appSecret;
this.sp = context.getSharedPreferences(SP, Context.MODE_PRIVATE);
MyClass.context = context;
initManagers();
}
/**
* Initializes managers. This method must be called after constructor
* returns, as the managers during own initialization may use myclass.get()
* method.
*/
private void initManagers() {
accountManager = new AccountManager();
myclassApi = new MyclassApi(context, apiUrl);
contactManager = new ContactManager();
connectionManager = new ConnectionManager();
meetingListManager = new MeetingListManager();
}
/**
* Returns {@link Context} that was passed to
* {@link myclass#init(Context, String, String)}.
*
* @return
*/
public static Context getContext() {
return context;
}
/**
* Returns {@link SharedPreferences} instance.
*
* @return SharedPreferences
*/
public SharedPreferences getSp() {
return this.sp;
}
public static class Event<T> {
private State state = State.SUCCESS;
private Throwable t;
private T data;
private String errorMessage;
/**
* Event state. If event related to network request/response
* operations - state indicates the physical (not logical)
* success or fail of request.
*/
public enum State {
/**
* Indicates that attempt to get data or perform task successful
*/
SUCCESS,
/**
* Indicates that attempt to get data or perform task fails,
* and reason of fail is the incorrect request data
*/
FAIL,
/**
* Indicates that attempt to get data or perform task encounter an error
* mostly due to connection problem
*/
ERROR,
/**
* Indicates that attempt to get data or perform task was ignored
* according to internal state of event producer.
*/
IGNORED
}
}
将应用程序上下文存储在静态字段中是安全的,您可以在将其存储在静态字段中之前对获得的任何上下文引用简单地调用context.getApplicationContext()
。
应用程序上下文无论如何都是单例的,你不能泄漏它。
这似乎是来自 IDE 的警告,如果您确保上下文将仅存储 ApplicationContext,而不是 Activity 上下文,您可以使用注释抑制此警告。
@SuppressLint("StaticFieldLeak")
如果您想了解更多关于内存泄漏的信息,可以查看我唯一的博客:) here
目前在我的代码库中,我有以下 class(部分),它向我显示了 2 条内存泄漏消息“不要将 Android 上下文 classes 放入静态字段(对 Myclass 的静态引用,其中字段上下文指向 Context);这是内存泄漏(并且还会破坏 Instant 运行)” 我不确定替代方案是什么。这是 100% 的内存泄漏吗?我在上下文的 "INSTANCE;" 和 "static" 声明中收到泄漏警告。知道如何解决它吗?
public enum Myclass {
INSTANCE;
public static final boolean TLS_ENABLED = true;
private static final String TAG = Myclass.class.getSimpleName();
private static final String SP = "My_class";
private static Context context;
public void init(Context context, String appKey, String appSecret) {
init(context, null, appKey, appSecret);
}
/**
* Initialize class
*
* @param context Application level context.
* @param apiUrl API url of backend server
* @param appKey Application key
* @param appSecret Application secret
* @throws IllegalArgumentException If activity instance will be passed as the context
* @throws IllegalArgumentException If application key is empty or null
* @throws IllegalArgumentException If application secret is empty or null
*/
public void init(Context context, String apiUrl, String appKey, String appSecret) {
if (null == context) { throw new NullPointerException(); }
if (!(context instanceof Application)) { throw new IllegalArgumentException("Supply my class with application context"); }
// if (TextUtils.isEmpty(apiUrl)) { throw new IllegalArgumentException("Api url can't be null or empty string"); }
if (TextUtils.isEmpty(appKey)) { throw new IllegalArgumentException("App key can't be null or empty string"); }
if (TextUtils.isEmpty(appSecret)) { throw new IllegalArgumentException("App secret can't be null or empty string"); }
this.apiUrl = apiUrl;
this.appKey = appKey;
this.appSecret = appSecret;
this.sp = context.getSharedPreferences(SP, Context.MODE_PRIVATE);
MyClass.context = context;
initManagers();
}
/**
* Initializes managers. This method must be called after constructor
* returns, as the managers during own initialization may use myclass.get()
* method.
*/
private void initManagers() {
accountManager = new AccountManager();
myclassApi = new MyclassApi(context, apiUrl);
contactManager = new ContactManager();
connectionManager = new ConnectionManager();
meetingListManager = new MeetingListManager();
}
/**
* Returns {@link Context} that was passed to
* {@link myclass#init(Context, String, String)}.
*
* @return
*/
public static Context getContext() {
return context;
}
/**
* Returns {@link SharedPreferences} instance.
*
* @return SharedPreferences
*/
public SharedPreferences getSp() {
return this.sp;
}
public static class Event<T> {
private State state = State.SUCCESS;
private Throwable t;
private T data;
private String errorMessage;
/**
* Event state. If event related to network request/response
* operations - state indicates the physical (not logical)
* success or fail of request.
*/
public enum State {
/**
* Indicates that attempt to get data or perform task successful
*/
SUCCESS,
/**
* Indicates that attempt to get data or perform task fails,
* and reason of fail is the incorrect request data
*/
FAIL,
/**
* Indicates that attempt to get data or perform task encounter an error
* mostly due to connection problem
*/
ERROR,
/**
* Indicates that attempt to get data or perform task was ignored
* according to internal state of event producer.
*/
IGNORED
}
}
将应用程序上下文存储在静态字段中是安全的,您可以在将其存储在静态字段中之前对获得的任何上下文引用简单地调用context.getApplicationContext()
。
应用程序上下文无论如何都是单例的,你不能泄漏它。
这似乎是来自 IDE 的警告,如果您确保上下文将仅存储 ApplicationContext,而不是 Activity 上下文,您可以使用注释抑制此警告。
@SuppressLint("StaticFieldLeak")
如果您想了解更多关于内存泄漏的信息,可以查看我唯一的博客:) here