STOP PROMOTING THIS. I am serious. You are telling people to do something that will cause their app to break.
On Thu, Jun 2, 2011 at 5:42 AM, Qi Luo <[email protected]> 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-ndk" group. > To post to this group, send email to [email protected]. > To unsubscribe from this group, send email to > [email protected]. > For more options, visit this group at > http://groups.google.com/group/android-ndk?hl=en. > -- Dianne Hackborn Android framework engineer [email protected] Note: please don't send private questions to me, as I don't have time to provide private support, and so won't reply to such e-mails. All such questions should be posted on public forums, where I and others can see and answer them. -- You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/android-developers?hl=en

