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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10962344/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:34:56  来源:igfitidea点击:

How to save data in an android app

android

提问by user1446371

I recently coded an Android app. It's just a simple app that allows you to keep score of a basketball game with a few simple counter intervals. I'm getting demand to add a save feature, so you can save your scores and then load them back up. Currently, when you stop the app, your data is lost. So what I was wondering is what I would have to add to have the app save a label (score) and then load it back up. Thanks guys sorry I don't know much about this stuff.

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

回答by gobernador

You have two options, and I'll leave selection up to you.

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

  1. Shared Preferences

    This is a framework unique to Android that allows you to store primitive values (such as int, boolean,and String, although strictly speaking Stringisn't a primitive) in a key-value framework. This means that you give a value a name, say, "homeScore" and store the value to this key.

    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. Internal Storage

    This, in my opinion, is what you might be looking for. You can store anything you want to a file, so this gives you more flexibility. However, the process can be trickier because everything will be stored as bytes, and that means you have to be careful to keep your read and write processes working together.

    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();
    
  1. 共享偏好

    这是 Android 独有的框架,它允许您在键值框架中存储原始值(例如int,boolean,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();
    

Now, you can also look into External Storage, but I don't recommend that in this particular case, because the external storage might not be there later. (Note that if you pick this, it requires a permission)

现在,您还可以查看External Storage,但在这种特殊情况下,我不建议这样做,因为外部存储可能不会在以后出现。(请注意,如果您选择此项,则需要获得许可)

回答by Edward Falk

OP is asking for a "save" function, which is more than just preserving data across executions of the program (which you must do for the app to be worth anything.)

OP 要求“保存”功能,这不仅仅是在程序执行过程中保留数据(您必须这样做才能使应用程序有价值。)

I recommend saving the data in a file on the sdcard which allows you to not only recall it later, but allows the user to mount the device as an external drive on their own computer and grab the data for use in other places.

我建议将数据保存在 sdcard 上的文件中,这样您不仅可以在以后调用它,而且还允许用户将设备作为外部驱动器安装在自己的计算机上,并获取数据以供其他地方使用。

So you really need a multi-point system:

所以你真的需要一个多点系统:

1) Implement onSaveInstanceState(). In this method, you're passed a Bundle, which is basically like a dictionary. Store as much information in the bundle as would be needed to restart the app exactly where it left off. In your onCreate()method, check for the passed-in bundle to be non-null, and if so, restore the state from the bundle.

1) 实施onSaveInstanceState()。在这个方法中,你传递了一个 Bundle,它基本上就像一本字典。将尽可能多的信息存储在捆绑包中,以便从停止的地方重新启动应用程序。在您的onCreate()方法中,检查传入的包是否为非空,如果是,则从包中恢复状态。

2) Implement onPause(). In this method, create a SharedPreferences editor and use it to save whatever state you need to start the app up next time. This mainly consists of the users' preferences (hence the name), but anything else relavent to the app's start-up state should go here as well. I would notstore scores here, just the stuff you need to restart the app. Then, in onCreate(), whenever there's no bundle object, use the SharedPreferences interface to recall those settings.

2) 实施onPause()。在此方法中,创建一个 SharedPreferences 编辑器并使用它来保存下次启动应用程序所需的任何状态。这主要包括用户的偏好(因此得名),但与应用程序启动状态相关的任何其他内容也应放在此处。我不会在这里存储分数,只存储重新启动应用程序所需的东西。然后,在 中onCreate(),只要没有包对象,就使用 SharedPreferences 接口调用这些设置。

3a) As for things like scores, you could follow Mathias's advice above and store the scores in the directory returned in getFilesDir(), using openFileOutput(), etc. I think this directory is private to the app and lives in main storage, meaning that other apps and the user would not be able to access the data. If that's ok with you, then this is probably the way to go.

3a) 至于分数之类的东西,你可以按照上面 Mathias 的建议,把分数存储在返回的目录中getFilesDir(),使用openFileOutput()等。我认为这个目录是应用程序私有的,存在于主存储中,这意味着其他应用程序和用户将无法访问数据。如果这对你没问题,那么这可能是要走的路。

