ฉันจะใช้การแกว่งในตะขอปิดระบบได้อย่างไร

มีวิธีใดที่เป็นไปได้ในการเพิ่มการแกว่งลงในฮุกการปิดระบบ (นั่นคือแสดงป๊อปอัปเมื่อ VM ปิดตัวลง)

ฉันรู้ว่าหากฉันพยายามสร้าง JFrame ใหม่ มันจะทำให้ฉันมีข้อผิดพลาด เนื่องจากพยายามลงทะเบียนฮุกการปิดเครื่อง ซึ่งล้มเหลวเนื่องจาก VM กำลังปิดตัวลงแล้ว ฉันแค่สงสัยว่าจริง ๆ แล้วมีวิธีแก้ไขปัญหานี้หรือไม่


person Alex Coleman    schedule 25.08.2012    source แหล่งที่มา
comment
ฉันจะบอกว่าไม่ และแม้ว่าคุณจะทำไม่ได้ ฉันขอแนะนำว่าอย่าทำ   -  person MadProgrammer    schedule 25.08.2012
comment
@MadProgrammer ฉันได้ดูไปรอบ ๆ แล้วและไม่พบอะไรเลย แต่ฉันคิดว่ามันควรจะเป็นไปได้เนื่องจากแอปพลิเคชั่นจำนวนมากมีหน้าต่างป๊อปอัปให้คุณไม่ใช่แค่เมื่อปิด แต่เช่นถ้าคุณปิดคอมพิวเตอร์ (ซึ่งจะปิดเครื่อง จาวาวีเอ็ม)   -  person Alex Coleman    schedule 25.08.2012
comment
ฉันมีโปรแกรมที่เพิ่งส่งข้อยกเว้นเนื่องจากนักพัฒนาซอฟต์แวร์กำลังเข้าถึง Swing Component ภายในเบ็ดที่ปิดเครื่อง (ฉันคิดว่าภายใต้ Java 7) ฉันว่าคุณอาจมีปัญหาในการพยายามปฏิบัติตามแนวคิดนี้ ส่วนหนึ่งของปัญหาคือการไม่รู้ว่า JVM อยู่ในสถานะใดจริง ๆ หรือลำดับของการเรียก hooks ปิดระบบ   -  person MadProgrammer    schedule 25.08.2012
comment
@AlexColeman เป็นไปได้ที่จะแสดงหน้าต่างป๊อปอัปอย่างแน่นอน แต่ไม่ใช่ผ่านทางฮุกการปิดระบบอย่างที่คุณคิด โดยปกติจะทำในช่วงปิดหน้าต่าง   -  person user207421    schedule 26.08.2012
comment
บน Macintosh คุณสามารถมี ApplicationListener ซึ่งมีเมธอด public void handleQuit(ApplicationEvent) ได้ หากคุณต้องการสนับสนุน/มีเครื่อง Windows สิ่งนี้จะไม่ทำงานเนื่องจากอยู่ในแพ็คเกจ com.apple   -  person 11684    schedule 27.08.2012


คำตอบ (5)


คุณไม่ควรทำอย่างนี้จริงๆ จาก ข้อกำหนด Runtime.addShutdownHook :

เครื่องเสมือน Java ปิดตัวลง เพื่อตอบสนองต่อเหตุการณ์สองประเภท:

  • โปรแกรม ออก ตามปกติ เมื่อเธรดที่ไม่ใช่ daemon สุดท้ายออก หรือเมื่อเรียกใช้เมธอด exit (เทียบเท่า System.exit) หรือ
  • เครื่องเสมือนถูกยุติเพื่อตอบสนองการขัดจังหวะของผู้ใช้ เช่น การพิมพ์ ^C หรือเหตุการณ์ทั่วทั้งระบบ เช่น การออกจากระบบของผู้ใช้หรือการปิดระบบ

...

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

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

...

ในบางกรณีที่เกิดขึ้นไม่บ่อยนัก เครื่องเสมือนอาจ ยกเลิก กล่าวคือ หยุดทำงานโดยไม่ได้ปิดระบบอย่างสมบูรณ์ สิ่งนี้เกิดขึ้นเมื่อเครื่องเสมือนถูกยกเลิกจากภายนอก เช่น ด้วยสัญญาณ SIGKILL บน Unix หรือการเรียก TerminateProcess บน Microsoft Windows เครื่องเสมือนอาจยุติลงหากวิธีการดั้งเดิมผิดพลาด เช่น ทำให้โครงสร้างข้อมูลภายในเสียหาย หรือพยายามเข้าถึงหน่วยความจำที่ไม่มีอยู่ หากเครื่องเสมือนถูกยกเลิก จะไม่สามารถรับประกันได้ว่าจะมีการรัน hook การปิดระบบใดๆ หรือไม่

