Android静态变量丢失问题

6

我正在使用一个只有静态变量的类来存储所有常量和运行时属性。但是,最近我发现当我引用这些变量时,有时会得到null值。

以下是我的类定义:

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
    ...
}

我没有存储任何引用实例化PlayerProperties类,因为其中包含的所有变量都是静态的。

当我使用PlayerProperties.androidId 引用androidId变量时,有时会得到空值。

我已经在其中一个活动中初始化了这个变量:

PlayerProperties.androidId = sharedpreferences.getString(PlayerProperties.ANDROID_ID_KEY, String.valueOf(UUID.randomUUID()));
  1. 我的怀疑是垃圾回收器被安卓系统中断了。如果垃圾回收器确实启动了,是否会清除我所有运行时初始化的静态变量?

  2. 静态变量存储在哪个内存段中?

  3. 如果不是这个问题,还可能是什么原因?

额外细节:我的应用程序已配置为在启动时自动启动。我只在低端处理器和应用程序自动启动时遇到上述问题。


它是空的,因为没有初始化...无论它是否是静态的,你都应该初始化它。 - ΦXocę 웃 Пepeúpa ツ
3个回答

2
请注意以下关于上述问题的内容:
  1. 垃圾收集器只会删除未被引用的对象。静态变量只有在运行时从JVM中卸载时才会失去其值。

  2. 初始化发生在应用程序通过活动启动时。如果有任何服务/广播接收器访问其他类中的方法并使用这些ID,而此时应用程序尚未运行,则未初始化的值将作为默认值引用。在字符串的情况下,它是null。

  3. 与低端处理器无关,经常将责任归咎于它们,但JVM足够强大。


所以我们必须至少运行一次包含静态变量的类,才能通过广播接收器使用它吗? - Jitin

1
只有 public static String androidId; 可以为 null,在使用它之前,你应该在这个类或者其他类的 onResume() 方法中初始化它。

为什么特别是onResume? - jay
因为当您的应用程序进入后台时,androidId会被垃圾回收,当您的应用程序再次打开时,它将触发onResume(),因此当您在那里分配androidId时,它应该是可以的。另请参见此处 - Jozef Dochan

0

androidId 是一个字符串的引用,字符串是一个类,默认情况下如果不进行初始化,它将获得一个 null 引用作为初始值...

看一下这个来自 Oracle 文档的例子

enter image description here

基本上,androidId是空的,因为它没有被初始化...变量是静态的还是非静态的在这种情况下并不重要...

请参见此处以获取更多详细信息

...有时我会得到null。

是的,在运行时除非其值发生更改,否则您将始终获得null...


我已确保在运行时初始化了变量。我编辑了问题细节,请检查。 - jay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接