ความล้มเหลวในการดำเนินงานของไฟล์ในเกมล้มเหลว / ฆ่าโดย OS / ผู้ใช้ใน Android


13

เกมของฉันบันทึกสถานะหลังจากช่วงเวลาคงที่ในไฟล์ในที่เก็บข้อมูลภายในเกม / แอพ เมื่อเกมของฉันถูกฆ่าหรือล้มเหลวโดยผู้ใช้หรือระบบปฏิบัติการตามลำดับเราจะเขียนสถานะเกมปัจจุบันลงในไฟล์นั้น การเขียนไฟล์หลังจากช่วงเวลาการแก้ไขทำงานได้ดี แต่เมื่อเกมหยุดทำงาน / ถูกฆ่าโดยระบบปฏิบัติการหรือผู้ใช้การดำเนินการเขียนไฟล์ล้มเหลว ความล้มเหลวในการดำเนินงานส่งผลให้สถานะเกมไม่สมบูรณ์หรือสถานะเกมว่างเปล่าเช่นไม่มีข้อมูลที่เขียนลงไฟล์เลย ฉันได้ลองใช้วิธีแก้ไขปัญหาหลายอย่างโดยใช้บริการ android ในกรณีที่บริการไม่ใช่บริการที่เหนียวติดกับแอป ในทางกลับกันถ้าบริการติดแล้วมันจะเริ่มต้นใหม่ แต่ความตั้งใจที่แนบมากับบริการเป็นโมฆะหรือใหม่

คำถามคือฉันจะบันทึกข้อมูลของฉัน (อาจ ~ 2-3MB) ในไฟล์ในที่จัดเก็บข้อมูลภายในอย่างสมบูรณ์เมื่อผู้ใช้ / ระบบปฏิบัติการของเกม / แอพถูกฆ่าตาย?


คุณต้องจัดการกับ SIGTERMs และ SIGKILLs ของคุณ (อาจไม่ใช่ SIGKILLs, Android น่าจะใช้ SIGTERM) (ไม่มีเวลาค้นคว้า / เขียนคำตอบแบบเต็ม แต่นั่นเป็นความคิดพื้นฐาน)
John Hamilton

2
@JohnHamilton SIGKILL ไม่สามารถจัดการได้ตามคำจำกัดความ
Darkhogg

@ Darkhogg ไม่เป็นเอกภาพแน่นอนว่า (ฉันไม่เปลี่ยนแปลงลินุกซ์เคอร์เนลจุดหนึ่งสำหรับโครงการเพื่อจุดประสงค์นี้โดยเฉพาะและมันเป็นไปได้แน่นอนที่จะให้โปรแกรมจับ SIGKILL)
จอห์นแฮมิลตัน

คำตอบ:


20

ฉันขอแนะนำให้เขียนสถานะการบันทึกของคุณในแบบที่ถูกบัฟเฟอร์สองครั้งเช่นเดียวกับคอนโซลทั่วไปในอดีต (ซึ่งคุณต้องรับมือกับการ์ดหน่วยความจำที่ถูกลบกลางการเขียนและเขียนช้า)

บันทึก:

  • หากไม่มีไฟล์ให้เขียนสถานะเป็นไฟล์ A
  • ถ้ามีอยู่เขียนถึง B
  • หากทั้ง A และ B มีอยู่ให้ค้นหาว่าอันใดอันที่เก่ากว่าลบออกแล้วเขียนไปที่อันนั้น

โหลด:

  • หากทั้ง A และ B มีอยู่ให้ลองโหลดใหม่ทั้งสอง หากล้มเหลว (เนื่องจากไฟล์ไม่สมบูรณ์หรือเสียหาย) ให้ลบและโหลดไฟล์อื่น
  • หากมีเพียงหนึ่งรายการให้โหลด
  • หากทั้งคู่เกิดความเสียหายแจ้งผู้ใช้ว่าสถานะการบันทึกของพวกเขานั้นแก้ไขไม่ได้ (เช่นคุณต้องมีอยู่แล้ว)

โฟลว์นี้จะทำงานเพื่อให้แน่ใจว่ามีการบันทึกที่ถูกต้องอย่างน้อยหนึ่งรายการยังคงอยู่ในที่จัดเก็บข้อมูลของคุณแม้ว่าแอปจะถูกฆ่าตอนกลางคัน ผู้เล่นจะไม่ได้รับการเปลี่ยนแปลงใด ๆ ในสถานะเกมตั้งแต่บันทึกก่อนหน้านี้หากความล้มเหลวประเภทนั้นเกิดขึ้น แต่พวกเขาจะไม่ต้องเริ่มใหม่อีกครั้ง

นอกจากนี้คุณควรบันทึกทันทีหลังจากเหตุการณ์สำคัญ (เช่นการซื้อในแอป) นอกเหนือจากการบันทึกช่วงเวลาของคุณเพื่อลดหน้าต่างช่องโหว่ที่มีการหยุดทำงานผิดพลาด / การทำลายจะทำให้เหตุการณ์สำคัญนั้นหายไป นี่เป็นการป้องกันการหาประโยชน์จากเกม (เช่นบังคับให้ฆ่าแอปหลังจากเสียชีวิตเพราะคุณรู้ว่าคุณจะกลับคืนสู่สถานะเกมก่อนที่จะเสียชีวิตและลองอีกครั้ง) แน่นอนถ้าทำเช่นนี้คุณต้องป้องกันการบันทึกช่วงเวลาของคุณด้วยตรรกะที่ระบุว่า "ถ้าการบันทึกกำลังดำเนินการอยู่อย่าพยายามเริ่มการบันทึกอีกครั้ง"


