我最近编写了一个 Android 应用程序。它只是一个简单的应用程序,可让您通过几个简单的计数器间隔来记录篮球比赛的得分。我收到了添加保存功能的需求,这样您就可以保存您的分数,然后重新加载它们。目前,当您停止应用程序时,您的数据会丢失。所以我想知道的是我必须添加什么才能让应用程序保存标签(分数)然后重新加载它。谢谢大家,对不起,我对这些东西了解不多。
12 回答
你有两个选择,我会留给你选择。
共享偏好
这是一个 Android 独有的框架,允许您在键值框架中存储原始值(例如和
int
,虽然严格来说不是原始值)。这意味着您为一个值命名,例如“homeScore”并将该值存储到此键中。boolean,
String
String
SharedPreferences settings = getApplicationContext().getSharedPreferences(PREFS_NAME, 0); SharedPreferences.Editor editor = settings.edit(); editor.putInt("homeScore", YOUR_HOME_SCORE); // Apply the edits! editor.apply(); // Get from the SharedPreferences SharedPreferences settings = getApplicationContext().getSharedPreferences(PREFS_NAME, 0); int homeScore = settings.getInt("homeScore", 0);
内部存储器
在我看来,这就是您可能正在寻找的东西。您可以将所需的任何内容存储到文件中,因此这为您提供了更大的灵活性。但是,这个过程可能会比较棘手,因为所有内容都将存储为字节,这意味着您必须小心保持您的读取和写入进程一起工作。
int homeScore; byte[] homeScoreBytes; homeScoreBytes[0] = (byte) homeScore; homeScoreBytes[1] = (byte) (homeScore >> 8); //you can probably skip these two homeScoreBytes[2] = (byte) (homeScore >> 16); //lines, because I've never seen a //basketball score above 128, it's //such a rare occurance. FileOutputStream outputStream = getApplicationContext().openFileOutput(FILENAME, Context.MODE_PRIVATE); outputStream.write(homeScoreBytes); outputStream.close();
现在,您也可以查看External Storage,但我不建议在这种特殊情况下这样做,因为外部存储以后可能不存在。(注意,如果你选择这个,它需要一个权限)
OP 要求一个“保存”功能,这不仅仅是在程序执行期间保留数据(您必须这样做才能使应用程序有价值。)
我建议将数据保存在 sdcard 上的文件中,这样您不仅可以稍后调用它,还可以让用户将设备作为外部驱动器安装在自己的计算机上并获取数据以在其他地方使用。
所以你真的需要一个多点系统:
1)实施onSaveInstanceState()
。在这个方法中,你被传递了一个Bundle,它基本上就像一个字典。在捆绑包中存储尽可能多的信息,以便在应用程序停止的位置重新启动应用程序。在您的onCreate()
方法中,检查传入的捆绑包是否为非空,如果是,则从捆绑包中恢复状态。
2) 实施onPause()
。在此方法中,创建一个 SharedPreferences 编辑器并使用它来保存您下次启动应用程序所需的任何状态。这主要包括用户的偏好(因此得名),但与应用程序的启动状态相关的任何其他内容也应该放在此处。我不会在这里存储分数,只是你需要重新启动应用程序的东西。然后,在 中onCreate()
,只要没有捆绑对象,就使用 SharedPreferences 接口来调用这些设置。
3a) 至于分数之类的东西,你可以按照上面 Mathias 的建议,将分数存储在返回的目录中getFilesDir()
,使用openFileOutput()
等。我认为这个目录是应用程序私有的,并且存在于主存储中,这意味着其他应用程序和用户将无法访问数据。如果你没问题,那么这可能是要走的路。
3b)如果您确实希望其他应用程序或用户可以直接访问数据,或者如果数据将非常大,那么 sdcard 就是要走的路。选择一个目录名称,如 com/user1446371/basketballapp/ 以避免与其他应用程序冲突(除非您确定您的应用程序名称是合理唯一的)并在 sdcard 上创建该目录。正如 Mathias 所指出的,您应该首先确认 sdcard 已安装。
File sdcard = Environment.getExternalStorageDirectory();
if( sdcard == null || !sdcard.isDirectory()) {
fail("sdcard not available");
}
File datadir = new File(sdcard, "com/user1446371/basketballapp/");
if( !datadir.exists() && !datadir.mkdirs() ) {
fail("unable to create data directory");
}
if( !datadir.isDirectory() ) {
fail("exists, but is not a directory");
}
// Now use regular java I/O to read and write files to data directory
我建议为您的数据使用简单的 CSV 文件,以便其他应用程序可以轻松读取它们。
显然,您必须编写允许“保存”和“打开”对话框的活动。我通常只是调用 openintents 文件管理器并让它完成工作。但是,这需要您的用户安装 openintents 文件管理器才能使用这些功能。
在 onCreate 中:
SharedPreferences sharedPref = getSharedPreferences("mySettings", MODE_PRIVATE);
String mySetting = sharedPref.getString("mySetting", null);
在 onDestroy 或等效项中:
SharedPreferences sharedPref = getSharedPreferences("mySettings", MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString("mySetting", "Hello Android");
editor.commit();
使用 SharedPreferences,http://developer.android.com/reference/android/content/SharedPreferences.html
这是一个示例:http: //developer.android.com/guide/topics/data/data-storage.html#pref
如果数据结构比较复杂或者数据量大,使用Sqlite数据库;但是对于少量数据和非常简单的数据结构,我会说,SharedPrefs 会做,并且数据库可能是开销。
有很多选项可以存储您的数据,Android 让您可以选择任何人您的数据存储选项如下:
Shared Preferences 将私有原始数据存储在键值对中。内部存储 将私人数据存储在设备内存中。外部存储 将公共数据存储在共享的外部存储上。SQLite 数据库将结构化数据存储在私有数据库中。网络连接 使用您自己的网络服务器在 Web 上存储数据
在此处查看示例和教程
2021答案
老问题,但在 2021 年,您可以使用多种方法来保存数据。
1. 使用本地数据库- Room Library
Room 是一个库,可让您将数据存储在 Android 设备附带的内部 SqlLite 数据库中,它是一个本地数据库。这很容易而且非常强大。
https://developer.android.com/training/data-storage/room
2. 使用远程数据库- Firebase / 你自己的数据库实现
您可以在服务器上使用 Firebase 服务或您自己的数据库实现来远程存储您的数据,这样您就可以通过多个设备访问数据。
https://firebase.google.com/docs/firestore
3. 存储本地文件
您可以将所有信息存储在设备外部存储中保存的本地文件中,可能使用带有 \n 作为数据分隔符的 .txt 文件。这个选项在 2021 年看起来真的很“穴居人”。
https://stackoverflow.com/a/14377185/14327871
4. 使用 SharedPreferences
正如许多人指出的那样,您还可以使用 sharedPreferences 将少量信息存储为键值对,例如在跨会话保存用户首选项时很有用。
https://developer.android.com/training/data-storage/shared-preferences?hl=en
对于 OP 案例,我建议使用第一个或第二个选项。
共享偏好: 高分的android共享偏好示例?
您的应用程序是否可以访问“外部存储媒体”。如果是这样,那么您可以简单地将值(将其与时间戳一起存储)写入文件并保存。如果这就是您要查找的内容,时间戳将帮助您显示进度。{不是一个聪明的解决方案。}
请不要忘记一件事 - 卸载应用程序时会删除内部存储数据。在某些情况下,它可能是“意外功能”。然后最好使用外部存储。
关于存储的 Google 文档- 请特别查看 getExternalStoragePublicDirectory
快速回答:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Boolean Music;
public static final String PREFS_NAME = "MyPrefsFile";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//restore preferences
SharedPreferences settings = this.getSharedPreferences(PREFS_NAME, 0);
Music = settings.getBoolean("key", true);
}
@Override
public void onClick() {
//save music setup to system
SharedPreferences settings = this.getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("key", Music);
editor.apply();
}
}
您可以存储您的分数并轻松加载它们!通过使用此方法 使用此库Paper Db
在您的应用中添加此库:
implementation 'io.github.pilgr:paperdb:2.7.1'
然后在您存储的活动 onCreate() 中对其进行一次初始化:
Paper.init(context)
创建一个密钥来存储你的分数
int myScore=10;
Paper.book().write("scores", myScore);
并获得 score 的值:
int mySavedScores=Paper.book().read("scores");
而已!!!现在即使应用程序关闭,您也可以保存和访问该值,并参考文档以获取更多方法和信息,阅读文档是一个好习惯。
在我看来,db4o 是最简单的方法。在这里你可以找到一个教程:http: //community.versant.com/documentation/reference/db4o-7.12/java/tutorial/
在这里你可以下载图书馆:
http://www.db4o.com/community/download.aspx?file=db4o-8.0-java.zip
(只需将lib目录下的db4o-8.0...-all-java5.jar放到你项目的libs文件夹中。如果你的项目中没有libs文件夹就创建它)
由于 db4o 是一个面向对象的数据库系统,您可以直接将对象保存到数据库中,然后再将它们取回。
使用此方法可以非常轻松地使用 sharedPreferences。
private val sharedPreferences = context.getSharedPreferences("myPreferences", Context.MODE_PRIVATE)
fun put(key: String, value: String) = sharedPreferences.edit().putString(key, value).apply()
fun put(key: String, value: Int) = sharedPreferences.edit().putInt(key, value).apply()
fun put(key: String, value: Float) = sharedPreferences.edit().putFloat(key, value).apply()
fun put(key: String, value: Boolean) = sharedPreferences.edit().putBoolean(key, value).apply()
fun put(key: String, value: Long) = sharedPreferences.edit().putLong(key, value).apply()
fun getString(key: String, defaultValue: String? = null): String? = sharedPreferences.getString(key, defaultValue)
fun getInt(key: String, defaultValue: Int = -1): Int = sharedPreferences.getInt(key, defaultValue)
fun getFloat(key: String, defaultValue: Float = -1F): Float = sharedPreferences.getFloat(key, defaultValue)
fun getBoolean(key: String, defaultValue: Boolean = false): Boolean = sharedPreferences.getBoolean(key, defaultValue)
fun getLong(key: String, defaultValue: Long = -1L): Long = sharedPreferences.getLong(key, defaultValue)
fun clearAll() = sharedPreferences.edit().clear().apply()
将它们放在一个类中并在其构造函数中获取上下文。