Lỗi hoạt động của tệp đối với sự cố / hủy trò chơi của HĐH / Người dùng trong Android


13

Trò chơi của tôi lưu trạng thái sau khoảng thời gian cố định trên một tệp trong bộ nhớ trong của trò chơi / ứng dụng. Khi trò chơi của tôi bị giết hoặc bị sập bởi người dùng hoặc HĐH tương ứng, Chúng tôi viết trạng thái trò chơi hiện tại trên tệp đó. Viết tệp sau khoảng thời gian sửa lỗi hoạt động tốt nhưng khi trò chơi bị lỗi / bị giết bởi hệ điều hành hoặc người dùng, thao tác ghi tệp không thành công. Hoạt động thất bại dẫn đến trạng thái trò chơi không hoàn chỉnh hoặc trạng thái trò chơi trống tức là không có dữ liệu được ghi trên tệp. Tôi đã thử nhiều giải pháp bằng dịch vụ Android, Trong trường hợp dịch vụ là dịch vụ NON STICKY bị giết với ứng dụng. Mặt khác, nếu dịch vụ là STICKY thì nó được khởi động lại nhưng ý định được đính kèm ban đầu với dịch vụ là null hoặc mới.

Câu hỏi là làm thế nào tôi có thể lưu dữ liệu của mình (có thể ~ 2-3 MB) hoàn toàn trên tệp trong bộ nhớ trong khi trò chơi / ứng dụng của tôi bị giết bởi người dùng / HĐH?


Bạn phải xử lý SIGTERM và SIGKILL của bạn (có thể không phải SIGKILL, Android có thể đang sử dụng SIGTERM). (Không có thời gian để nghiên cứu / viết ra một câu trả lời đầy đủ nhưng đó là ý tưởng cơ bản.)
John Hamilton

2
Theo định nghĩa, @John Hamilton SIGKILL không thể được xử lý.
Darkhogg

@Darkhogg Chà, không phải ở Unity, điều đó là chắc chắn. (Tôi đã thay đổi kernel linux tại một thời điểm cho một dự án cho mục đích cụ thể này và chắc chắn có thể để các chương trình xử lý SIGKILL)
John Hamilton

Câu trả lời:


20

Tôi sẽ đề nghị viết trạng thái lưu của bạn theo cách đệm đôi, như thường thấy đối với các tựa game console trong quá khứ (nơi bạn phải đối phó với việc thẻ nhớ bị xóa giữa chừng và ghi bị chậm).

Tiết kiệm:

  • Nếu không có tệp nào tồn tại, ghi trạng thái vào tệp A
  • Nếu A tồn tại, viết thư cho B
  • Nếu cả A và B đều tồn tại, hãy tìm cái nào cũ hơn, xóa nó và sau đó viết cho cái đó

Tải:

  • Nếu cả A và B tồn tại, hãy thử tải cái mới hơn của hai cái. Nếu thất bại (vì tệp không đầy đủ hoặc bị hỏng), hãy xóa tệp đó và tải tệp khác
  • Nếu chỉ có một tồn tại, tải nó
  • Nếu cả hai đều bị hỏng, hãy thông báo cho người dùng rằng trạng thái lưu của họ là không thể khắc phục được (như bạn có lẽ phải có)

Luồng này sẽ hoạt động để đảm bảo luôn có ít nhất một lưu hợp lệ vẫn còn trong bộ nhớ của bạn, ngay cả khi ứng dụng bị hủy giữa chừng. Người chơi sẽ không nhận được bất kỳ thay đổi nào trong trạng thái trò chơi kể từ lần lưu trước đó nếu loại lỗi đó xảy ra, nhưng họ sẽ không phải bắt đầu lại.

Ngoài ra, bạn nên lưu ngay lập tức sau các sự kiện chính (chẳng hạn như mua trong ứng dụng) ngoài việc lưu khoảng thời gian của bạn, để giảm thiểu cửa sổ dễ bị tổn thương trong đó sự cố / giết sẽ khiến sự kiện quan trọng đó bị mất. Đây cũng là biện pháp bảo vệ chống lại việc khai thác trò chơi (ví dụ: giết chết ứng dụng sau khi mất mạng, bởi vì bạn biết bạn sẽ khôi phục lại trạng thái trò chơi từ trước khi bạn mất mạng và thử lại). Tất nhiên, nếu làm điều này, bạn phải bảo vệ việc tiết kiệm khoảng thời gian của mình bằng logic có nội dung "nếu việc lưu đã được tiến hành, đừng cố bắt đầu lưu lại."


