当前位置: 首页 > 知识库问答 >
问题:

跨多个活动的SharedReference返回NULL

廉飞捷
2023-03-14

我已经分享了在我的应用程序中使用的首选项,但现在只有四个活动。第一个活动是带有复选框的回收站视图,并且使用共享prefs helper类为每个复选框保存(在回收站适配器中)。然后,下一个活动将作为一个包含随机项目列表的片段的tablayout启动。

当用户单击第二个活动片段中的任何项目时,将启动第三个活动。在这里,我尝试从shared prefs helper类中检索值,但它返回null,与第四个活动中的情况相同。另外,当我在第一个活动上按两下时,它也会返回null。

我会发布所有活动的代码,但这只会让问题变得冗长。这是我的助手类:

public class WalpyPrefsHelper {

public Context context;
public SharedPreferences customizePrefs, tabsCountPrefs;
public SharedPreferences.Editor editor, tabsEditor;

public static final String CUSTOMIZE_TABS_PREFS = "customizeTabsPrefs";
public static final String COUNT_TABS_PREFS = "countTabsPrefs";

public static final String KEY_NATURE = "nature";
public static final String KEY_SPACE = "space";
public static final String KEY_SEASONS = "seasons";
public static final String KEY_ART = "art";
public static final String KEY_SCIFI = "sci_fi";
public static final String KEY_MISC = "misc";

public static final String KEY_COUNT = "count_tabs";

public WalpyPrefsHelper(Context context) {
    this.context = context;
    customizePrefs = context.getSharedPreferences(CUSTOMIZE_TABS_PREFS, Context.MODE_PRIVATE);
    editor = customizePrefs.edit();

    tabsCountPrefs = context.getSharedPreferences(COUNT_TABS_PREFS, Context.MODE_PRIVATE);
    tabsEditor = tabsCountPrefs.edit();

}

public void saveNaturePrefs(String s){
    editor.putString(KEY_NATURE, s).apply();
}

public String getKeyNature(){
    return customizePrefs.getString(KEY_NATURE, null);
}

public void removeNaturePrefs(){
    editor.remove(KEY_NATURE).apply();
}

public void saveSpacePrefs(String s){
    editor.putString(KEY_SPACE, s).apply();
}

public String getKeySpace(){
    return customizePrefs.getString(KEY_SPACE, null);
}

public void removeSpacePrefs(){
    editor.remove(KEY_SPACE).apply();
}

public void saveSeasonsPrefs(String s){
    editor.putString(KEY_SEASONS, s).apply();
}

public String getKeySeasons(){
    return customizePrefs.getString(KEY_SEASONS, null);
}

public void removeSeasonPrefs(){
    editor.remove(KEY_SEASONS).apply();
}

public void saveArtPrefs(String s){
    editor.putString(KEY_ART, s).apply();
}

public String getKeyArt(){
    return customizePrefs.getString(KEY_ART, null);
}

public void removeArtPrefs(){
    editor.remove(KEY_ART).apply();
}

public void saveSci_FiPrefs(String s){
    editor.putString(KEY_SCIFI, s).apply();
}

public String getKeyScifi(){
    return customizePrefs.getString(KEY_SCIFI, null);
}

public void removeSci_FiPrefs(){
    editor.remove(KEY_SCIFI).apply();
}

public void saveMiscPrefs(String s){
    editor.putString(KEY_MISC, s).apply();
}

public String getKeyMisc(){
    return customizePrefs.getString(KEY_MISC, null);
}

public void removeMiscPrefs(){
    editor.remove(KEY_MISC).apply();
}

public void removeAllPrefs(){
    editor.remove(KEY_NATURE).apply();
    editor.remove(KEY_SPACE).apply();
    editor.remove(KEY_SEASONS).apply();
    editor.remove(KEY_ART).apply();
    editor.remove(KEY_SCIFI).apply();
    editor.remove(KEY_MISC).apply();
}

public void saveCount(int count) {
    tabsEditor.putInt(KEY_COUNT, count).apply();
}

public int getSaveCount(){
    return tabsCountPrefs.getInt(KEY_COUNT, 0);
}
}

首选项保存在第一个活动回收适配器中,如下所示:

viewholder.customizeSelImg.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            String nature, space, seasons, art, scifi, misc;
            switch (position) {
                case 0:
                    nature = prefsHelper.getKeyNature();
                    if (viewholder.customiseCheckBox.isChecked()) {
                        viewholder.customiseCheckBox.setChecked(false);
                        viewholder.customiseCheckBox.setVisibility(View.INVISIBLE);
                        if (nature != null) {
                            prefsHelper.removeNaturePrefs(); // infer nullity
                            if (count > 0) {
                                count--;
                                Log.d(TAG, "Count Value:\t" + count);
                            }
                            Log.d(TAG, "Position:\t" + position + " is UNChecked");
                        }
                    } else {
                        viewholder.customiseCheckBox.setChecked(true);
                        viewholder.customiseCheckBox.setVisibility(View.VISIBLE);
                        count ++;
                        Log.d(TAG, "Count Value:\t" + count);
                        prefsHelper.saveNaturePrefs(Constants.NATURE); // save value. Works fine
                        Log.d(TAG, "Position:\t" + position + " is Checked");
                    }
                    break;

在下一次活动中,我能够检索共享的首选项值,如下所示:

    String space = prefsHelper.getKeySpace();
    String nature = prefsHelper.getKeyNature();
    String seasons = prefsHelper.getKeySeasons();
    String art = prefsHelper.getKeyArt();
    String scifi = prefsHelper.getKeyScifi();
    String misc = prefsHelper.getKeyMisc();

像这样初始化后:prefsHelper=new-WalpyPrefsHelper(this)

使用首选项的第二个活动:

public void setUpTabs() {

    prefsHelper = new WalpyPrefsHelper(this);
    int count = prefsHelper.getSaveCount();
    Log.d(TAG, "Tabs Count:\t" + count);

    setUpViewPager(viewPager);
    tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
    tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
    tabLayout.setupWithViewPager(viewPager);
}

private void setUpViewPager(ViewPager viewPager) {

    space = prefsHelper.getKeySpace();
    nature = prefsHelper.getKeyNature();
    seasons = prefsHelper.getKeySeasons();
    art = prefsHelper.getKeyArt();
    scifi = prefsHelper.getKeyScifi();
    misc = prefsHelper.getKeyMisc();

    pagerAdapter = new TabsPagerAdapter(getSupportFragmentManager(), this);
    pagerAdapter.addTab(new Top30Fragment(), Constants.Top30);

    if (nature != null) {
        pagerAdapter.addTab(new NatureFragment(), Constants.NATURE);
    }

    if(space != null){
        pagerAdapter.addTab(new SpaceFragment(), Constants.SPACE);
    }

    if (seasons != null){
        pagerAdapter.addTab(new SeasonsFragment(), Constants.SEASONS);
    }

    if (art != null){
        pagerAdapter.addTab(new ArtFragment(), Constants.ART);
    }

    if (scifi != null){
        pagerAdapter.addTab(new SciFiFragment(), Constants.SCI_FI);
    }

    if (misc != null){
        pagerAdapter.addTab(new MiscFragment(), Constants.MISC);
    }

    pagerAdapter.addTabAtLastPosition(new PrefsFragment(), Constants.PREFS);

    viewPager.setAdapter(pagerAdapter);
}

我在应用程序安装时使用了shared prefs来设置tablayout,但在导航其他活动并返回到该活动后,prefs中的那些选项卡将被删除。在其他情况下,我的最后一个选项卡将包含prefs中的自然片段的视图和数据。

在适配器和最后两个活动的顺序,我得到这样的关键,但它返回null:

    prefsHelper = new WalpyPrefsHelper(this);
    Log.d(TAG, "Nature Key:\t" + prefsHelper.getKeyNature());

此外,在适配器中,该值返回null,并且在第二个活动之后的其他后续活动中返回null。这是sharedprefs行为吗?我在某个地方配置错误,或者sharedprefs无法从活动传递到片段和适配器上下文?

我试过。apply()和。commit()用于编辑器,但出现相同的情况。有人知道为什么吗?谢谢


共有2个答案

程和煦
2023-03-14

查看附带的代码流,我找不到任何有问题的部分。尽管每个活动都创建并使用了一个preference manager类实例,但SharedPreferRece对象本身作为一个对象共享,因此这不是问题。

请再次检查流中是否删除了首选项值。此外,如果在每个活动中附加使用prefsHelper的零件,则故障排除将很有帮助。

漆雕昊天
2023-03-14

我已经通过使用sqlite来持久化和检索这些值,解决了这个问题。

 类似资料:
  • 我在一个活动中有一个列表视图,在自定义适配器中有一个信息图标。当用户点击该信息按钮时,下一个活动将打开,当用户点击更新按钮时,在下一个活动中标记出勤率后,第二个活动应该完成,第一个活动列表视图应该更新。 我成功地做了什么:我已经成功地标记了出席情况并更改了listview的颜色,但我在关闭第二个活动并重新启动第一个活动后这样做了。通过这种方式,由于再次开始活动,listview会得到更新。 我无法

  • 在Android中,当我们用一个新的片段替换容器视图时,我们可以使用replace()和addToBackStack(),因此按下back按钮就可以转到上一个片段。 但如果出现以下情况怎么办: 在Activity1中,我可以按下back按钮从fragment2转到fragment1。但当fragment2启动另一个活动时,从Activity2按下back按钮,它会将我带到Activity1中的fr

  • 我有两个带有链接数据的表。有针对单个客户(客户id)的活动更新。我想返回每个客户最近的活动; 联系客户id(自动增量)姓氏姓氏姓氏 电话工作 活动活动\u id(自动增量)数据\u项目\u id按日期输入\u创建注释 我可以返回整套活动; 从联系人的联系人加入活动中选择姓氏、名、创建日期、备注。客户id=活动。数据项标识; ...但是我只想要每个customer_name最近的活动。如果我使用唯一

  • 我读过很多关于这方面的文章,但也有2012年或更早的文章。 (我只是打算从数据库中读取和插入一些数据。)

  • 我有一个活动叫做。我从MapsActivity开始参加这个活动。然而,在上运行几秒钟后,它会返回到,而我什么也不做。我需要修复它,但我不确定为什么会发生。 我正在尝试更新数据库: Locker对象使其在此处不可用(其唯一id已从传递到此处), 我正在复制下面的代码: 日志中没有例外:我有这个:2020-02-11 22:35:30.211 10084-10127/android。比格纳德兰奇。pr

  • 所以我有一个打开活动的通知: 我制作的活动是一个简单的对话框样式的活动。当我从通知抽屉中打开活动时,在任何其他应用程序上,如facebook、whatsapp、chrome浏览器等,活动就会按预期打开。问题是当我试图关闭它,并回到以前的应用程序。 单击对话框中创建的“关闭”按钮时: 同样的事情发生了:活动结束了,但我要回到主屏幕,而不是上一个应用程序。为什么?? *注意:以前的应用程序仍然在后台工