Android의 OS / 사용자에 의한 게임 충돌 / 킬에서 파일 작업 실패


13

내 게임은 게임 / 앱 내부 저장소의 파일에 고정 간격 후에 상태를 저장합니다. 내 게임이 사용자 또는 OS에 의해 각각 죽거나 추락되면, 우리는 그 파일에 현재 게임 상태를 기록합니다. 수정 간격 후 파일 쓰기가 제대로 작동하지만 OS 또는 사용자가 게임을 중단 / 킬하면 파일 쓰기 작업이 실패합니다. 작업 실패로 인해 게임 상태가 불완전하거나 게임 상태가 비어 있습니다. 즉, 파일에 데이터가 전혀 기록되지 않았습니다. 안드로이드 서비스를 사용하여 여러 솔루션을 시도했습니다. 서비스가 NON STICKY 인 경우 서비스가 앱으로 종료됩니다. 반면에 서비스가 STICKY이면 서비스가 다시 시작되지만 처음에 서비스에 첨부 된 의도는 null이거나 새로운 것입니다.

문제는 내 게임 / 앱이 사용자 / OS에 의해 죽일 때 어떻게 내 데이터를 (2-3MB 일 수 있음) 내부 저장소의 파일에 완전히 저장할 수 있습니까?


SIGTERM과 SIGKILL을 처리해야합니다 (SIGKILL이 아닐 수도 있습니다 .Android는 아마도 SIGTERM을 사용하고 있습니다). (연구 할 시간이없고 완전한 답을 쓸 수는 있지만 기본 아이디어입니다.)
John Hamilton

2
@JohnHamilton SIGKILL은 정의에 따라 처리 할 수 ​​없습니다.
Darkhogg

@Darkhogg 글쎄, Unity가 아닌 것은 확실합니다. (이 특정 목적을 위해 프로젝트를 위해 한 시점에서 리눅스 커널을 변경했으며 프로그램이 SIGKILL을 처리하게 할 수 있습니다.)
John Hamilton

답변:


20

과거의 콘솔 타이틀에서와 같이 저장 상태를 이중 버퍼 방식으로 쓰는 것이 좋습니다 (쓰기 중 메모리 카드를 제거하고 쓰기 속도가 느려진 문제에 대처해야 함).

저장:

  • 파일이 없으면 파일 A에 상태를 씁니다.
  • A가 존재하면 B에 쓰십시오.
  • A와 B가 둘 다 존재하는 경우 이전 버전 중 하나를 찾아서 삭제 한 다음 쓰기

하중:

  • A와 B가 모두 존재하면 둘 중 최신을로드하십시오. 실패하면 (파일이 불완전하거나 손상되어) 삭제 한 후 다른 파일을로드하십시오
  • 하나만 존재하면로드
  • 둘 다 손상된 경우 저장 상태를 검색 할 수 없음을 사용자에게 알립니다 (아마도 이미 가지고 있어야 함)

이 흐름은 앱이 쓰기 도중 종료 되더라도 스토리지에 항상 하나 이상의 유효한 저장이 여전히 존재하도록 보장합니다. 이러한 종류의 오류가 발생하면 이전 저장 이후 플레이어는 게임 상태에서 변경 사항을 얻지 못하지만 다시 시작할 필요는 없습니다.

또한 충돌 / 킬 (kill / kill)로 인해 해당 키 이벤트가 손실되는 취약점의 창을 최소화하기 위해 간격 절약 외에도 주요 이벤트 (예 : 인앱 구매) 직후에 저장해야합니다. 또한 게임 악용으로부터 보호합니다 (예 : 생명을 잃기 전부터 게임 상태로 복원하고 다시 시도하기 때문에 생명을 잃은 후 앱 강제 종료). 물론 이렇게하면 "저장이 이미 진행중인 경우 다시 저장을 시작하지 마십시오"라는 논리를 사용하여 간격 저장을 보호해야합니다.


감사합니다 MrCranky 이것은 내 문제에 대한 부분적인 해결책입니다. 앱 / 게임을 죽이기 직전에 마지막 세션의 데이터를 어떻게 저장할 수 있습니까? 예를 들어 그는 앱을 구매하고 앱을 종료했습니다.
파이살 이므 란

12
두 개의 파일도 필요하지 않습니다. 쓰기가 성공한 경우에만 B에 쓰십시오. A를 삭제하고 B의 이름을 A로 바꾸십시오. java.nio.file.Files.move(Path source, Path target, CopyOption... options)이름 바꾸기 및 원자 적 조작으로 겹쳐 쓰기를 수행 할 수 있습니다.
Polygnome

6
@Polygnome : 정전시 sync()파일 A를 파일 A로 옮기기 전에 파일 B 를 호출하지 않는 한 (예 : 완전한 보증이 없지만 sync()상당히 양호 함) 항상 예상 한 보장을 제공 하지는 않습니다 .
Dietrich Epp

1
@FaisalImran 중요한 작업 직후 (예 : IAP) 후 데이터를 저장합니다. 전화가 꺼지면서 작업이 중단되면 어쨌든 그 사람에게서 돈을받지 않을 것입니다. 그러나 경우에 따라 무언가를 구매하기 위해 계정 데이터를 일부 플랫폼의 구매에 저장하려고 할 수 있습니다. 그런 다음 나중에 수입을 해당 데이터와 비교하여이 사람이 실제로 무언가를 구입했는지 확인할 수 있습니다. 그런 다음 모든 데이터를 저장하는 데 사용하는 온라인 서비스를 통해이 기능을 엽니 다. IAP에 로컬 저장을 사용하는 경우이 문제보다 더 나쁩니다.
솔직한 달 _Max_

1
마지막으로,이 방법으로 모든 문제를 해결할 수는 없지만 문제를 완전히 해결할 수는 없습니다. "사용자가 언제든지 내 앱을 종료 할 수 있습니다"와 "데이터를 잃어 버릴 필요가 없습니다"를 모두 지원할 수는 없습니다. 앱을 종료하고 데이터를 잃을 수 있습니다.
MrCranky

3

Android는 백그라운드에있을 때만 앱을 종료합니다. 앱이 백그라운드에있을 때 게임 데이터를 실제로 업데이트해야합니까, 아니면 앱이 포 그라운드로 돌아올 때까지 데이터 업데이트를 중지 할 수 있습니까? 이벤트 내역을 확인하거나 앱이 포 그라운드로 돌아올 때 현재 상태 만 잡을 수 있으면 멀티 플레이어 게임에서도 업데이트를 연기 할 수 있습니다. 이것은 CPU, 네트워크 및 배터리 효율성을 위해 어쨌든 살펴 봐야 할 것입니다.

사용자가 앱을 종료하면 실행중인 서비스가에 대한 전화를 받아야합니다 onTaskRemoved. 이 방법으로 많은 처리를 시도하면 어떻게 될지 모르겠습니다. 특정 시간 내에 반환되지 않으면 Android가 kill -9앱 을 사용 하기를 기대합니다.


앱은 백그라운드에서 업데이트 할 필요는 없지만 앱은 백그라운드로 이동하거나 파괴하기 전에 데이터 (예 : json 파일)를 저장해야합니다.
파이살 이므 란

onTaskRemoved 메소드가 호출하지만 파일을 저장하는 데 필요한 시간이 더 길거나 계산 시간이 크다고 말할 수 있습니다. 사용자가 앱을 종료하면이 방법이 중지됩니다.
파이살 이므 란
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.