ConnectivityManager leaking, not sure how to resolve

对着背影说爱祢 提交于 2020-02-01 04:41:06

问题


So, I have this method that let's me know if the user has an active internet connection. It works well. However, leak canary has identified a memory leak associated with the connectivityManager. I am presently not closing the connectivityManager anywhere in my code at any time that I know of.

I've tried to close the connectivityManager in onDestroy. Either that isn't an option or I don't know the code. Truth be told, I simply tried to get auto fill to tell me how to do it. No luck.

public static boolean isNetworkAvailable(Context context) {
    ConnectivityManager connectivityManager =(ConnectivityManager)  context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo =connectivityManager.getActiveNetworkInfo();
    return activeNetworkInfo !=null && activeNetworkInfo.isConnected();
}

回答1:


Use this to prevent leak,

ConnectivityManager connectivityManager = (ConnectivityManager) context.getApplicationContext()
                .getSystemService(Context.CONNECTIVITY_SERVICE);



回答2:


This is a bug on Android M and has been fixed on L.

The reason is that on M, ConnectivityManager holds the first instance as a static object.

When you get it first using an Activity Context, the static object will always have reference to your Activity. Using the Application Context will solve the problem.




回答3:


Sharing a new answer as there is a catch:

I tried fixing the bug by instantiating ConnectivityManager using the following code in my activity:

ConnectivityManager connectivityManager = (ConnectivityManager) context.getApplicationContext()
            .getSystemService(Context.CONNECTIVITY_SERVICE);

However, this did not fix the memory leak. The problem is that even before my activity is called, some dependent library might be internally using ConnectivityManager in its code which leads to static variable of context being initialized to an activity context. The trick to fix this is to instantiate ConnectivityManager in the Application class just for the sake of it (unused).

public class MyApp extends Application {
    @Override
    public void onCreate() {
         ConnectivityManager cm = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
    }
}


来源:https://stackoverflow.com/questions/41431409/connectivitymanager-leaking-not-sure-how-to-resolve

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!