Cảm ơn MrCranky đây là một giải pháp cho vấn đề của tôi, làm thế nào tôi có thể lưu dữ liệu của phiên trước tức là ngay trước khi tắt ứng dụng / trò chơi? Ví dụ, anh ta đã mua một ứng dụng và giết ứng dụng.
Faisal Imran

12
Bạn thậm chí không cần hai tập tin. Viết thư cho B, nếu và chỉ khi viết thành công, xóa A và đổi tên B thành A. java.nio.file.Files.move(Path source, Path target, CopyOption... options)có thể đổi tên và ghi đè thành thao tác nguyên tử.
Polygnome

6
@Polygnome: Lưu ý rằng trong trường hợp mất điện, điều này sẽ không luôn luôn cung cấp sự đảm bảo mà bạn mong đợi, trừ khi bạn gọi sync()vào tệp B trước khi bạn chuyển nó qua tệp A (ngay cả khi không có bảo đảm hoàn toàn, nhưng sync()khá tốt).
Dietrich Epp

1
@FaisalImran Lưu dữ liệu ngay sau thao tác quan trọng, ví dụ, sau IAP. Nếu hoạt động bị gián đoạn do tắt điện thoại, tôi đoán nó sẽ không bao giờ lấy tiền từ người đó. Nhưng chỉ trong trường hợp, bạn có thể muốn lưu dữ liệu tài khoản của anh ấy trong giao dịch mua trên một số nền tảng như một nỗ lực để mua thứ gì đó. Sau đó, bạn có thể so sánh thu nhập của mình với dữ liệu đó và xem người này có thực sự mua thứ gì đó không. Và sau đó mở tính năng này cho anh ta thông qua dịch vụ trực tuyến bạn đang sử dụng để lưu tất cả dữ liệu. Nếu bạn đang sử dụng tiết kiệm cục bộ cho IAP, thì điều đó còn tồi tệ hơn vấn đề này.
Mặt trăng thí sinh _Max_

1
Cuối cùng, mặc dù điều này có thể không giải quyết được tất cả các vấn đề của bạn, tôi muốn nói rằng vấn đề của bạn không thể giải quyết được hoàn toàn. Bạn không thể hỗ trợ cả "người dùng có thể giết ứng dụng của tôi bất cứ lúc nào" và "không có dữ liệu nào bị mất" bởi vì sẽ luôn có một cửa sổ sau khi một sự kiện đã diễn ra nhưng trước khi nó được lưu giữ để lưu trữ nơi người dùng có thể giết ứng dụng và mất dữ liệu.
MrCranky

3

Android chỉ giết các ứng dụng khi chúng ở chế độ nền. Dữ liệu trò chơi của bạn có thực sự cần được cập nhật khi ứng dụng ở chế độ nền không, hoặc bạn có thể ngừng cập nhật dữ liệu cho đến khi ứng dụng trở lại nền trước không? Bạn có thể trì hoãn cập nhật ngay cả trong một trò chơi nhiều người chơi, nếu bạn có thể lấy lịch sử các sự kiện hoặc thậm chí chỉ trạng thái hiện tại khi ứng dụng trở lại nền trước. Đây là điều mà có lẽ bạn nên xem xét dù sao đi nữa vì lợi ích của CPU, mạng và hiệu quả pin.

Nếu người dùng giết ứng dụng của bạn, các dịch vụ đang chạy sẽ nhận được cuộc gọi đến onTaskRemoved. Tôi không biết điều gì sẽ xảy ra nếu bạn cố gắng xử lý nhiều trong phương pháp này. Tôi hy vọng rằng nếu nó không quay trở lại trong một thời gian nhất định, Android sẽ kill -9ứng dụng của bạn.


ứng dụng không cần cập nhật trong nền, nhưng ứng dụng phải lưu dữ liệu của nó, ví dụ như tệp json trước khi chuyển sang nền hoặc hủy.
Faisal Imran

bạn đã đúng phương thức onTaskRemond sẽ gọi nhưng thời gian cần thiết để lưu tệp là nhiều hơn hoặc chúng ta có thể nói thời gian tính toán là lớn. Khi người dùng giết ứng dụng, phương thức này sẽ bị dừng.
Faisal Imran
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.