Cara menangani dialog LWUIT yang ditampilkan di thread latar belakang

Saya telah menulis aplikasi di LWUIT yang ditargetkan untuk telepon J2ME (Sprint DuraXT). Aplikasi ini untuk pengemudi van penjemputan dan pengantaran. Ia menerima kiriman dari sistem pengiriman back-end yang menjelaskan pengambilan dan pengiriman yang harus dilakukan pengemudi. Saat pengemudi melakukan penjemputan dan pengantaran, pengemudi memasukkan informasi status yang dikirim kembali ke sistem pengiriman.

Sekarang, selama pemrosesan pengambilan atau pengiriman, pengemudi mungkin disajikan dengan dialog kesalahan (entri kolom salah), dialog konfirmasi ya/tidak (mengonfirmasi beberapa tindakan) dan dialog informasi (menunjukkan beberapa status yang harus diketahui pengemudi).

Selain itu, ada thread latar belakang yang mendengarkan kiriman yang datang dari server back-end. Dalam implementasi saat ini, thread latar belakang ini juga dapat membuat dialog konfirmasi ya/tidak dan dialog informasi. Dialog-dialog ini lebih mirip peringatan karena memiliki suara terkait, namun hanya berupa dialog.

Selama kedua dialog ini tidak terjadi “bersamaan”, semuanya berjalan sesuai harapan. Anda dapat mengabaikan dialog dan aplikasi melanjutkan seperti yang diharapkan.

Namun, ketika Anda berada di layar dan ada dialog yang sudah ditampilkan dan dialog kedua dari thread latar belakang terjadi, terkadang Anda berakhir dengan tampilan layar yang salah dan layar tersebut "dibekukan". Misalnya. tombol lunak tidak berpengaruh.

Hipotesis saya adalah ada kondisi perlombaan antar thread yang mengabaikan dialog. Bunyinya seperti ini. EDT diblokir menampilkan dialog yang muncul sebagai bagian dari logika formulir. Utas latar belakang juga diblokir menampilkan dialog. Sekarang ketika dialog yang ditampilkan pada EDT ditutup, formulir dikembalikan, namun EDT mungkin mati dan menampilkan formulir lain (melalui show()). Ketika dialog yang ditampilkan oleh thread latar belakang ditutup, formulir yang ditampilkan saat dialog pertama kali ditampilkan terkadang dipulihkan. Sekarang, tampilan menunjukkan bentuk yang berbeda dari yang mungkin ditunjukkan oleh EDT.

Jelas sekali bahwa masalah ini disebabkan oleh dialog yang dihasilkan dari aktivitas thread latar belakang. Jadi pertanyaan dasarnya adalah: “Bagaimana cara menangani dialog yang muncul dari thread latar belakang?” Saya punya beberapa pemikiran tetapi tidak ada yang menghasilkan implementasi yang sangat bersih. Saya berharap seseorang harus menghadapi masalah yang sama dan memiliki saran.

Saya telah mencoba menyinkronkan konstruksi dan tampilan dialog sehingga hanya satu dialog yang dapat ditampilkan dalam satu waktu. Hal ini tentu saja meningkatkan UI, namun tidak sepenuhnya menyelesaikan masalah. Perlombaan dimulai ketika dialog pertama ditutup. Berikut beberapa ide lainnya,

  1. Jika dialog ditampilkan oleh thread selain EDT, panggil show pada formulir di bagian atas tumpukan tampilan saat dialog ditutup. Ini sedikit peretasan, tetapi mungkin bisa menjadi solusi.
  2. Jalankan dialog yang akan ditampilkan oleh thread latar belakang pada EDT. Ada beberapa cara untuk melakukan hal ini, namun pertanyaannya adalah apakah cara ini dapat menyelesaikan masalah? Apakah menggunakan EventDispatcher akan membantu? Saya telah bereksperimen menggunakan EventDispatcher untuk menjalankan ActionEvent yang berisi subkelas Dialog sebagai sumber. Subkelas berisi metode show() yang memanggil bentuk metode Dialog show yang benar. Kelas yang memegang EventDispatcher (global untuk aplikasi) mendengarkan kejadian ini. Ketika acara tiba, metode pertunjukan dipanggil. Untuk dialog informasi yang melanjutkan eksekusi dari mana pun dialog tersebut ditutup, ini akan berhasil. Untuk dialog ya/tidak, Anda mungkin harus membuat panggilan balik ya/tidak untuk menangani bifurkasi dalam logika. Dan yang tidak jelas adalah apakah ini benar-benar akan membuat serialisasi pemrosesan dialog di thread EDT. Tampaknya ini rumit.

Ada ide?


person Andy    schedule 14.12.2012    source sumber


Jawaban (1)


Saya benar-benar menemukan solusinya setelah sedikit eksperimen. Karena Dialog adalah bagian dari tindakan yang lebih rumit yang melibatkan Dialog ya/tidak dan kueri basis data, saya mendapati saya harus menggabungkan seluruh tindakan dalam kelas yang mengimplementasikan antarmuka Runnable. Kemudian saya menjalankan aksinya melalui Display.getInstance().callSerialAndWait(runnable).

Agar orang lain dapat memperoleh manfaat dari diskusi ini, berikut adalah contoh salah satu kelas tersebut dengan tindakan yang tertanam dalam metode run.

   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);
        }
    }
}

Kuncinya di sini adalah bahwa tindakan tersebut mengandung logika tergantung pada bagaimana pengguna merespons Dialog ya/tidak dan terdapat operasi pada database yang mendasarinya dan subsistem pesan juga. Kecuali Dialog, tidak ada apa pun dalam tindakan ini yang memblokir EDT selama lebih dari beberapa 100 milidetik, sehingga aplikasi berjalan dengan sangat lancar. Aplikasi ini dengan tepat menangani dislog yang bertumpuk satu sama lain yang merupakan masalah dengan pendekatan sederhana membiarkan tindakan ini berjalan di thread latar belakang (non EDT).

person Andy    schedule 19.12.2012