Это может быть глупый вопрос, а также может быть дубликат. Но я действительно не знаю и вообще не мог найти решение. У меня вопрос, как приложения сохраняют данные. Я делаю приложение с 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);
Однако, когда вы удаляете, эти данные идут вместе с ним, и они не очень безопасны для игроков, которые любят «исследовать». Другое дело, что вы можете хранить свои собственные созданные данные в каком-то месте. Если вы храните его вне внутреннего приложения, он сохраняется даже после удаления приложения, и пока данные остаются, а ваше приложение выглядит в том же месте после переустановки, вы сможете получить данные. Но, как и следовало ожидать, это тоже не безотказно.
Единственный реальный способ убедиться - это иметь какой-то механизм входа в систему. Самый жизнеспособный способ - это база данных. У меня сейчас работает аналогичная система, но между клиентом и базой данных есть сервер. Вы можете хранить любые данные в базе и привязать их к игроку по его ID.
Новые игроки могут выбрать игру в качестве гостя. Будет создана новая учетная запись с именем
"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.
Синхронизация данных между приложением 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
Если, однако, вы просто делаете простую игру. Я рекомендую вам использовать локальную базу данных в сочетании с общими настройками.
Если вы храните данные только локально, есть вероятность «взлома». Если у вас есть данные на сервере и локально, вы можете «рукопожатие» и проверить правильность данных.
Есть много способов сделать это.
Для некоторых онлайн-приложений они использовали сетевое соединение для связи со своими серверами, такими как онлайн-серверы MYSQL, веб-службы и т. Д.
Для автономного приложения используются SQLite, SharedPreferences, внутреннее и внешнее хранилище.
http://developer.android.com/guide/topics/data/data-storage.html
Это зависит от того, что вы хотите спасти. Есть много способов сохранить вещи, о которых упоминали другие. Если вы хотите сохранить на устройстве только одну переменную, вам, вероятно, будет лучше всего использовать pref.
Вот как вы можете использовать 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
}