Really sorry for duplicate threads for my bad network connection, but I was
not advertising. I hope there is someone could help get rid of it.
I admitted it's a terrible hack and not versions compatible.

It's a long story that I didn't get another choice but have to make a real
modal dialog, otherwise, the worst situation is to build my own widget
toolkit and ui framework.

Anyway, sorry again if bothering.

On Thu, Jun 2, 2011 at 9:05 PM, Mark Murphy <mmur...@commonsware.com> wrote:

> IMHO, anybody who uses this code is a fool.
>
> This code assumes a certain implementation, let alone certain method
> signatures, of the internal message-handling logic. This may not be
> consistent across Android versions. Anyone using this is simply asking
> for trouble.
>
> On Thu, Jun 2, 2011 at 8:51 AM, Qi Luo <regcollect...@gmail.com> wrote:
> >
> I saw much people wanted such a feature, me either. These days I've google-ed 
> around and tried serveral ways to get it right, finally ended up with 
> following solution. No thread synchronization, no dialog-themed activities, 
> really simple.
> > Some useful resource and background,
> >
> >
> http://groups.google.com/group/android-developers/browse_thread/thread/5616a220c97a13fc/5e722e601f33d884#5e722e601f33d884
> >
> http://stackoverflow.com/questions/2028697/dialogs-alertdialogs-how-to-block-execution-while-dialog-is-up-net-style
> >
> > Modal dialog is a typical widget in Win32, it could
> > 1. block current workflow
> >
> 2. capture all input (key, mouse) events, but still properly dispatch other 
> events, like paint
> > 3. wait for response and quit
> >
> >
> People who's familiar with Win32 programming possibly knows how to implement 
> a modal dialog. Generally it runs a nested message loop (by 
> GetMessage/PostMessage) when there is a modal dialog up. So, I tried to 
> implement my own modal dialog in this traditional way.
> >
> At the first, android didn't provide interfaces to inject into ui thread 
> message loop, or I didn't find one. When I looked into source, Looper.loop(), 
> I found it's exactly what I wanted. But still, MessageQueue/Message haven't 
> provided public interfaces. Fortunately, we have reflection in java.
> >
> Basically, I just copied exactly what Looper.loop() did, it blocked workflow 
> and still properly handled events. I haven't tested nested modal dialog, but 
> theoretically it would work.
> >
> > Here's my source code,
> >
> > public class ModalDialog {
> >     private boolean mChoice = false;
> >     private boolean mQuitModal = false;
> >     private Method mMsgQueueNextMethod = null;
> >     private Field mMsgTargetFiled = null;
> >     public ModalDialog() {
> >     }
> >     public void showAlertDialog(Context context, String info) {
> >         if (!prepareModal()) {
> >             return;
> >         }
> >         // build alert dialog
> >         AlertDialog.Builder builder = new AlertDialog.Builder(context);
> >         builder.setMessage(info);
> >         builder.setCancelable(false);
> >
>         builder.setPositiveButton("Yes", new 
> DialogInterface.OnClickListener() {
> >             public void onClick(DialogInterface dialog, int id) {
> >                 ModalDialog.this.mQuitModal = true;
> >                 dialog.dismiss();
> >             }
> >         });
> >         AlertDialog alert = builder.create();
> >         alert.show();
> >         // run in modal mode
> >         doModal();
> >     }
> >     public boolean showConfirmDialog(Context context, String info) {
> >         if (!prepareModal()) {
> >             return false;
> >         }
> >         // reset choice
> >         mChoice = false;
> >         AlertDialog.Builder builder = new AlertDialog.Builder(context);
> >         builder.setMessage(info);
> >         builder.setCancelable(false);
> >
>         builder.setPositiveButton("Yes", new 
> DialogInterface.OnClickListener() {
> >             public void onClick(DialogInterface dialog, int id) {
> >                 ModalDialog.this.mQuitModal = true;
> >                 ModalDialog.this.mChoice = true;
> >                 dialog.dismiss();
> >             }
> >         });
> >
>         builder.setNegativeButton("Cancel", new 
> DialogInterface.OnClickListener() {
> >             public void onClick(DialogInterface dialog, int id) {
> >                 ModalDialog.this.mQuitModal = true;
> >                 ModalDialog.this.mChoice = false;
> >                 dialog.cancel();
> >             }
> >         });
> >         AlertDialog alert = builder.create();
> >         alert.show();
> >         doModal();
> >         return mChoice;
> >     }
> >     private boolean prepareModal() {
> >         Class<?> clsMsgQueue = null;
> >         Class<?> clsMessage = null;
> >         try {
> >             clsMsgQueue = Class.forName("android.os.MessageQueue");
> >         } catch (ClassNotFoundException e) {
> >             e.printStackTrace();
> >             return false;
> >         }
> >         try {
> >             clsMessage = Class.forName("android.os.Message");
> >         } catch (ClassNotFoundException e) {
> >             e.printStackTrace();
> >             return false;
> >         }
> >         try {
> >
>             mMsgQueueNextMethod = clsMsgQueue.getDeclaredMethod("next", new 
> Class[]{});
> >         } catch (SecurityException e) {
> >             e.printStackTrace();
> >             return false;
> >         } catch (NoSuchMethodException e) {
> >             e.printStackTrace();
> >             return false;
> >         }
> >         mMsgQueueNextMethod.setAccessible(true);
> >         try {
> >             mMsgTargetFiled = clsMessage.getDeclaredField("target");
> >         } catch (SecurityException e) {
> >             e.printStackTrace();
> >             return false;
> >         } catch (NoSuchFieldException e) {
> >             e.printStackTrace();
> >             return false;
> >         }
> >         mMsgTargetFiled.setAccessible(true);
> >         return true;
> >     }
> >     private void doModal() {
> >         mQuitModal = false;
> >         // get message queue associated with main UI thread
> >         MessageQueue queue = Looper.myQueue();
> >         while (!mQuitModal) {
> >             // call queue.next(), might block
> >             Message msg = null;
> >             try {
> >
>                 msg = (Message)mMsgQueueNextMethod.invoke(queue, new 
> Object[]{});
> >             } catch (IllegalArgumentException e) {
> >                 e.printStackTrace();
> >             } catch (IllegalAccessException e) {
> >                 e.printStackTrace();
> >             } catch (InvocationTargetException e) {
> >                 e.printStackTrace();
> >             }
> >             if (null != msg) {
> >                 Handler target = null;
> >                 try {
> >                     target = (Handler)mMsgTargetFiled.get(msg);
> >                 } catch (IllegalArgumentException e) {
> >                     e.printStackTrace();
> >                 } catch (IllegalAccessException e) {
> >                     e.printStackTrace();
> >                 }
> >                 if (target == null) {
> >
>                     // No target is a magic identifier for the quit message.
> >                     mQuitModal = true;
> >                 }
> >                 target.dispatchMessage(msg);
> >                 msg.recycle();
> >             }
> >         }
> >     }
> > }
> >
> > Hopefully this would help.
> >
> > --
> > You received this message because you are subscribed to the Google
> > Groups "Android Developers" group.
> > To post to this group, send email to android-developers@googlegroups.com
> > To unsubscribe from this group, send email to
> > android-developers+unsubscr...@googlegroups.com
> > For more options, visit this group at
> > http://groups.google.com/group/android-developers?hl=en
>
>
>
> --
> Mark Murphy (a Commons Guy)
> http://commonsware.com | http://github.com/commonsguy
> http://commonsware.com/blog | http://twitter.com/commonsguy
>
> Android 3.0 Programming Books: http://commonsware.com/books
>
> --
> You received this message because you are subscribed to the Google
> Groups "Android Developers" group.
> To post to this group, send email to android-developers@googlegroups.com
> To unsubscribe from this group, send email to
> android-developers+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/android-developers?hl=en

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to