【问题标题】:Saving values when closing app or switching fragments关闭应用或切换片段时保存值
【发布时间】:2018-12-24 13:12:20
【问题描述】:

我是 Android 新手,在关闭应用程序时需要保留一个整数 weekNumber。我的想法是在处理需要使用该值的片段的活动中设置值,并始终使用 getter 从那里获取值,但是当我关闭应用程序或切换片段时,weekNumber 会不断重置,即使我使用共享首选项。我将保存的数据加载到活动的 onCreate 中,并将数据保存在 onPause 中。也许这是错误的。为什么会这样?我将不胜感激,并希望了解更多信息!

这是我处理 Fragments 的 MainActivity:

public class MainActivity extends AppCompatActivity {

private int weekNumber;

private static final String SHARED_PREFS = "sharedPrefs";
private static final String WEEK_NUMBER = "weekNumber";

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

    BottomNavigationView bottomNavigationView = findViewById(R.id.bottomNavigation);
    bottomNavigationView.setOnNavigationItemSelectedListener(navListener);

    getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,new HomeFragment()).commit();

    loadData();

    }

private BottomNavigationView.OnNavigationItemSelectedListener navListener =
        new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                Fragment selectedFragment = null;

                switch (item.getItemId()) {
                    case R.id.nav_home:
                        selectedFragment = new HomeFragment();
                        break;
                    case R.id.nav_add:
                        selectedFragment = new CalculatorFragment();
                        break;
                    case R.id.nav_settings:
                        selectedFragment = new SettingsFragment();
                        break;
                }

                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,selectedFragment).commit();
                return true;
            }
        };



@Override
protected void onPause() {
    super.onPause();
    saveData();
}

public void saveData() {
    SharedPreferences sharedPreferences = getSharedPreferences(SHARED_PREFS,MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPreferences.edit();

    editor.putInt(WEEK_NUMBER,weekNumber);
    }

public void loadData() {
    SharedPreferences sharedPreferences = getSharedPreferences(SHARED_PREFS,MODE_PRIVATE);
    weekNumber = sharedPreferences.getInt(WEEK_NUMBER,1);
}

public int getWeekNumber() {
    return weekNumber;
}

public void setWeekNumber(int weekNumber) {
    this.weekNumber = weekNumber;
}

其中一个片段:

public class HomeFragment extends Fragment {

View rootView;

private TextView[] textViews;

MainActivity mainActivity = new MainActivity();

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

    rootView = inflater.inflate(R.layout.fragment_home,container,false);

    textViews = new TextView[16];

    for(int i=0; i<textViews.length; i++) {
        {
            String buttonID = "textView" + (i+1);

            int resID = getResources().getIdentifier(buttonID, "id", getActivity().getPackageName());
            textViews[i] = ((TextView) rootView.findViewById(resID));
        }
    }

    setWeekText();

    textViews[9].setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            startActivity(new Intent(getActivity(),ActivityDay1.class));
        }
    });

    Button buttonNextWeek = rootView.findViewById(R.id.buttonNextWeek);
    buttonNextWeek.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mainActivity.setWeekNumber(mainActivity.getWeekNumber()+1);
            setWeekText();
        }
    });

    return rootView;
}

private void setWeekText() {
    textViews[8].setText(String.valueOf(mainActivity.getWeekNumber()));
}

【问题讨论】:

    标签: android android-studio android-fragments sharedpreferences


    【解决方案1】:

    saveData 函数的末尾调用 editor.apply();,以便实际将值保存在 SharedPreferences 中。

    另外,你不能在片段中调用MainActivity mainActivity = new MainActivity();。在 onCreateView 或直接在 onClick 侦听器中使用mainActivity = getActivity(); 设置它。

    为什么?您所拥有的内容在片段内创建了一个新的 MainActivity 实例,而不是引用您在其上设置了所需数据的实例。

    此外,如果您保留当前设计,在您创建将尝试访问数据的片段之前,在您的活动onCreate 中调用loadData 可能会更安全。 p>

    也许更好的选择是直接使用片段中的共享首选项。

    【讨论】:

    • 这很遗憾没有奏效。同样的问题也适用,但还是谢谢你
    • 这现在成了一种魅力。太感谢了!我理解使用 getActivity() 的概念,但为什么MainActivity mainActivity = new MainActivity 不是指我保存数据的那个?只有 Fragments 是这种情况吗?
    • 当你调用它时,它会在你的片段中创建一个新的 MainActivity 实例。它没有显示,因此没有调用它的生命周期方法(onCreateonPause 等...)。它有自己的weekNumber 实例,但从不调用loadDatasaveData,因此不会保留您在那里设置的值。
    【解决方案2】:

    几件事。

    1. 您需要确保实际保存了数据。在您的saveData() 中添加editor.commit()
    2. 您应该在onSaveInstance 中进行保存并在onSaveInstance 中进行恢复,因为当系统在内存不足等情况下终止您的活动时,android 会调用此操作

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多