我一直在寻找有关SharedPreferences(SP)的帮助,但发现自己越来越困惑。我的理解是,默认情况下,在SP声明中使用包名称将使首选项在我应用程序的所有活动中均可用。
自从搜索堆栈溢出以来,我注意到文件名的使用(我已经在我的应用程序文件夹中广泛搜索了任何种类的SP文件,但没有用),这些文件名将存储在哪里?我也注意到所谓“单子方法”的使用。
我的问题的来源是以下代码-
主要活动 -
public class MainActivity extends AppCompatActivity {
SharedPreferences sharedPreferences;
SharedPreferences.Editor editor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setTitle("Let's Play Darts");
sharedPreferences = getApplicationContext().getSharedPreferences("com.app.letsplaydarts", Context.MODE_PRIVATE);
editor = sharedPreferences.edit(); // package name used in declaration as I was taught
editor.putString("p1", null);
editor.putInt("p1Picked", 0);
editor.putString("p2", null);
editor.putInt("p2Picked", 0); // Resetting values when app opens
editor.putString("p3", null);
editor.putInt("p3Picked", 0);
editor.putString("p4", null);
editor.putInt("p4Picked", 0);
editor.commit();
}
}
单击按钮将打开-GameSetup活动-此活动中未使用编辑器
public class GameSetup extends AppCompatActivity {
SharedPreferences sharedPreferences;
SharedPreferences.Editor editor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game_setup);
sharedPreferences = getApplicationContext().getSharedPreferences("com.app.letsplaydarts", Context.MODE_PRIVATE);
editor = sharedPreferences.edit(); // declared in same manner
if (sharedPreferences.getInt("p1Picked", 0) == 1) {
player1TextView.setText(sharedPreferences.getString("p1", ""));
if (sharedPreferences.getInt("p2Picked", 0) == 1) {
player2TextView.setText(sharedPreferences.getString("p2", ""));
if (sharedPreferences.getInt("p3Picked", 0) == 1) {
player3TextView.setText(sharedPreferences.getString("p3", ""));
if (sharedPreferences.getInt("p4Picked", 0) == 1) {
player4TextView.setText(sharedPreferences.getString("p4", ""));
}
}
} // sets textviews dependant on SP values
}
Log.d("testing", "p1Picked " + sharedPreferences.getInt("p1Picked", 0));
Log.d("testing", "p1" + sharedPreferences.getString("p1", ""));
Log.d("testing", "p2Picked " + sharedPreferences.getInt("p2Picked", 0));
Log.d("testing", "p2" + sharedPreferences.getString("p2", ""));
Log.d("testing", "p3Picked " + sharedPreferences.getInt("p3Picked", 0));
Log.d("testing", "p3" + sharedPreferences.getString("p3", ""));
Log.d("testing", "p4Picked " + sharedPreferences.getInt("p4Picked", 0));
Log.d("testing", "p4" + sharedPreferences.getString("p4", ""));
} // on first run through, all logs are defaults reset in MainActivity
点击GameSetup活动中的按钮会调用.java类,以打开一个带有列表视图的警报对话框,以从ParseServer检索的玩家列表中进行选择-
public void selectionDialog (View view) {
CustomMethods.playerSelection(this);
}
通话-
public class CustomMethods {
static public String playerSelection (final Context context) {
final SharedPreferences sharedPreferences = context.getApplicationContext().getSharedPreferences("com.apps.letsplaydarts", Context.MODE_PRIVATE);
final SharedPreferences.Editor editor = sharedPreferences.edit(); // same declaration again - declared final for access in listeners
// alert dialog code removed
playerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (position == 0) {
Intent intent = new Intent(context, AddPlayer.class);
intent.putExtra("callingIntent", "Setup");
context.startActivity(intent);
} else {
playerToReturn[0] = playerList.get(position);
if (sharedPreferences.getInt("p1Picked", 0) == 0) {
editor.putInt("p1Picked", 1);
editor.putString("p1", playerToReturn[0]);
} else {
if (sharedPreferences.getInt("p2Picked", 0) == 0) {
editor.putInt("p2Picked", 1);
editor.putString("p2", playerToReturn[0]);
} else {
if (sharedPreferences.getInt("p3Picked", 0) == 0) {
editor.putInt("p3Picked", 1);
editor.putString("p3", playerToReturn[0]);
} else {
if (sharedPreferences.getInt("p4Picked", 0) == 0) {
editor.putInt("p4Picked", 1);
editor.putString("p4", playerToReturn[0]);
}
}
}
}
editor.apply();
Log.d("testing", "p1Picked " + sharedPreferences.getInt("p1Picked", 0));
Log.d("testing", "p1" + sharedPreferences.getString("p1", ""));
Log.d("testing", "p2Picked " + sharedPreferences.getInt("p2Picked", 0));
Log.d("testing", "p2" + sharedPreferences.getString("p2", ""));
Log.d("testing", "p3Picked " + sharedPreferences.getInt("p3Picked", 0));
Log.d("testing", "p3" + sharedPreferences.getString("p3", ""));
Log.d("testing", "p4Picked " + sharedPreferences.getInt("p4Picked", 0));
Log.d("testing", "p4" + sharedPreferences.getString("p4", ""));
Intent intent = new Intent(context, GameSetup.class);
intent.putExtra("callingIntent", "Select");
intent.putExtra("playerReturned", playerToReturn[0]);
context.startActivity(intent);
}
Log.i("Position Selected", Integer.toString(position));
}
});
现在...编码本身起作用了,在离开警报对话框之前已设置了适当的SP,但是当返回GameSetup活动并再次检查日志时,它仅显示与离开GameSetup之前日志相同的默认值,而不显示运行警报对话框时保存的文件。
我是否完全误解了SP的工作原理?还是在其他需要更改的示例中未使用过的
Context.MODE_PRIVATE
。我花了很长时间研究此问题,但并没有加深对SP功能的了解,但是根据我的经验,这应该可行。非常感谢您对此事的协助。谢谢。
AFTERTHOUGHT EDIT-可能是上下文在我在单独的.java类中运行代码时引起问题吗?直接通过GameSetup活动运行警报对话框代码可以解决我的问题吗?我使用.java类的原因是为了能够从其他活动进行调用。
根据要求的日志-从MainActivity加载GameSetup
11-01 19:55:44.449 22498-22498/com.app.letsplaydarts D/testing: p1Picked 0
11-01 19:55:44.449 22498-22498/com.app.letsplaydarts D/testing: p1
11-01 19:55:44.449 22498-22498/com.app.letsplaydarts D/testing: p2Picked 0
11-01 19:55:44.449 22498-22498/com.app.letsplaydarts D/testing: p2
11-01 19:55:44.449 22498-22498/com.app.letsplaydarts D/testing: p3Picked 0
11-01 19:55:44.449 22498-22498/com.app.letsplaydarts D/testing: p3
11-01 19:55:44.449 22498-22498/com.app.letsplaydarts D/testing: p4Picked 0
11-01 19:55:44.449 22498-22498/com.app.letsplaydarts D/testing: p4
在.java类警报对话框中选择玩家后-
these are NOT reset by the onCreate of MainActivity
11-01 19:55:50.168 22498-22498/com.app.letsplaydarts D/testing: p1Picked 1
11-01 19:55:50.168 22498-22498/com.app.letsplaydarts D/testing: p1[Les]
11-01 19:55:50.168 22498-22498/com.app.letsplaydarts D/testing: p2Picked 1
11-01 19:55:50.169 22498-22498/com.app.letsplaydarts D/testing: p2[Iain]
11-01 19:55:50.169 22498-22498/com.app.letsplaydarts D/testing: p3Picked 1
11-01 19:55:50.169 22498-22498/com.app.letsplaydarts D/testing: p3[Les]
11-01 19:55:50.169 22498-22498/com.app.letsplaydarts D/testing: p4Picked 1
11-01 19:55:50.169 22498-22498/com.app.letsplaydarts D/testing: p4[Les]
从.java类警报对话框返回GameSetup之后
11-01 19:55:50.212 22498-22498/com.app.letsplaydarts D/testing: p1Picked 0
11-01 19:55:50.212 22498-22498/com.app.letsplaydarts D/testing: p1
11-01 19:55:50.212 22498-22498/com.app.letsplaydarts D/testing: p2Picked 0
11-01 19:55:50.212 22498-22498/com.app.letsplaydarts D/testing: p2
11-01 19:55:50.212 22498-22498/com.app.letsplaydarts D/testing: p3Picked 0
11-01 19:55:50.212 22498-22498/com.app.letsplaydarts D/testing: p3
11-01 19:55:50.212 22498-22498/com.app.letsplaydarts D/testing: p4Picked 0
11-01 19:55:50.212 22498-22498/com.app.letsplaydarts D/testing: p4
已解决-由于我的一份SP声明中有错字。我是该社区的新手,因此请告知我是应该删除此问题还是保留此问题,以防其他人遇到该问题。作为记录,我从这篇文章中学到了很多。谢谢。
最佳答案
这些位于/data/data/tld.domain.package/shared_prefs/*.xml
和.onCreate(Bundle savedInstanceState)
中,检查savedInstanceState == null
...以确定何时启动Activity
-因为.onCreate(Bundle savedInstanceState)
的运行频率超过一次,这是造成混乱的常见原因。只需在其中设置一个断点,然后查看返回此Activity
时的作用即可。 SharedPreferences
和SharedPreferences.Editor
的文档对此进行了很好的解释-并且还可以使用registerOnSharedPreferenceChangeListener()
收听其他地方的更改。