ขอบคุณ MrCranky นี่เป็นวิธีแก้ปัญหาบางส่วนของฉันฉันจะบันทึกข้อมูลของเซสชันล่าสุดเช่นก่อนที่จะฆ่าแอพ / เกมได้อย่างไร ตัวอย่างเช่นเขาซื้อแอพและฆ่าแอพ
Faisal Imran

12
คุณไม่จำเป็นต้องมีแม้แต่สองไฟล์ เขียนถึง B หากการเขียนสำเร็จแล้วให้ลบ A และเปลี่ยนชื่อ B เป็น A java.nio.file.Files.move(Path source, Path target, CopyOption... options)สามารถทำการเปลี่ยนชื่อและเขียนทับเป็นการดำเนินการปรมาณู
Polygnome

6
@Polygnome: โปรดทราบว่าในกรณีที่ไฟฟ้าขัดข้องสิ่งนี้จะไม่รับประกันทุกสิ่งที่คุณคาดหวังเว้นแต่ว่าคุณจะเรียกsync()ไฟล์ B ก่อนที่จะย้ายไฟล์ A (แม้จะมีการรับประกันไม่สมบูรณ์ แต่sync()ก็ค่อนข้างดี)
Dietrich Epp

1
@FaisalImran บันทึกข้อมูลทันทีหลังจากการดำเนินการที่สำคัญตัวอย่างเช่นหลังจาก IAP หากการดำเนินการถูกขัดจังหวะโดยการปิดโทรศัพท์ฉันเดาว่ามันจะไม่ใช้เงินจากคนต่อไป แต่ในกรณีคุณอาจต้องการบันทึกข้อมูลบัญชีของเขาในการซื้อบนแพลตฟอร์มบางอย่างเพื่อพยายามซื้อบางอย่าง จากนั้นคุณสามารถเปรียบเทียบรายได้ของคุณกับข้อมูลนั้นและดูว่าคนนี้ซื้ออะไรจริงๆหรือไม่ จากนั้นเปิดฟีเจอร์นี้สำหรับเขาผ่านบริการออนไลน์ที่คุณใช้เพื่อบันทึกข้อมูลทั้งหมด หากคุณใช้การบันทึกในท้องถิ่นสำหรับ IAP แสดงว่ายิ่งแย่ไปกว่าปัญหานี้
Candid Moon _Max_

1
สุดท้ายนี้อาจไม่สามารถแก้ปัญหาทั้งหมดของคุณได้ แต่ฉันบอกว่าปัญหาของคุณไม่สามารถแก้ไขได้อย่างสมบูรณ์ คุณไม่สามารถรองรับได้ทั้ง "ผู้ใช้อาจฆ่าแอพของฉันได้ตลอดเวลา" และ "ไม่ต้องมีการสูญหายของข้อมูล" เพราะจะมีหน้าต่างเสมอหลังจากเหตุการณ์เกิดขึ้น แต่ก่อนที่จะมีการจัดเก็บที่ผู้ใช้ สามารถฆ่าแอพและสูญเสียข้อมูล
MrCranky

3

Android จะฆ่าแอปเมื่ออยู่ในพื้นหลังเท่านั้น ข้อมูลเกมของคุณจำเป็นต้องได้รับการอัปเดตจริง ๆ หรือไม่เมื่อแอปอยู่ในพื้นหลังหรือคุณสามารถหยุดอัปเดตข้อมูลได้จนกว่าแอพจะกลับสู่เบื้องหน้าหรือไม่? คุณอาจสามารถเลื่อนการอัปเดตได้แม้กระทั่งในเกมที่มีผู้เล่นหลายคนหากคุณสามารถคว้าประวัติของเหตุการณ์หรือแม้กระทั่งสถานะปัจจุบันเมื่อแอปกลับสู่เบื้องหน้า นี่คือสิ่งที่คุณควรพิจารณาในการดำเนินการเพื่อประโยชน์ของ CPU เครือข่ายและประสิทธิภาพของแบตเตอรี่

onTaskRemovedหากผู้ใช้ฆ่าแอปของคุณบริการที่ทำงานควรได้รับการเรียกไปยัง ฉันไม่รู้ว่าจะเกิดอะไรขึ้นถ้าคุณพยายามประมวลผลมากในวิธีนี้ ฉันคาดว่าถ้ามันไม่กลับมาภายในระยะเวลาที่กำหนด Android จะkill -9แอปของคุณ


แอปไม่จำเป็นต้องอัปเดตในพื้นหลัง แต่แอปจะต้องบันทึกข้อมูลเช่นไฟล์ json ก่อนที่จะพื้นหลังหรือทำลาย
Faisal Imran

คุณพูดถูกวิธี onTaskRemoved จะโทร แต่เวลาที่ใช้ในการบันทึกไฟล์นั้นมากขึ้นหรือเราสามารถพูดได้ว่าเวลาการคำนวณมีขนาดใหญ่ เมื่อผู้ใช้ฆ่าแอพวิธีนี้จะหยุด
Faisal Imran
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.