应用程序如何保存数据

How do apps save data

这可能是个愚蠢的问题,也可能是重复的。但是,我真的不知道,也根本找不到解决办法。我的问题是,应用程序如何保存数据。我正在为 Android 设备制作一个带有 LibGDX 和 Java 的应用程序,我一直在思考这个问题。例如,当我关闭 Candy Crush 并在第二天重新打开它时,它是如何记住我所在的位置的,即使应用程序已重置?如果这确实是重复的,我会非常感谢其他论坛,并为重复道歉。我只是没能找到一个。提前致谢!

有很多方法可以做到这一点。

对于某些在线应用程序,他们使用网络连接与其服务器进行通信,例如在线 MYSQL 服务器、Web 服务等。

对于离线应用,使用SQLite、SharedPreferences、内部和外部存储。

http://developer.android.com/guide/topics/data/data-storage.html

很多游戏根据自己的要求采用不同的方法。像 Candy Crush、Age of War 或 Clash of Clans 这样的游戏,所有用户信息都存储在在线数据库中。用户信息在启动时从所述数据库中获取。然后,您可以在本地存储该信息,以便加载速度更快。然后下次你启动你的应用程序时,你在本地加载数据,如果你不能,再次从服务器加载它。您可以在每次要保存游戏状态时向服务器推送新信息。不知道你在做什么样的游戏,很难给你一个具体的答案。

你应该通读这篇文章post: Which Android Data Storage Technique to use? 它有很多关于 android 上保存数据的信息。

Sync data between Android App and webserver 又是一篇不错的 post 通读。它为您提供了一些有关如何同步保存在本地和 Web 服务器上的数据的信息。

Google云存储也是另一种选择: https://cloud.google.com/solutions/mobile/how-to-build-mobile-app-with-app-engine-backend-tutorial/

Google 还提供游戏存档服务: https://developers.google.com/games/services/common/concepts/savedgames?hl=en

如果您只是制作基本游戏。我建议您将本地数据库与共享首选项结合使用。

如果您只在本地存储数据,则有可能获得 "Hacked"。如果你在服务器和本地都有数据,你可以"handshake"检查数据是否正确。

这是一个广泛的问题,但我试图涵盖有关该主题的视图元素。如果您未注册或未将您的帐户与 Facebook 等网站相关联并重新安装该应用程序,Candy Crush Sage 会自行重置。他们很可能使用数据库来存储东西。如果你没有注册,东西可能只是存储在本地。

LibGDX 提供了一个方便的本地存储数据的功能。它称为首选项,您只需写入它,下次打开您的应用程序时它就会持续存在。

Preferences pref = Gdx.app.getPreferences("somefile");
pref.putString("name", "Menyo");
pref.putInteger("level", 20);

然而,当您卸载时,这些数据会随之消失,对于喜欢 "investigate" 的玩家来说,它也不是很安全。除此之外,您可以将自己创建的数据存储在某个地方。如果您将它存储在内部应用程序之外,即使在删除应用程序后它仍然存在,并且只要数据保留并且您的应用程序在重新安装后看起来在同一位置,您就应该能够检索数据。但正如您所料,这也不是 fail-proof。

确保的唯一真正方法是拥有某种登录机制。最可行的方法是数据库。我现在有一个类似的系统 运行 但在客户端和数据库之间有一个服务器。您可以将任何数据存储在数据库中,然后 link 通过玩家 ID 将其发送给玩家。

  • 新玩家可以选择以访客身份玩。这将创建一个名称为 "Guest" + id 的新帐户。当玩家 link 使用 Facebook 或电子邮件地址之类的帐户时,该帐户将持续存在,因此 link 向其输入的数据也会如此。

  • 现有玩家将在他们安装您的应用程序时登录,您可以将登录信息存储在该设备上,以便他们在该数据存在且有效时自动登录.

要设置数据库,我强烈建议永远不要通过客户端设备直接连接到数据库。要么有一个网络服务,要么像我目前正在做一个 KryoNet 服务器。这里的原因是您需要清理来自客户端的数据。您可以从客户端设备执行此操作,但您无法完全控制它。始终在服务器端对用户输入进行清理。