3b) If you do want other apps or the user to have direct access to the data, or if the data is going to be very large, then the sdcard is the way to go. Pick a directory name like com/user1446371/basketballapp/ to avoid collisions with other applications (unless you're sure that your app name is reasonably unique) and create that directory on the sdcard. As Mathias pointed out, you should first confirm that the sdcard is mounted.

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

I recommend simple CSV files for your data, so that other applications can read them easily.

我建议为您的数据使用简单的 CSV 文件,以便其他应用程序可以轻松读取它们。

Obviously, you'll have to write activities that allow "save" and "open" dialogs. I generally just make calls to the openintents file manager and let it do the work. This requires that your users install the openintents file manager to make use of these features, however.

显然,您必须编写允许“保存”和“打开”对话框的活动。我通常只是调用 openintents 文件管理器并让它完成工作。但是,这需要您的用户安装 openintents 文件管理器才能使用这些功能。

回答by Martin.Martinsson

In onCreate:

在 onCreate 中:

SharedPreferences sharedPref = getSharedPreferences("mySettings", MODE_PRIVATE);

    String mySetting = sharedPref.getString("mySetting", null);

In onDestroy or equivalent:

在 onDestroy 或同等条件下:

SharedPreferences sharedPref = getSharedPreferences("mySettings", MODE_PRIVATE);

    SharedPreferences.Editor editor = sharedPref.edit();
    editor.putString("mySetting", "Hello Android");
    editor.commit();

回答by Mathias Conradt

Use SharedPreferences, http://developer.android.com/reference/android/content/SharedPreferences.html

使用 SharedPreferences,http://developer.android.com/reference/android/content/SharedPreferences.html

Here's a sample: http://developer.android.com/guide/topics/data/data-storage.html#pref

这是一个示例:http: //developer.android.com/guide/topics/data/data-storage.html#pref

If the data structure is more complex or the data is large, use an Sqlitedatabase; but for small amount of data and with a very simple data structure, I'd say, SharedPrefs will do and a DB might be overhead.

如果数据结构比较复杂或者数据比较大,使用Sqlite数据库;但是对于少量数据和非常简单的数据结构,我想说,SharedPrefs 会做,一个 DB 可能是开销。

回答by Mohamed ALOUANE

There is a lot of options to store your data and Android offers you to chose anyone Your data storage options are the following:

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

Shared Preferences Store private primitive data in key-value pairs. Internal Storage Store private data on the device memory. External Storage Store public data on the shared external storage. SQLite Databases Store structured data in a private database. Network Connection Store data on the web with your own network server

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

Check herefor examples and tuto

检查这里的例子和政党成员

回答by redM0nk

  1. Shared preferences: android shared preferences example for high scores?

  2. Does your application has an access to the "external Storage Media". If it does then you can simply write the value (store it with timestamp) in a file and save it. The timestamp will help you in showing progress if thats what you are looking for. {not a smart solution.}

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

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

回答by fivef

In my opinion db4o is the easiest way to go. Here you can find a tutorial: http://community.versant.com/documentation/reference/db4o-7.12/java/tutorial/

在我看来,db4o 是最简单的方法。在这里你可以找到一个教程:http: //community.versant.com/documentation/reference/db4o-7.12/java/tutorial/

And here you can download the library:

您可以在这里下载库:

http://www.db4o.com/community/download.aspx?file=db4o-8.0-java.zip

http://www.db4o.com/community/download.aspx?file=db4o-8.0-java.zip

(Just put the db4o-8.0...-all-java5.jar in the lib directory into your project's libs folder. If there is no libs folder in you project create it)

(只要把lib目录下的db4o-8.0...-all-java5.jar放到你项目的libs文件夹中。如果你的项目中没有libs文件夹,就创建它)

As db4o is a object oriented database system you can directly save you objects into the database and later get them back.

由于 db4o 是一个面向对象的数据库系统,您可以直接将对象保存到数据库中,然后再将它们取回。

回答by myworldbox

Quick answer:

快速回答:

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

回答by SinaMN75

use this methods to use sharedPreferences very easily.

使用此方法可以非常轻松地使用 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()

put them in a class and get context in its constructor.

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

回答by user2707175

Please don't forget one thing - Internal Storage data are deleted when you uninstall the app. In some cases it can be "unexpected feature". Then it's good to use external storage.

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

Google docs about storage- Please look in particular at getExternalStoragePublicDirectory

关于存储的 Google 文档- 请特别查看 getExternalStoragePublicDirectory