草庐IT

java - 在 "firstUse"之后 onCreate 报告的 Android 首选项设置不一致——我的错,但是怎么样?

coder 2024-07-01 原文

EDIT 我忘记了一大块代码。在此处插入。

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    Log.w("Before switch", (String) item.getTitle());
    switch (item.getItemId()) {
      case R.id.menu_settings:
        Log.w("Before intent","\n");
        Intent intent = new Intent(this, SettingsActivity.class);
        startActivity(intent);
        Log.w("back from intent", "\n");
        preferences = getSharedPreferences(SETTINGS, MODE_PRIVATE);
        focusAtClue = preferences.getBoolean("focus",true);
        screenSaver = preferences.getBoolean("screen",true);
        Log.w("after intent", focusAtClue + " " + screenSaver);
        return true;

      default:
        Log.w("onOptItemSel","default");
        return super.onOptionsItemSelected(item);
    }
  }
}

此处的 onCreate 代码用于创建首选项,如图所示。 preferences.xml 中的 xml 作为注释插入。它也完整地包含在下面。

首选项存储在键focusscreen 下。对吧?

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    preferences = getSharedPreferences(SETTINGS, MODE_PRIVATE);
    boolean firstUse = preferences.getBoolean(FIRST_USE, true);
    if (firstUse){
      Toast helloMessage = Toast.makeText(getApplicationContext(), "Hello First Time User",Toast.LENGTH_LONG);
      helloMessage.show();
      editor = preferences.edit();
      editor.putBoolean(FIRST_USE, false);
      editor.putBoolean  ("focus", false);
/*NOTE THE MATCHED STRING  vvvvv
      <CheckBoxPreference
              android:key="focus"   android:title="@string/focusAfterShow" android:summary="Always place the cursor" android:defaultValue="false"/> */
      editor.putBoolean  ("screen", false);
/*NOTE THE MATCHED STRING  vvvvvv
      <CheckBoxPreference
              android:key="screen"  android:title="@string/screenSaver" android:summary="Keep screen on" android:defaultValue="false" /> */
          editor.commit();
    }
    else {
    ///////////////////// problems here *******************
      SharedPreferences preferences = getSharedPreferences(SETTINGS, MODE_PRIVATE);
      focusAtClue = preferences.getBoolean("focus",focusAtClue);
      screenSaver = preferences.getBoolean("screen",screenSaver);
      Log.w("oncreate:", focusAtClue + " " + screenSaver);
    ///////////////////// problems 
    }
  }

preferences.xml:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <PreferenceCategory
        android:title="Screen options">
        >
        <CheckBoxPreference
            android:key="focus"
            android:title="@string/focusAfterShow"
            android:summary="Always place the cursor at the 'clue' (sum) after tapping 'Show'."
            android:defaultValue="false"
            />
        <CheckBoxPreference
            android:key="screen"
            android:title="@string/screenSaver"
            android:summary="Keep screen on at all times while running this app."
            android:defaultValue="false"
            />
    </PreferenceCategory>
</PreferenceScreen>

离开应用程序进入主屏幕然后返回主屏幕后,偏好设置没有变化,如 logcat 所示。

然后我通过选中它的框来更改第一个首选项。 logcat 显示正确。涉及的代码在SettingsFragment.java中:

package com.bffmedia.hour11app;

import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.preference.PreferenceFragment;
import android.util.Log;

public class SettingsFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
    }
  @Override
    public void onResume() {
        super.onResume();
        getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
    }
  @Override
    public void onPause() {
        super.onPause();
        getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
    }
    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {    
       //SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getActivity());
       Log.w("onSharedPrefChgd", sharedPreferences.getBoolean("focus",false) + " " + sharedPreferences.getBoolean("screen",false));
       }
    }

然后我从内存中的应用程序列表中删除该应用程序,然后从应用程序图标运行它。

onCreate 表示两个值都是 FALSE,但只有第一个是。

这是 logcat,其中只有我通过 Log.w 编写的行。有 3 个组要看:创建首选项和更改第一个首选项,效果很好。然后是第二个 onCreate,这两个值据说都是 false,这是错误的——第一个是 true——但是设置屏幕显示我做了选中第一个框。

我对自己做错了什么一无所知。

05-16 13:25:20.290  18778-18778/com.bffmedia.hour11app W/Before switch? Settings
05-16 13:25:20.291  18778-18778/com.bffmedia.hour11app W/Before intent? [ 
05-16 13:25:20.292   438:0x1a07 I/ActivityManager ]
    START u0 {cmp=com.bffmedia.hour11app/.SettingsActivity} from pid 18778