如果您了解一点 PHP 和 mysql,创建一个通过数据库连接的 Web 服务是非常容易的。您只需要将 HttpRequest 发送到 php 页面并让它完成工作即可。

public class WebTest {
    HttpRequestBuilder builder;
    Net.HttpRequest request;

    public WebTest()
    {
        builder = new HttpRequestBuilder();
        request = builder.newRequest().method(Net.HttpMethods.GET).url("http://yourdomain.com/script.php").build();
        request.setHeader("Content-Type", "application/x-www-form-urlencoded");


        final long start = System.nanoTime();
        Gdx.net.sendHttpRequest(request, new Net.HttpResponseListener() {
            @Override
            public void handleHttpResponse(Net.HttpResponse httpResponse) {
                Gdx.app.log("Test", "HTTP Response code: " + httpResponse.getStatus().getStatusCode());
                Gdx.app.log("Test", "HTTP Response code: " + httpResponse.getResultAsString());
                Gdx.app.log("Test", "Response time: " + ((System.nanoTime() - start) / 1000000) + "ms");
            }

            @Override
            public void failed(Throwable t) {
                Gdx.app.log("Test", "HTTP request failed");
            }

            @Override
            public void cancelled() {
                Gdx.app.log("Test", "HTTP request cancelled");
            }
        });
    }
}

将名为 script.php 的 php 脚本放入 yourdomain.com 并在其中回显一些内容。那么这段代码应该会在您的应用程序中接收到该回显。

您还可以创建 xml 并使用您喜欢的解析器对其进行解析。但是你必须设置请求的 header 才能正确接收 xml。

request.setHeader("Content-Type", "text/xml");

这是一个 PHP MySQL 连接,它在 XML 中发送反馈。

<?php
$link = mysqli_connect("127.0.0.1", "root", "", "chatapp");
$xml = new SimpleXMLElement("<?xml version=\"1.0\" encoding=\"utf-8\" ?><mysql></mysql>");
if (!$link)
{
    $xml->addChild("error", "Error: Unable to connect to MySQL.");
    $xml->addChild("error", "Debugging errno: " . mysqli_connect_errno());
    $xml->addChild("error", "Debugging error: " . mysqli_connect_error());
    exit;
}

$xml->addChild("success", "Success: A proper connection to MySQL was made!");
$xml->addChild("success", "Host information: " . mysqli_get_host_info($link));

//Sends the xml to whoever requested this
print($xml->asXML());

mysqli_close($link);
?>

现在您可以简单地使用 PHP 将用户登录到数据库,就像您在普通网页上所做的那样。有很多 php 教程涵盖了这个主题。当然,您可以为此使用任何服务器端脚本。

您自己的服务器也可以连接到数据库,但需要做更多的工作。但是 KryoNet 需要你做很多工作。您自己的服务器确实意味着您可以在服务器上存储数据并通过 TCP 或 UDP 连接非常快速地交换这些数据。您基本上可以更好地控制所交换的内容。

这取决于你想保存什么。有很多方法可以像其他人提到的那样保存东西。如果您只想将一个变量保存到设备,使用 pref 可能是您最好的选择。


以下是使用首选项的方法。

//This is how you can store a boolean, using a pref
SharedPreferences prefs = getSharedPreferences("BOOL", MODE_PRIVATE);
        SharedPreferences.Editor editor = prefs.edit();
        editor.putBoolean("ads", showAds);
        editor.commit();

`//showAds is a boolean that you are storing

你可以像这样创建一个函数来检索存储的布尔值

public boolean checkStoredBool(){
        SharedPreferences prefs = getSharedPreferences("BOOL", MODE_PRIVATE);
        boolean extractedBool = prefs.getBoolean("ads", false);
        return extractedBool;
    }

//The false in the previous code, is what would be called in if no value was stored

您要确保在创建 SharedPreferences 时,引号中的部分与您在存储布尔值时放入代码中的内容相匹配。

此外,当调用 prefs.getBoolean 时,引号中的部分需要与您之前使用 editor.putBoolean 时引号中的内容相匹配


现在在您的代码中,如果您想调用保存的代码,只需调用该方法即可。

例如,如果您想要一个 if 语句来检查存储的值是真还是假,它看起来像这样

if(checkStoredBool() == true){
    //code when it's true
}
else{
    //code when it's false
}