【问题标题】:Get attributes from SharedPreferences in android从android中的SharedPreferences获取属性
【发布时间】:2014-12-21 16:44:33
【问题描述】:

这是我的 MainActivity.java,我在其中实例化静态 SharedPreferences 及其编辑器:

public static SharedPreferences settings;
public static SharedPreferences.Editor editor;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    settings = PreferenceManager.getDefaultSharedPreferences(this);
    editor = settings.edit();

然后我对另一个 java 类进行 AsyncTask 调用,在该类中我尝试将 onPostExecute 方法中的令牌存储到此 SharedPreferences。

@Override
protected void onPostExecute(String result) {

    MainActivity.editor.putString("auth_token", result);
    MainActivity.editor.commit();

    Log.d("token", MainActivity.settings.getString("auth_token", "Nothing"));

}

这个 Log.d() 方法输出控制台中的令牌值,即“OK”。但随后我启动​​了一个活动 Next.java,我尝试在屏幕上使用此令牌:

TextView text;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_next);

    String auth_token_string = MainActivity.settings.getString("auth_token", "Nothing");

    text = (TextView) findViewById(R.id.logintxt);
    text.setText(auth_token_string);

屏幕上的结果是默认的字符串“Nothing”。

我在这里做错了什么? ...这是使用 SharedPreferences 的正确方法吗?我在topic 中得到了这个想法。

编辑:

来自我调用 asyncTask 的 AuthorizeActivity.java 的代码:

 public void getToken(String code){

    AsyncTask<String, Void, String> tsk = new Api().execute(code);

    Intent i = new Intent(this.getBaseContext(), Next.class);
    dialog.dismiss();

    startActivity(i);

}

【问题讨论】:

  • 你能发布完整的代码(你调用 asyncTask 的地方)吗?
  • 见您的.commit() 呼叫正在返回true 以成功保存。您可以尝试将.commit() 替换为apply()。按照设计,这不会返回任何内容,但它是自 2.3 以来添加的方法。
  • @issathink - 我从 AuthorizeActivity.java 调用 asynctask - 你可以看到上面更新的代码。
  • @JASONGPETERSON - 出于这个原因,我打印了 Log.d(),其中我从“MainActivity.settings.getString("auth_token", "Nothing")" 获取值。但无论如何, .commit() 正在返回 true
  • 我很确定您通过持有 Object 的静态引用来泄漏您的 Activity,您将向该引用传递您的 Activity 的实例。传递ApplicationContext 而不是this

标签: java android sharedpreferences


【解决方案1】:

您的设置变量是静态的,当您访问 Next.java 中的设置时,它已在 MainActivity 的 onCreate 方法中初始化,但尚未初始化。

您可以访问 Next.java 中的 SharedPreferences(它是共享的)。

编辑:

在 MainActivity 中添加更新方法:

public void update() {

  Intent i = new Intent(this.getBaseContext(), Next.class);

  startActivity(i);
}

你的 postExecute 应该是这样的:

 @Override
 protected void onPostExecute(String result) {

   MainActivity.editor.putString("auth_token", result);
   MainActivity.editor.commit();

   Log.d("token", MainActivity.settings.getString("auth_token", "Nothing"));
   ((MainActivity) context).update();

  }

【讨论】:

  • 我在 Next.java 中和在 MainActivity.java 中一样使用“this”来初始化 sharedPreferences,但结果仍然是默认字符串。
  • 也许你的 asyncTask 做的工作太多,让 Thread.sleep() 直到你的 asyncTask 完成后再访问 sharedPreferences
  • 是的,你是对的!我让线程休眠 10 秒,然后打印出我的令牌!感谢您的回答我如何通过不放置 Thread.sleep(3000) 来解决这个问题,因为在不同的设备上它可能需要更长或更短的时间?
  • 看看我的回答。
  • 这些设置真的不应该是静态的并且可以跨不同的上下文访问
【解决方案2】:

不要使用 MainActivity 中的设置,创建一个新的 SharedPrefs 实例并调用 getString 方法。

【讨论】:

  • 我该怎么做?因为然后我需要以某种方式获取与我用来实例化 SharedPrefs 相同的上下文,以将值保存到我想从 SharedPrefs 读取一些值以实例化它的那个活动中......或者我错了吗?
  • 使用 getApplicationContext() 方法获取上下文。您应用中的每个 Activity 都有相同的偏好。
  • 我在 MainActivity 中进行了更改,在那里我将 sharedPreferences “this”初始化为“getApplicationContext()”,并在 Next.java 中初始化了 sharedPrefs - 结果仍然是默认字符串
  • 如果你这样做,在 Next.java 中: SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());如果你仍然没有得到价值问题不是sharedprefs。
【解决方案3】:

编辑:我创建了一个应该如何处理的示例on GitHub

首先,我建议您不要让您的成员成为静态的;它们不需要是静态的。

在您的Next.class 上(也许您应该重命名它,不清楚它的作用),您只需要使用您的新上下文再次处理共享首选项:

PreferenceManager.getDefaultSharedPreferences(this);

请注意,有一个difference between getDefaultSharedPreferences and getSharedPreferences - 使用您认为最合适的那个。

【讨论】:

  • 我已经尝试过了,但我仍然打印出默认字符串
  • 为了解决这个问题,如果您提交共享首选项并且他们尝试立即从中读取(在同一个活动中)会发生什么?
  • 正如您在根本问题中看到的(查看 onPostExecute),我确实立即从 sharedPrefs 中阅读,它很好地打印出我需要的内容。我扩展 asyncTask 的这个类是单独的类(它不是活动的内部类)。
  • 我创建了几个示例类来展示它应该如何完成,并将它们上传到 GitHub。随便看看,应该有帮助
  • 如何在 GitHub 上找到它?
猜你喜欢
  • 2018-01-24
  • 1970-01-01
  • 1970-01-01
  • 2016-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-04
  • 1970-01-01
相关资源
最近更新 更多