【问题标题】:How do apps save data应用程序如何保存数据
【发布时间】:2015-12-13 19:25:57
【问题描述】:

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

【问题讨论】:

  • 它有很多方法可以做到这一点......来自 Candy Crush......这是简单的“Web 服务”,他们通过将数据从服务器传递到应用程序来“记住”状态。其他方法是使用 SharedPreference 或使用目录文件夹将数据保存在 SD 卡上。 SQL 是另一种选择。关键是...没有唯一的方法,保存数据的最佳方法是适合您的方法。
  • 你有没有在你的电脑上玩过任何游戏。游戏如何记住您的级别以及您的分数。为什么 Android Java 或 Native Java 应该有任何不同,并且不能远程或在设备上存储数据并在应用程序启动时检索它。它不是魔法,它只是一种编程语言,就像其他任何语言一样。

标签: android libgdx saving-data


【解决方案1】:

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

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

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

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

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

  • 新玩家可以选择以访客身份进行游戏。这将创建一个以 "Guest" + id 为名称的新帐户。当玩家将其帐户链接到 Facebook 或电子邮件地址之类的东西时,该帐户将保持不变,与之关联的数据也将保持不变。

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

    李>

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

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

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 并使用您喜欢的解析器对其进行解析。但是您必须设置请求的标头才能正确接收xml。

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

这是一个以 XML 格式发送反馈的 PHP MySQL 连接。

<?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 连接快速交换这些数据。您基本上可以更好地控制正在交换的内容。

【讨论】:

  • 我个人在 Android 端使用 Realm。这是一个让生活变得非常简单的 ORM。 realm.io 您还可以使用 java 序列化来存储和 ecnrypt 对象。我只是想提供一些替代建议。尽管并没有过度推荐序列化,但它作为一种选择很有趣。 developer.android.com/reference/java/io/Serializable.html
【解决方案2】:

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

您应该阅读这篇文章: Which Android Data Storage Technique to use? 它有很多关于在an​​droid上保存数据的信息。

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

谷歌云存储也是另一种选择: 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

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

如果您只在本地存储数据,则有可能被“黑客入侵”。如果您在服务器和本地都有数据,您可以“握手”并检查数据是否正确。

【讨论】:

    【解决方案3】:

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

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

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

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

    【讨论】:

      【解决方案4】:

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


      这是使用首选项的方法。

      //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
      }
      

      【讨论】:

      • 我要制作一个游戏有不同的关卡和解锁的关卡选择项目、成就、总积分等。所以一系列变量和数组。
      • 我添加了一些关于如何使用首选项的更多细节。让我知道这是否有帮助。我知道有点晚了。或者非常晚。
      猜你喜欢
      • 2011-07-04
      • 1970-01-01
      • 2013-05-05
      • 1970-01-01
      • 2011-11-05
      • 2014-09-26
      • 2021-02-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多