【问题标题】:Using Activity class static members in a background service在后台服务中使用 Activity 类静态成员
【发布时间】:2013-02-25 21:06:46
【问题描述】:

我的应用有一个名为 MainActivity 的 Activity 类,它的成员之一是

public static SharedPreferences prefsdefault;

我的应用程序还有一个在后台运行的服务(在另一个进程中)。在我写的服务里面

MainActivity.prefsdefault.getString(Key,"Hello");

应用有时会在这一行抛出空指针异常。为什么?这是否意味着当我关闭活动并且我无法随时访问它(当我的服务运行时)时,垃圾收集器会清理该成员?那么什么是完美的解决方案呢?

我应该将 MainActiviy.class 传递给服务吗?当我实现需要上下文的线程时也会发生这种情况。

【问题讨论】:

    标签: android service android-context


    【解决方案1】:

    这是因为,即使您的 prefsdefault 可能已初始化一次,您的整个应用程序也可能被垃圾回收并再次重新启动。

    在这种情况下,您的服务会发现该字段为空。在 Activity 中使用静态字段是错误的,原因有很多,最重要的是您的应用可能会被操作系统杀死并重新启动,然后所有静态字段又会被清除。

    使用共享首选项的正确方法是在需要访问/写入时使用 getSharedPreferences 访问它们。

    另一个奇怪的事情是你说服务在另一个进程中运行。在这种情况下,它应该无法访问来自另一个进程的数据。

    【讨论】:

    • 我不明白“消灭”这个词,如果我在我的活动中有 static boolean x = true 并且它在应用程序中设置为 false。现在如果操作系统重新启动我的应用程序,x 是 True 还是 False?
    • 这是真的。出于同样的原因,如果您在某处初始化了一个对象,如果操作系统需要您应用程序的资源,则指向该对象的指针变为空。
    • 这就是我应该避免在 Activity 中使用静态字段的原因吗?现在,如果我想(从我的活动)调用一个需要来自活动中声明的对象的信息的线程?那么解决方案是什么?将 MainActivity.class 传递给 Thread 构造函数?也许?
    • 如果您需要一次性线程(即执行一项工作并返回),请使用异步任务,如果您需要长时间运行线程,请使用 loopers。 developer.android.com/reference/android/os/Looper.html您可以使用处理程序在不同线程之间传递消息。
    【解决方案2】:

    因为prefsdefaultNULL。我没有看到它已初始化。 你可以这样做

    prefsdefault = getSharedPreferences("my_preferences", Activity.MODE_PRIVATE);
    

    热点提示:永远不要让您的 SharedPreference 实例静态

    【讨论】:

    • 线程播放声音所需的上下文等其他对象呢?将 MainActivity 传递给构造函数?这是完美的主意吗?
    • @yasserbn 很难说没有看到更多的代码,这真的取决于;但不要将 SharedPreference 设为静态。
    【解决方案3】:

    原因是SharedPreferences 没有初始化你不需要这样做,因为SharedPreferences 在应用程序中是全局可用的,如果 MODE 是私有的,只需在服务中创建新实例它也可以工作

    【讨论】:

      猜你喜欢
      • 2012-03-30
      • 2014-02-17
      • 1970-01-01
      • 2018-10-05
      • 1970-01-01
      • 1970-01-01
      • 2014-08-07
      • 1970-01-01
      • 2012-04-13
      相关资源
      最近更新 更多