คำเตือนเฉพาะที่นี่ซึ่งแนะนำให้คุณไม่ทำเช่นนี้:

  1. "ฮุคการปิดระบบควรทำงานให้เสร็จอย่างรวดเร็วเช่นกัน"

    การใช้สิ่งใดก็ตามที่อาจใช้เวลาสักครู่ในการทำงาน หรือการบล็อกอินพุตที่ผู้ใช้ป้อนอย่างไม่มีกำหนด เช่น กล่องโต้ตอบ JOptionPane นั้นไม่ใช่สิ่งที่คุณควรทำในการปิดเครื่อง

  2. "ความพยายามที่จะใช้บริการตามเธรดอื่น ๆ เช่น เธรดการจัดส่งเหตุการณ์ AWT อาจนำไปสู่การหยุดชะงัก"

    Swing ทำงานบน AWT ซึ่งเธรดการส่งเหตุการณ์พื้นฐานอาจอยู่ในกระบวนการปิดตัวลงเช่นกัน การพยายามใช้ Swing หรือ AWT ในขณะที่ปิดเครื่องไม่เพียงแต่จะทำให้ระบบล็อคตายเท่านั้น แต่ยังอาจไม่ได้ผลเลยด้วยซ้ำ

  3. "หากเครื่องเสมือนถูกยกเลิก จะไม่สามารถรับประกันได้ว่าจะมีการเรียกใช้การปิดระบบใดๆ หรือไม่"

    ไม่มีการรับประกันว่าผู้ใช้ของคุณจะได้รับข้อความของคุณ เนื่องจากฮุกการปิดระบบจะรับประกันว่าจะทำงานเมื่อออกตามปกติหรือถูกยกเลิกเท่านั้น -- ไม่ เมื่อหยุดหรือยกเลิก

person obataku    schedule 25.08.2012
comment
นี่คือสิ่งที่ฉันเข้าใจมาก่อน หวังว่าจะมีวิธี แต่ฉันคิดว่าไม่ใช่ - person Alex Coleman; 25.08.2012

hooks การปิดระบบควรจะดำเนินการโดยเร็วที่สุด ซึ่งไม่รวมถึงการรอให้ผู้ใช้ยืนยันกล่องโต้ตอบ ไม่ว่าในกรณีใด คุณไม่รับประกันว่าเธรดเหตุการณ์ Swing ยังคงทำงานอยู่

คุณไม่สามารถทำเช่นนี้ได้

person user207421    schedule 25.08.2012
comment
+1 ดีที่คุณไม่รับประกันว่าเธรดกิจกรรม Swing ยังคงทำงานอยู่ - person David Kroukamp; 25.08.2012

ถ้ามีก็ช่วยอะไรไม่ได้

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

สำหรับการปล่อยทรัพยากรและการดูแลทำความสะอาดอื่น ๆ เมื่อ JVM ปิดระบบ

สิ่งสำคัญที่ควรทราบคือ hook การปิดระบบจะไม่ทำงานเสมอไป สำหรับข้อมูลเพิ่มเติมโปรดดูคำตอบของฉันที่นี่: วิธีปิดแอปพลิเคชัน java อย่างถูกต้องจาก C# one

person David Kroukamp    schedule 25.08.2012
comment
แม้ว่าจะได้รับการจัดการแบบอะซิงโครนัส แต่เธรดยังคงไม่ใช่ daemon ดังนั้นจึงอาจยังใช้งานได้... ไม่ใช่ว่าคุณควรจะ เคย ทำ - person obataku; 25.08.2012
comment
@veer จริง แต่ฉันเดาว่าปัญหาที่ใหญ่ที่สุดที่ OP จะเผชิญก็คือการยุติแอปทั้งหมดจะไม่ทำให้เกิดการปิดระบบ - person David Kroukamp; 25.08.2012

  1. ต้องทำ Swing GUI บน Event Dispatch Thread จากนั้น

  2. วิธีง่ายๆ แต่ผู้ใช้ปลายทางต้องดำเนินการ (ปิด JDialog)

person mKorbel    schedule 25.08.2012
comment
ฉันเกรงว่าฉันไม่เห็นว่าคำตอบของคุณเกี่ยวข้องกับคำถามเดิมอย่างไร - person Duncan Jones; 25.08.2012
comment
@DuncanJones เขากำลังตอบมัน คำตอบของเขาเกี่ยวกับการปิดระบบ hook + ลิงก์ไปยังวิธีแก้ปัญหาที่เป็นไปได้ ... - person Alex Coleman; 25.08.2012
comment
@mKorbel ฉันไม่เห็นว่าตัวเลือกแรกทำงานอย่างไร ฉันไม่ได้เรียกร้องให้ปิดระบบ แต่มันเกิดขึ้นโดยบังเอิญ ฉันแค่อยากจะจัดการมันด้วยหน้าต่างป๊อปอัป อย่างที่สอง ฉันเห็นศักยภาพบางอย่างว่า Runtime#exec จะทำงานเมื่อ JVM/คอมพิวเตอร์กำลังปิดตัวลงหรือไม่ - person Alex Coleman; 25.08.2012
comment
@Alex Coleman Runtime#exec เป็นหนึ่งในเจ็ดตัวเลือก หากมีบางสิ่งที่คุณไม่เข้าใจ ให้ค้นหาคำถามเกี่ยวกับ JVM, Swing และเหตุใด Shutdown Hook จึงไม่ทำงานกับ Swing GUI ที่มี taks พื้นหลัง - person mKorbel; 25.08.2012

ฉันไม่แน่ใจเกี่ยวกับคำถามของคุณ แต่ฉันคิดว่ามันเป็นไปไม่ได้ที่จะเรียกใช้หรือแสดงหน้าต่างป๊อปอัปเมื่อ JVM กำลังปิดตัวลง เหมือนคุณกำลังพยายามวิ่งขณะเตรียมตัวนอนใช่ไหม? แค่คาดเดา :)

person user1577161    schedule 25.08.2012