0

I'm pretty new to programming for Android so if this is the wrong way to go about it anyway, feel free to comment about my bad practice.

In my App, I have different Activities that use the same values. Also, I have some classes that have static methods, used in multiple activities. For example to generate ImageViews from a "URL".

One of the values I would use in almost all of my app is this snippet: (taken from another question on SO)

getApplicationContext().getResources().getDisplayMetrics().density

This particular value for example is needed for every activity. But it's also needed for the same task. So I use a static class that has the appropriate method for that task. However, that static class does not have a "getApplicatioContext", obviously. So I would need to store the value somewhere else.

My question is, is there a designated or at least optimal or clean way to store such values and initialize them on App startup?

As I understand it, I could use the "onCreate"-Method of my launch activity and initialize some static class or something like that. However, that seems a little dirty to me. Maybe there is some "earlier" time than the launch activity's onCreate() and a better place to store the values than a custom static (or singleton) class?

halfer
  • 19,824
  • 17
  • 99
  • 186
Benjamin Basmaci
  • 2,247
  • 2
  • 25
  • 46

1 Answers1

1

It is hard to tell you exactly what the best practice is when we don't know exactly what you're trying to accomplish overall, but I have a point to make that I think is abstract enough to be relevant here.

Always use the current Context. Don't store a Context or otherwise try to "get around" having to pass a Context argument to methods.

(Of course there are always exceptions, but this is a good rule of thumb.)

In this particular case, I'd recommend creating a class with a static helper method:

public class MyUtils {

    private MyUtils() {
        throw new UnsupportedOperationException("static methods only");
    }

    public static float getDisplayDensity(Context context) {
        return context.getResources().getDisplayMetrics().density;
    }
}

And you could call it from any Activity like this:

float density = MyUtils.getDisplayDensity(this);

Or from any Fragment or View like this:

float density = MyUtils.getDisplayDensity(getContext());

Often, when people post questions about DisplayMetrics and density, what they're really trying to do is convert dp units to px units. For example, they know they want something to be 48dp, but they need to pass a pixel value to some Android method, so they want to multiply by the display density.

In these cases, you're better off using dimen resources. You can define:

<dimen name="my_dimension">48dp</dimen>

And then you can get that in px units easily by calling

getResources().getDimensionPixelSize(R.dimen.my_dimension);
Ben P.
  • 52,661
  • 6
  • 95
  • 123
  • THanks for that answer! However, I have one more followup question. Things like density are different from device to device, right? How exactly is a staticly declared "dimen" going to help here? – Benjamin Basmaci Jan 03 '19 at 18:05
  • `dp` units are "density-independent pixels"; 48 dp should be _approximately_ the same real-world size (a little less than one centimeter) on every device, but will correspond to a different number of physical pixels depending on the density of the display. If the density is mdpi, 48dp == 48px. If the density is xhdpi, 48dp == 96px. When you use the resources framework with dimens resources, this conversion is done automatically for you based on the current device. – Ben P. Jan 03 '19 at 18:34
  • Very cool! Thanks! Is there a way, other than trail and error, to see the size dimension, for example 48dp, within android studio without building in some control on my action to test it? – Benjamin Basmaci Jan 04 '19 at 12:26