05-16 13:25:20.449  18778-18778/com.bffmedia.hour11app W/back from intent? 
05-16 13:25:20.450 18778:0x495a W/after intent ]
    false false ***************************** CORRECT ************************



05-16 13:35:16.717  18778-18778/com.bffmedia.hour11app W/onSharedPrefChgd? 
     true false *********************************** CORRECT



05-16 13:37:21.185  20014-20014/com.bffmedia.hour11app W/Before switch? Settings
05-16 13:37:21.186  20014-20014/com.bffmedia.hour11app W/Before intent? [ 
05-16 13:37:21.188   438:0x2ef I/ActivityManager ]
    START u0 {cmp=com.bffmedia.hour11app/.SettingsActivity} from pid 20014
05-16 13:37:21.245  20014-20014/com.bffmedia.hour11app W/back from intent? [ 
05-16 13:37:21.245 20014:0x4e2e W/after intent ]
    false false *************************************** WHY? *******************************************

最佳答案

这里的问题是您没有查看正确的首选项 xml 文件。 PreferenceFragment 中的首选项被保存到默认首选项 xml 文件中,并且在您的 MainActivity 中,因为您正在使用 getSharedPreferences(SETTINGS, MODE_PRIVATE),这会创建一个新文件除了默认的首选项 xml 文件。

为了修复它,只需将该代码更改为 PreferenceManager.getDefaultSharedPreferences(this),然后您将查看与 PreferenceFragment 相同的首选项 xml 文件用途。

更多信息 here....还有here.....

这就是您需要做的所有修复工作,我刚刚测试过它,它可以工作!

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //preferences = getSharedPreferences(SETTINGS, MODE_PRIVATE);
        //use this instead:
        preferences = PreferenceManager.getDefaultSharedPreferences(this);

        boolean firstUse = preferences.getBoolean(FIRST_USE, true);
        if (firstUse){
            Toast helloMessage = Toast.makeText(getApplicationContext(), "Hello First Time User",Toast.LENGTH_LONG);
            helloMessage.show();
            editor = preferences.edit();
            editor.putBoolean(FIRST_USE, false);
            editor.putBoolean  ("focus", false);
/*NOTE THE MATCHED STRING  vvvvv
      <CheckBoxPreference
              android:key="focus"   android:title="@string/focusAfterShow" android:summary="Always place the cursor" android:defaultValue="false"/> */
            editor.putBoolean  ("screen", false);
/*NOTE THE MATCHED STRING  vvvvvv
      <CheckBoxPreference
              android:key="screen"  android:title="@string/screenSaver" android:summary="Keep screen on" android:defaultValue="false" /> */
            editor.commit();
        }
        else {
            ///////////////////// problems here *******************
            //no need to create another preferences, it's already defined above
            //SharedPreferences preferences = getSharedPreferences(SETTINGS, MODE_PRIVATE);

            //This should work now!!!!!!
            focusAtClue = preferences.getBoolean("focus",focusAtClue);
            screenSaver = preferences.getBoolean("screen",screenSaver);
            Log.w("oncreate:", focusAtClue + " " + screenSaver);
            Toast helloMessage = Toast.makeText(getApplicationContext(), "Hello Returning User " + focusAtClue + " " + screenSaver,Toast.LENGTH_LONG);
            helloMessage.show();
            ///////////////////// problems
        }
    }

还有一点需要注意,下面这段代码看起来不会像您想象的那样运行。这段代码的执行不会在调用 startActivity() 时暂停,它会继续执行。因此,此处的日志将反射(reflect)设置 Activity 打开之前 SharedPreference 的状态,而不是之后。

此外,您还应该在此处使用默认的共享首选项。

Intent intent = new Intent(this, SettingsActivity.class);
startActivity(intent);
Log.w("back from intent", "\n");
//preferences = getSharedPreferences(SETTINGS, MODE_PRIVATE);
preferences = PreferenceManager.getDefaultSharedPreferences(this);
focusAtClue = preferences.getBoolean("focus",true);
screenSaver = preferences.getBoolean("screen",true);
Log.w("after intent", focusAtClue + " " + screenSaver);
return true;

关于java - 在 "firstUse"之后 onCreate 报告的 Android 首选项设置不一致——我的错,但是怎么样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30278998/

有关java - 在 "firstUse"之后 onCreate 报告的 Android 首选项设置不一致——我的错,但是怎么样?的更多相关文章

  1. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  2. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  3. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  4. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  5. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  6. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

    我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

  7. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  8. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  9. ruby-on-rails - 迷你测试错误 : "NameError: uninitialized constant" - 2

    我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test

  10. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

    我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

随机推荐