繁体   English   中英

如何在Android应用程序中保存数据

[英]How to save data in an android app

我最近编写了一个 Android 应用程序。 它只是一个简单的应用程序,可让您通过几个简单的计数器间隔来保持篮球比赛的得分。 我收到了添加保存功能的需求,这样您就可以保存您的乐谱,然后重新加载它们。 目前,当您停止应用程序时,您的数据将丢失。 所以我想知道的是我必须添加什么才能让应用程序保存标签(分数)然后重新加载它。 谢谢各位,抱歉,我对这些东西了解不多。

你有两个选择,我会留给你选择。

  1. 共享偏好

    这是 Android 独有的框架,允许您在键值框架中存储原始值(例如intboolean,String ,尽管严格来说String不是原始值)。 这意味着您给一个值命名,例如“homeScore”并将该值存储到该键中。

     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);
  2. 内部存储器

    在我看来,这就是您可能正在寻找的。 您可以将任何您想要的内容存储到文件中,因此这为您提供了更大的灵活性。 但是,这个过程可能会更棘手,因为所有内容都将存储为字节,这意味着您必须小心保持读取和写入过程协同工作。

     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/ 以避免与其他应用程序发生冲突(除非您确定您的应用程序名称相当独特)并在 SD 卡上创建该目录。 正如 Mathias 所指出的,您应该首先确认已安装 SD 卡。

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 会做,一个 DB 可能是开销。

有很多选项可以存储您的数据,Android 允许您选择任何人您的数据存储选项如下:

共享首选项将私有原始数据存储在键值对中。 内部存储 将私人数据存储在设备内存中。 外部存储将公共数据存储在共享的外部存储上。 SQLite 数据库将结构化数据存储在私有数据库中。 网络连接 使用您自己的网络服务器在网络上存储数据

在此处查看示例和教程

  1. 共享偏好: 高分的android共享偏好示例?

  2. 您的应用程序是否可以访问“外部存储介质”。 如果是这样,那么您可以简单地将值(使用时间戳存储)写入文件并保存。 如果那是您正在寻找的,时间戳将帮助您显示进度。 {不是一个聪明的解决方案。}

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 情况,我建议使用第一个或第二个选项。

请不要忘记一件事 - 卸载应用程序时会删除内部存储数据。 在某些情况下,它可能是“意外功能”。 那么最好使用外部存储。

关于存储的 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);

并获得分数的值:

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()

将它们放在一个类中并在其构造函数中获取上下文。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM