Question

Over the development of an Android app I've come to a collection of utility-type methods that I have put into a static class. All these methods are used across multiple Activities and most of them do not require any information from the calling Activity.

However, I now have some methods that require the Context of the Activity and one that requires the Activity itself. Let me exemplify some of them:

  • getDeviceNaturalOrientation() - Uses an Activity's getWindow().getWindowManager().getDefaultDisplay() to access the displays rotation, width, and height to determine the device's natural orientation.
  • getDeviceOrientation() - Similar to the above but to get the current orientation
  • createFile() - Uses the Context to to access some resources (strings) and to create and show some Toasts

Now, my big questions regarding this Utils class are:

  1. So far, each function takes a Context parameter which I pass from whatever Activity I'm on, but would it be OK to create a static Context or Activity variable in the Utils class and set it at the beginning of each Activity (like in onCreate)? This variable would be used in whatever functions require a Context or Activity instance.
  2. Assuming the above is not recommended, is it OK to pass an Activity parameter to a method or is there a reason to only pass an Activity as Context? The methods I use for the device orientation functions above are specific to Activity objects, not Context, so either I pass as Activity or pass as Context and cast into Activity (the latter sounding like a terrible idea).

Also, I am very open to the idea that this Util class may not be the way to go for these methods that require Context/Activity, so I would welcome alternatives that would still prevent having copies of these methods in each activity class that uses them.

Was it helpful?

Solution

1)A static link to a context is likely to cause a memory leak. It means that a reference to the Activity will be kept around in the static variable even after its destroyed, so all of the memory of the activity and all its views will remain valid and not be cleaned by gc. You can do this, but you have to be careful to null out the variable when done. Its better just to avoid it.

2)Its a little bit awkward to pass the activity as an Activity, but no technical reason not to. At that point we're arguing over code cleanliness/maintainability. And there are times where the non-clean solution is just easier. Of course in the cases above I'd rather pass the orientation/display/Resources objects to the function than pass the entire context or make special accessors.

OTHER TIPS

I think following design should be fine when you call from Activity

MyUtility utility=new MyUtility();
utility.getDeviceNaturalOrientation(this);
utility.getFile(this);

And you can define these function like

public int getDeviceNaturalOrientation(Activity activity){
 //code
return some_oreientation
}

and like this

public File getFile(Context context){
 //code
//return file handler
}

Activity is the subclass of Context so you can even change the design to following

MyUtility utility=new MyUtility(this); //this refer to Activity
utility.getDeviceNaturalOrientation();
utility.getFile();

As long as you pass activity you are fine but if you do following from your activity you will get error from first method call

MyUtility utility=new MyUtility(getApplicationContext());
utility.getDeviceNaturalOrientation(); //will throw exception
utility.getFile();

And, yes first idea is not a recommended way.

I would suggest you to send a WeakReference of your Activity or getApplicationContext() (for those works which can work using it) and don't use static method because it cause memory leaks. Read Developer blog also

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top