วิธีจัดการกล่องโต้ตอบ LWUIT ที่แสดงบนเธรดพื้นหลัง

ฉันได้เขียนแอปพลิเคชันใน LWUIT ที่กำหนดเป้าหมายสำหรับโทรศัพท์ J2ME (Sprint DuraXT) แอปพลิเคชั่นนี้สำหรับผู้ขับรถกระบะและรถตู้ส่งของ รับการจัดส่งจากระบบการจัดส่งส่วนหลังที่อธิบายการรับสินค้าและส่งมอบที่คนขับต้องทำ ในฐานะคนขับ ดำเนินการรับและส่งมอบ คนขับจะป้อนข้อมูลสถานะที่ส่งกลับไปยังระบบสั่งการ

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

นอกจากนี้ ยังมีเธรดเบื้องหลังคอยฟังการจัดส่งที่มาจากเซิร์ฟเวอร์ส่วนหลัง ในการใช้งานปัจจุบัน เธรดพื้นหลังนี้ยังสามารถสร้างกล่องโต้ตอบการยืนยันใช่/ไม่ใช่และกล่องโต้ตอบข้อมูลได้ กล่องโต้ตอบเหล่านี้เป็นเหมือนการแจ้งเตือนเนื่องจากมีเสียงเชื่อมโยงกัน แต่เป็นเพียงกล่องโต้ตอบเท่านั้น

ตราบใดที่กล่องโต้ตอบทั้งสองนี้ไม่เกิดขึ้น "พร้อมกัน" ทุกสิ่งก็ทำงานได้ตามที่คาดไว้ คุณสามารถปิดกล่องโต้ตอบได้และแอปจะดำเนินการตามที่คาดไว้

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

สมมติฐานของฉันคือมีสภาวะการแข่งขันระหว่างเธรดที่ละทิ้งกล่องโต้ตอบ มันเป็นแบบนี้ EDT ถูกบล็อกโดยแสดงกล่องโต้ตอบที่เกิดขึ้นโดยเป็นส่วนหนึ่งของตรรกะของแบบฟอร์ม เธรดพื้นหลังยังถูกบล็อกโดยแสดงกล่องโต้ตอบ ตอนนี้เมื่อกล่องโต้ตอบที่แสดงบน EDT ถูกยกเลิก แบบฟอร์มจะถูกกู้คืน แต่ EDT อาจปิดและแสดงแบบฟอร์มอื่น (ผ่าน show()) เมื่อกล่องโต้ตอบที่แสดงโดยเธรดพื้นหลังถูกยกเลิก แบบฟอร์มที่แสดงเมื่อมีการแสดงกล่องโต้ตอบเริ่มแรกจะถูกเรียกคืนในบางครั้ง ตอนนี้จอแสดงผลจะแสดงรูปแบบที่แตกต่างจากที่ EDT อาจแสดงไว้

ค่อนข้างชัดเจนว่าปัญหานี้มีสาเหตุมาจากกล่องโต้ตอบที่เกิดจากกิจกรรมของเธรดพื้นหลัง คำถามพื้นฐานคือ: “จะจัดการกับกล่องโต้ตอบที่เกิดจากเธรดพื้นหลังได้อย่างไร” ฉันมีความคิดบางอย่าง แต่ไม่มีสิ่งใดที่ให้การนำไปใช้ที่สะอาดเป็นพิเศษ ฉันหวังว่าจะมีคนจัดการกับปัญหาเดียวกันนี้และมีข้อเสนอแนะ

