Android static variables are lost

2019-02-24 23:29发布

问题:

I am using a class with only static variables to store all constants and run-time properties. But, recently I have seen instances when I'm referencing these variables, I get null.

Following is my class definition:

public class PlayerProperties {

    // Runtime but constant properties
    public static int screenHeight;
    public static int screenWidth;
    public static String androidId;

    // Static properties

    // Urls
    public static final String baseUrl = "http://www.blynq.in/api/player/";

    public static final String registerUrlAppender = "activationKeyValid";
    public static final String schedulesUrlAppender = "getScreenData";
    public static final String updateUrlAppender = "updateAvailable";
    public static final String tokenRegisterUrl = "fcmRegister";
    public static final String mediaStatsUrl = "mediaStats";
    public static final String logsUrl = "logs";
    public static final String pingUrl = "ping";
    public static final String screenInfoUrl = "screenInfo";

    // Developer Keys
    public static final String youtubeDeveloperKey = "ABCDEFGH...";

    // Folder structure
    public static final String mediaFolder = "player/media";
    public static final String imagesFolder = "player/media/images";
    public static final String videosFolder = "player/media/videos";
    public static final String pdfFolder = "player/media/pdf";
    public static final String gifFolder = "player/media/gif";
    public static final String webFolder = "player/media/web";
    public static final String othersFolder = "player/media/others";
    public static final String logsFolder = "player/logs";

    public static final String defaultFolder = "player/default/";
    public static final String serFolder = "player/ser/";
    public static final String tempFolder = "player/temp/";

    // Shared Prefs Keys
    public static final String ANDROID_ID_KEY = "ANDROID_ID";
    public static final String MY_PREFERENCES_KEY = "MyPrefs";


    // General properties
    public static final String dateTimeFormatString = "ddMMyyyyHHmmss";
    public static final String dateFormatString = "yyyy-MM-dd";

    // Timeouts
    public static final int httpPollTimeout = 20000;                    // in millis
    public static final int pingPeriodicity = 30;                       // in secs
    public static final int updateCheckPeriodicity = 24;                // in hrs
    public static final int pushEnabledPollPeriodicity = 30;            // in secs
    public static final int pushDisabledPollPeriodicity = 30;           // in secs
    public static final int statsUploadPeriodicity = 60;                // in mins
    public static final int logsUploadPeriodicity = 24;                 // in hours
    public static final int cleanupPeriodicity = 24;                    // in hours
    public static final int registrationStatusRecheckPeriod = 20000;    // in millis
    public static final int tokenResendToServerPeriod = 20000;          // in millis

    // Others
    public static final int maxTextHeight = 50; // in dp
    ...
}

I have not stored any reference instantiatin PlayerProperties class, as all variables contained within are static.

When I am referencing the variable androidId using PlayerProperties.androidId , I SOMETIMES get null.

I have initialized the variable in one of the activities:

PlayerProperties.androidId = sharedpreferences.getString(PlayerProperties.ANDROID_ID_KEY, String.valueOf(UUID.randomUUID()));
  1. My suspicion is that garbage collector was kicked by android in between. If gc does kick in, would it knock off all my runtime-initialized static variables ?

  2. Which memory segment are the static variables stored ?

  3. If not, what else could be the issue ?

Extra details: My app is configured to automatically launches on boot. I am facing the above described issue only with low end processors and when app is automatically triggered on boot.

回答1:

Only public static String androidId; can be null, when you want to use it you should init it in this class or in some other class in onResume()



回答2:

androidId is a reference to an string, string is a class that will get by default a null reference as intial value if you dont do it....

look at this taken from oracle's doc

So basically androidId is null because is not initialized....the fact that the variable is static or not is not relevant in this case...

see here for more details

...I SOMETIMES get null.

yes, you will get always null unless its value change at run time...



回答3:

Please note the following in reference to above question:

  1. Garbage collector removes only unreferenced objects. Static variables will lose their values only when they are unloaded from JVM during run-time.

  2. Initialization happens when app is launched via activities. If there are any services/broadcast receivers that are accessing methods within other classes and use these ids, and the app is not yet running by that time, the uninitialized values are referenced as default value. In case of string - it is null.

  3. Nothing to do with low-end processors, easy to blame them often but JVM is powerful enough.