静态声明上下文和INSTANCE的内存泄漏,我该如何改变它?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了静态声明上下文和INSTANCE的内存泄漏,我该如何改变它?相关的知识,希望对你有一定的参考价值。

目前在我的代码库中我有以下类(部分内容),它显示了2个内存泄漏,消息“不要将android上下文类放在静态字段中(静态引用Myclass,其中字段上下文指向Context);这是内存泄漏(也打破了Instant Run)“我不确定替代方案是什么。这是100%的内存泄漏吗?我在“INSTANCE”上收到泄漏警告和上下文的“静态”声明。知道怎么去修理吗?

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

以上是关于静态声明上下文和INSTANCE的内存泄漏,我该如何改变它?的主要内容,如果未能解决你的问题,请参考以下文章

Android:静态字段和内存泄漏

gcc/linux:CppuTest 使用静态向量显示内存泄漏,误报?

将上下文从 Activity 传递到静态类是不是会永久保留该 Activity?内存泄漏?

此Loader类应该是静态的,否则可能会发生泄漏内部类内存泄漏| AsyncTaskLoader内存泄漏 -

Kotlin伴侣对象中的内存泄漏?

内存泄漏和内存溢出