【问题标题】:Android static variables are lostAndroid静态变量丢失
【发布时间】:2016-11-14 18:54:04
【问题描述】:

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

以下是我的类定义:

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. 我的怀疑是垃圾收集器在两者之​​间被 android 踢了。如果 gc 确实启动了,它会关闭我所有运行时初始化的静态变量吗?

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

  3. 如果不是,还有什么问题?

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

【问题讨论】:

  • 它是空的,因为它没有被初始化......不管它是否是静态的,你应该初始化它

标签: java android garbage-collection


【解决方案1】:

关于上述问题,请注意以下几点:

  1. 垃圾收集器仅删除未引用的对象。静态变量只有在运行时从 JVM 中卸载时才会丢失它们的值。

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

  3. 与低端处理器无关,很容易经常指责它们,但JVM足够强大。

【讨论】:

  • 所以我们必须至少运行一次包含静态变量的类才能通过广播接收器使用它?
【解决方案2】:

只有public static String androidId;可以为null,当你想使用它时你应该在这个类或onResume()的其他类中初始化它

【讨论】:

  • 为什么要专门 onResume ?
  • 因为当你的应用程序进入后台时androidId 会被垃圾收集,当你的应用程序再次打开时它会触发onResume() 所以当你分配androidId 时应该没问题。另见here
【解决方案3】:

androidId 是对字符串的引用,字符串是一个类,如果你不这样做,默认情况下将获得一个空引用作为初始值....

看看这个取自 oracle 的文档

所以基本上 androidId 是 null 因为没有初始化......在这种情况下,变量是否为静态的事实与此无关......

查看here了解更多详情

...我有时会得到 null。

是的,除非它的值在运行时发生变化,否则您将始终为 null...

【讨论】:

  • 我已经确定我在运行时初始化了变量。我编辑了问题的详细信息。请检查。
猜你喜欢
  • 1970-01-01
  • 2011-05-31
  • 1970-01-01
  • 1970-01-01
  • 2019-04-27
  • 1970-01-01
  • 1970-01-01
  • 2011-09-30
  • 1970-01-01
相关资源
最近更新 更多