Static Context Warning

2019-09-09 22:18发布

问题:

Android Studio now displays a warning when a class contains a static Context object. It says this causes a memory leak. However, I have noticed this is also done in android libraries. For instance, the LocalBroacastManager class has a static instance and it contains a context object.

So how bad is this as a memory leak?

I have a singleton geofencing class that runs in the background and saves a boolean to sharedPreferences indicating if the user is in the geofence or not. To save the preferences I need a context object, but since the method is an overridden method, I have no way of passing a context object in.

How can this be accomplished without a context instance variable?

回答1:

Its about the worst you can have. Lets say that you have an Activity, and store that as a static Context. Unless you null it out when the activity finishes, you now have leaked a whole Activity. That means every variable that the activity holds is leaked, including the entire view hierarchy. Its basically preventing anything in that Context from freeing up.

The best thing to do is not to store a Context, but instead to pass it in as a parameter to functions that need it. If you must store a Context, do not make it static. A non-static variable won't leak it so long as nothing in the framework continues to hold a reference to the object after the activity is finished.

If you absolutely must use a static Context, make it the Application context. That one is valid over the length of your app, so it can't really be leaked.



回答2:

Statics should be rarely used, especially in Android. There are ways and reasons of using statics, but in 90% of cases, it is just a misuse of them.

Keeping the context as a static variable is a big no-no. Imagine following scenario:

  1. You go from activity A to activity B.
  2. While in activity B you keep activity B reference as static Context somewhere.
  3. You go back to activity A. Activity B should be destroyed, but instead it is kept, since you keep a static reference to it.
  4. Now you go again to B from A, et voila - you have two B instances: the one you see and another one kept as static context.

You may NEVER have two instances of the same activity. It could cause a lot of issues.

Now, I'm aware that a lot of developers (even ones making libraries) every now and then make mistakes and use anti-patterns, so you should not blindly rely on practice/pattern seen in someone other's code. Hell, I've even seen a lot of garbage code in something written by Google devs.

If you really need a singleton (not Singleton pattern (uppercase S)), but single instance of some class, if you don't want to use libraries like Dagger and so, you can instantiate that class in your Application class, and then reference it from wherever you want.