【问题标题】:Are Android Context objects serializable?Android Context 对象可以序列化吗?
【发布时间】:2012-10-29 04:40:38
【问题描述】:

我声明了一个名为 PREFS 的非最终静态 SharedPreferences 对象以及我的 Constants.java 类中的其他常量:

public static SharedPreferences PREFS = null;

我这样做的原因是我的应用由大约 6 个不同的 AsyncTasks 组成,它们不断访问相同的共享首选项文件,我不想每次都得到 SharedPreferences 和它的 Editor。在我的应用程序第一次运行时,我在MainActivity 中调用getSharedPreferences() 并将其存储到PREFS,以便它在AsyncTasks 被触发之前指向一个实例,因此避免NullPointerException

但是,无论如何,我一直从AsyncTasks 获得NullPointerExceptions。所有堆栈跟踪都指向我调用Constants.PREFS 以获取值的行。我的理论是,一段时间后,Android 会杀死我的应用程序的进程,所以下次我的任何AsyncTasks 的警报响起时,Constants.PREFS 的值已经是null

我的问题是:我应该为Context 创建一个静态变量吗?即使 Android 终止了我的进程,它的状态是否会持续存在?我总是将Context 的引用传递给我的AsyncTasks,当后者被实例化时,它们可以调用getSystemService(),并且永远不会抛出NullPointerException。但是,我没有看到 Context 从 Android 文档中扩展 Serializable

【问题讨论】:

    标签: android static sharedpreferences android-context


    【解决方案1】:

    使用Application 类在应用程序中全局共享首选项。

    public class MyApp extends Application {
        private static Context mAppContext;
    
        @Override
        public void onCreate() {
            super.onCreate();
            mAppContext = getApplicationContext();
        }
    
        public static SharedPreferences getPreferences(){
            return mAppContext.getSharedPreferences("my_app_preferences",MODE_MULTI_PROCESS);
        }
    }
    

    通过在清单中提及它来告诉 android 你想要你的自定义应用程序类:

    <application android:name=".MyApp" android:label="@string/app_name" android:icon="@drawable/ic_launcher">
    

    现在从任何地方,只需拨打电话

    MyApp.getPreferences().edit().putBoolean("pref1",true). . . put more stuff . .commit()
    

    MODE_MULTI_PROCESS 确保所有 AsyncTask 线程同步访问SharedPreferences 的同一实例。此外,commit() 是原子的,并且会将更改持久保存到磁盘。

    上述模式对于从任何地方访问资源也很方便。

    更新

    似乎对上下文的静态引用会导致新的Instant Run 功能出现问题。

    因此,上下文可以作为实用方法的参数:

    public static SharedPreferences getPreferences(context){
        return context.getSharedPreferences("my_app_preferences",MODE_MULTI_PROCESS);
    }
    

    【讨论】:

    • "上述模式对于从任何地方访问资源也很方便。" -- 你的意思是任何类型的资源?现在我还计划从MyApp 内部存储/生成应用程序的 UUID 字符串,存储为私有静态字符串。
    • 我的意思是资源,从 res 目录中的strings.xml 获取字符串。基本上,您可以从Context.getResources() 获得任何东西。
    • 等一下,方法getApplicationContext()Application内部不存在。
    • 我认为App的私人偏好是存储这个UUID(可选加密)的最佳位置。在Application 类的onCreate() 中,检查此首选项是否存在。如果不是,你生成并保存它,如果它存在,你验证它。此外,您可以将其存储在 MyApp 类中的静态变量中,并与其他应用程序代码共享。
    • Application 类扩展了ContextWrapper,它有一个公共方法getApplicationContext()。此方法在Application 类的内部 onCreate() 中可用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-08
    • 1970-01-01
    • 2010-11-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多