Как приложения сохраняют данные

Это может быть глупым вопросом, а также может быть дубликатом. Но я действительно не знаю и не смог найти решение, вообще. У меня вопрос, как приложения сохраняют данные. Я делаю приложение с LibGDX и Java для устройств Android, и я просто задумываюсь над этим. Как, например, когда я закрываю Candy Crush и снова открываю его на следующий день, он вспоминает, где я нахожусь, даже если приложение перезагружается? Если это будет дубликат, я был бы очень признателен другому форуму и прошу прощения за дублирование. Я просто не смог найти. Заранее спасибо!

4 ответа

Решение

Это широкий вопрос, но я пытаюсь охватить элементы представления по теме. Candy Crush Sage сбрасывает себя, если вы не регистрируете или не связываете свою учетную запись с чем-то вроде Facebook и переустанавливаете приложение. Скорее всего, они используют базу данных для хранения вещей. Если вы не зарегистрированы, вещи могут просто храниться локально.

LibGDX предлагает удобную функцию для локального хранения данных. Он называется "Настройки", и вы просто пишете в него, и при следующем запуске приложения оно сохраняется.

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

Однако, когда вы удаляете эти данные, они идут вместе с ними, и они не очень безопасны для игроков, которым нравится "расследовать". Кроме того, вы можете хранить свои собственные созданные данные в каком-то месте. Если вы храните его вне внутреннего приложения, оно сохраняется даже после удаления приложения, и до тех пор, пока данные остаются и ваше приложение после переустановки выглядит в одном и том же месте, вы сможете получить данные. Но, как и следовало ожидать, это тоже не безотказно.

Единственный реальный способ убедиться в этом - иметь какой-то механизм входа в систему. Самый жизнеспособный способ - это база данных. У меня сейчас работает похожая система, но между клиентом и базой данных есть сервер. Вы можете хранить любые данные в базе данных и связывать их с игроком по его идентификатору.

  • Новые игроки могут выбрать игру в качестве гостя. Это создает новую учетную запись с "Guest" + id как имя Когда игрок связывает свою учетную запись с чем-то вроде Facebook или адресом электронной почты, учетная запись сохраняется, как и данные, связанные с ним.

  • Существующие игроки будут входить в систему, когда они устанавливают ваше приложение, и вы можете сохранять там данные для входа на свое устройство, чтобы они автоматически входили в систему, если эти данные существуют и действительны.

Для настройки базы данных я настоятельно рекомендую никогда не подключаться напрямую к базе данных через клиентское устройство. Либо есть веб-сервис, либо, как я сейчас делаю KryoNet сервер. Причина в том, что вам нужно очистить данные, поступающие от клиентов. Вы можете сделать это с клиентского устройства, но у вас нет полного контроля над этим. Делайте дезинфекцию пользовательского ввода всегда на стороне сервера.

Создать веб-сервис для подключения через базу данных довольно легко, если вы немного знаете PHP и mysql. Все, что вам нужно, это отправить 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");
            }
        });
    }
}

Поместите скрипт php под названием script.php в yourdomain.com и повторить что-то в этом. Тогда этот код должен получить это эхо внутри вашего приложения.

Вы также можете создать xml и проанализировать его с вашим любимым парсером. Но вы должны установить заголовок запроса, чтобы правильно получать 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-соединение. Вы в основном имеете гораздо больший контроль над тем, что обменивается.

Многие игры имеют разные подходы к этому в зависимости от их требований. Такие игры, как: Candy Crush, Age of War или Clash of Clans, хранят всю пользовательскую информацию в онлайн-базе данных. Информация о пользователе извлекается при запуске из указанной базы данных. Затем вы можете хранить эту информацию локально, чтобы она загружалась быстрее. Затем в следующий раз, когда вы запустите свое приложение, вы загрузите данные локально, а если не сможете, загрузите их снова с сервера. Вы можете отправлять новую информацию на сервер каждый раз, когда хотите сохранить состояние игры. Трудно дать вам конкретный ответ, не зная, какую игру вы делаете.

Вы должны прочитать этот пост: какую технику хранения данных Android использовать? В нем много информации для сохранения данных на андроид.

Синхронизация данных между Android-приложением и веб-сервером Еще одна хорошая статья для чтения. Он дает вам некоторую информацию о том, как синхронизировать данные, которые вы сохранили локально и на веб-сервере.

Облачное хранилище 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

Если, однако, вы просто делаете основную игру. Я рекомендую вам использовать локальную базу данных в сочетании с общими настройками.

Если вы храните данные только локально, есть вероятность получить "взломанный". Если у вас есть данные на сервере и локально, вы можете "рукопожатие" и проверить правильность данных.

Это зависит от того, что вы хотите сохранить. Есть много способов сохранить вещи, о которых упоминали другие. Если вы хотите сохранить только одну переменную на устройстве, используя преф, это, вероятно, будет лучшим выбором.


Вот как вы можете использовать прив.

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

Есть много способов сделать это.

Для некоторых онлайн-приложений они использовали сетевое соединение для связи со своими серверами, такими как онлайн-серверы MYSQL, веб-сервисы и так далее.

Для автономного приложения используются SQLite, SharedPreferences, Внутреннее и Внешнее хранилище.

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

Другие вопросы по тегам