ฉันได้ลองซิงโครไนซ์โครงสร้างกล่องโต้ตอบและการแสดงผลเพื่อให้สามารถแสดงกล่องโต้ตอบได้ครั้งละหนึ่งรายการเท่านั้น สิ่งนี้ช่วยปรับปรุง UI ได้อย่างแน่นอน แต่ไม่สามารถแก้ไขปัญหาได้ทั้งหมด การแข่งขันเริ่มต้นขึ้นเมื่อบทสนทนาแรกถูกยกเลิก ต่อไปนี้เป็นแนวคิดอื่นๆ

  1. หากกล่องโต้ตอบแสดงโดยเธรดอื่นที่ไม่ใช่ EDT ให้เรียกใช้การแสดงบนแบบฟอร์มที่ด้านบนของสแต็กการแสดงผลเมื่อกล่องโต้ตอบถูกยกเลิก นี่เป็นการแฮ็กเล็กน้อย แต่อาจเป็นวิธีแก้ปัญหา
  2. เรียกใช้กล่องโต้ตอบที่จะแสดงโดยเธรดพื้นหลังบน EDT มีหลายวิธีในการทำเช่นนี้ แต่คำถามคือจะช่วยแก้ปัญหาได้หรือไม่ การใช้ EventDispatcher จะช่วยได้หรือไม่ ฉันได้ทดลองใช้ EventDispatcher เพื่อเริ่มการทำงานของ ActionEvent ที่มีคลาสย่อยของ Dialog เป็นแหล่งที่มา คลาสย่อยประกอบด้วยเมธอด show() ซึ่งเรียกใช้รูปแบบที่ถูกต้องของเมธอด Dialog show คลาสที่ถือ EventDispatcher (ส่วนกลางของแอปพลิเคชัน) จะรับฟังเหตุการณ์เหล่านี้ เมื่อเหตุการณ์มาถึง วิธีการแสดงจะถูกเรียกใช้ สำหรับกล่องโต้ตอบข้อมูลที่ดำเนินการต่อไปจากทุกที่ที่ถูกปิด สิ่งนี้น่าจะได้ผล สำหรับกล่องโต้ตอบใช่/ไม่ใช่ คุณอาจต้องสร้างบางอย่างเช่นการเรียกกลับใช่/ไม่ใช่เพื่อจัดการกับการแยกไปสองทางในตรรกะ และสิ่งที่ไม่ชัดเจนก็คือว่าสิ่งนี้จะทำให้การประมวลผลกล่องโต้ตอบบนเธรด EDT เป็นอนุกรมจริงหรือไม่ ดูเหมือนซับซ้อน

มีความคิดอะไรบ้าง?


person Andy    schedule 14.12.2012    source แหล่งที่มา


คำตอบ (1)


ฉันได้ค้นพบวิธีแก้ปัญหาจริง ๆ หลังจากการทดลองเล็กน้อย เนื่องจาก Dialogs เป็นส่วนหนึ่งของการดำเนินการที่ซับซ้อนมากขึ้นที่เกี่ยวข้องกับ yes/no Dialogs และการสืบค้นฐานข้อมูล ฉันจึงพบว่าฉันต้องรวมการดำเนินการทั้งหมดในคลาสที่ใช้อินเทอร์เฟซ Runnable จากนั้นฉันก็เรียกใช้การกระทำผ่าน Display.getInstance().callSeriallyAndWait(runnable)

ดังนั้นคนอื่นๆ อาจได้รับประโยชน์จากการสนทนานี้ นี่คือตัวอย่างของหนึ่งในคลาสเหล่านี้ที่มีการดำเนินการฝังอยู่ในวิธีการเรียกใช้

   private class CancelOrder implements Runnable {

    private KWMap order;

    public CancelOrder(KWMap order) {
        this.order = order;
    }

    public void run() {
        String orderNum = getString(order, OrderTable.ORDER_NUM);
        if (legStatusTable.isOrderStarted(orderNum)
                && !orderTable.isOrderComplete(order)) {
            String msg = "You received a cancellation message for Order "
                    + orderNum
                    + " which has been started but is not finished."
                    + "\nDo you want to keep it?";
            if (app.yesNoDialog(msg, "Yes", "no")) {
                sendCancelResponse(order, "Yes", "");
            } else {
                deleteOrder(orderNum);
                sendCancelResponse(order, "No", "");
            }
        } else {
            // order has neither been started nor completed.
            deleteOrder(orderNum);
            sendCancelResponse(order, "Yes", "");
            app.alertDialog("Dispatcher cancelled Order " + orderNum);
        }
    }
}

สิ่งสำคัญที่นี่คือการดำเนินการประกอบด้วยตรรกะ ขึ้นอยู่กับวิธีที่ผู้ใช้ตอบสนองต่อกล่องโต้ตอบใช่/ไม่ใช่ และมีการดำเนินการบนฐานข้อมูลพื้นฐานและระบบย่อยการส่งข้อความเช่นกัน ยกเว้นกล่องโต้ตอบ ไม่มีสิ่งใดในการดำเนินการนี้บล็อก EDT เป็นเวลามากกว่า 2-3 100 มิลลิวินาที ดังนั้นแอปพลิเคชันจึงทำงานได้อย่างราบรื่นมาก แอปจัดการ dislog ที่ซ้อนทับกันอย่างเหมาะสม ซึ่งเป็นปัญหากับวิธีการง่ายๆ ที่ให้การดำเนินการเหล่านี้ทำงานบนเธรดพื้นหลัง (ไม่ใช่ EDT)

person Andy    schedule 19.12.2012