Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Developer
Posts: 69
Registered: ‎10-27-2008
My Device: Not Specified

Re: Possible bug in OS 5.0 with SendListener?

vamshee,

 

It probably will not work on OS 5.0 at all until RIM fixes this issue.  The fact that you are trying to get a user input while the SendListener is in progress seems to be where there is a deadlock (as proven by Peter).

 

We can't do anything until RIM either fixes the issue (and all OS 5.0 versions prior to the fix will be incompatible with our software) or comes out with a workaround (which, I highly doubt can be done, but you never know...).

 

 

Matty

 

Please use plain text.
Developer
Developer
CMY
Posts: 1,123
Registered: ‎02-10-2009
My Device: 8130 / 8350 / 9530 / 9550 / 9850 / PlayBook
My Carrier: Verizon

Re: Possible bug in OS 5.0 with SendListener?

Have you tried using a simple spin lock?

 

example:

 

 

    volatile int answer = -1;    

    private int ask( final String message,
                     final Object[] choices,
                     final int defaultChoice )
    {
        final Dialog dialog = new Dialog(
                                          message,
                                          choices,
                                          null,
                                          defaultChoice,
                                          Bitmap
                                              .getPredefinedBitmap( Bitmap.QUESTION ) );

        synchronized ( Application.getEventLock() )
        {
            Application.getApplication().invokeAndWait( new Runnable()
            {

                public void run()
                {
                    UiApplication.getUiApplication().pushModalScreen( dialog );
                }

            } );
        }

        while( (answer=dialog.getSelectedValue()) < 0 ){}

        return answer;
    }

 

 

Also, I know on OSes previous to 4.7 I always have to synchronize to get on the event thread, but on 4.7+ I almost never have to. Have you tried removing the synchronized from around the inokeLaterAndWait?

 

Please use plain text.
Developer
Posts: 69
Registered: ‎10-27-2008
My Device: Not Specified

Re: Possible bug in OS 5.0 with SendListener?

Thanks for the thought, but it sadly doesn't work.  The main issue is something behind the scenes that is running the SendListener.sendMessage() method is grabbing the needed lock and we need it to display the dialog for the response to know what to do from inside that method.

 

In your example, I even changed the invokeAndWait() to an invokeLater() (to immediately pass by the statement), but one of two things happened:

 

1] If the 'defaultChoice' is set to a number equal to or greater than 0, the dialog.getSelectedValue() gets that value immediately and it doesn't stop at all at the while loop.  It therefore passes right on through, the email gets sent off and the dialog is presented to the user after the fact (where the response to the dialog doesn't matter, as the email is either already stopped or sent), or

 

2] If the 'defaultChoice' is set to a number less than 0 (e.g.: -1), the while loop spins forever, never dropping out of the sendMessage() method and the Runnable.run() method never gets run (even using the invokeLater() method).  This freezes the mail application exactly like previous attempts to retrieve an answer to the dialog before exiting the sendMessage() method.

 

 

Matty

Please use plain text.
Developer
Developer
CMY
Posts: 1,123
Registered: ‎02-10-2009
My Device: 8130 / 8350 / 9530 / 9550 / 9850 / PlayBook
My Carrier: Verizon

Re: Possible bug in OS 5.0 with SendListener?

I know this is probably not the best answer. But since something in the OS is holding the "global UiApplication/Application" event lock, have you tried creating a dummy UiApplication instance that you can use to push your screens from. I had to use a similar trick to get some processing done with two apps I have. One does the same as you are doing but without using the SendListener and another I needed because a MenuItem was exiting immediately before my background processing was complete.

 

What I did was create an alternate entry point and mark as a System Module so that it will not show in the task switcher. Then whenever I need to do something I just call that entry point to create my screen and then it kills itself when it is done.

Please use plain text.
New Developer
vamshee
Posts: 2
Registered: ‎02-04-2010
My Device: 9700
My Carrier: AT&T

Re: Possible bug in OS 5.0 with SendListener?

I got a work around from RIM

 

CheckExternalEmailAddresses.java

 

package test.demo.mail.addresschecker;

import net.rim.blackberry.api.mail.Message;
import net.rim.blackberry.api.mail.NoSuchServiceException;
import net.rim.blackberry.api.mail.SendListener;
import net.rim.blackberry.api.mail.Session;
import net.rim.blackberry.api.mail.Store;
import net.rim.device.api.system.Application;
import net.rim.device.api.system.ApplicationManager;
import net.rim.device.api.system.RuntimeStore;

public class CheckExternalEmailAddresses extends Application implements SendListener {

        //GlobalEvent ID = test.demo.mail.addresschecker
        public static long key = 0x2a134a8398fedb1L;
        public static String identifier = "OKAY";
        RuntimeStore myRTStore;

        public static void main (String [] args){
                new CheckExternalEmailAddresses().enterEventDispatcher();
        }

        public CheckExternalEmailAddresses(){
                Store store;
                this.addGlobalEventListener(new WaitForDialog());
                try {
                        store = Session.waitForDefaultSession().getStore();
                        store.addSendListener(this);
                } catch (NoSuchServiceException e) {
                        e.printStackTrace();
                }
        }

        public boolean sendMessage(final Message message) {
                String subject = message.getSubject();
                int index = subject.indexOf(identifier);
                if (index== -1){
                        Application.getApplication().invokeLater(new Runnable(){
                                public void run(){
                                        RuntimeStore.getRuntimeStore().replace(key, message);
                                        ApplicationManager.getApplicationManager().postGlobalEvent(key);
                                }
                        });
                        return false;
                }
                subject = subject.substring(0,index);
                return true;
        }

}

 

-------------------------------------------------

WaitForDialog.java

 

package test.demo.mail.addresschecker;

import net.rim.blackberry.api.mail.Address;
import net.rim.blackberry.api.mail.Message;
import net.rim.blackberry.api.mail.MessagingException;
import net.rim.blackberry.api.mail.Transport;
import net.rim.device.api.system.Application;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.GlobalEventListener;
import net.rim.device.api.system.RuntimeStore;
import net.rim.device.api.ui.Ui;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.UiEngine;
import net.rim.device.api.ui.component.CheckboxField;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.DialogClosedListener;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.VerticalFieldManager;

public class WaitForDialog implements GlobalEventListener, DialogClosedListener {

        Message message;
        Address [] toAddresses;
        String emailAddressDomain = "@Domain.com";
        UiApplication uiApplication;

        public void check(){
                boolean foundExternal = false;
                try {
                        toAddresses = message.getRecipients(Message.RecipientType.TO);
                        for (int i=0 ; i < toAddresses.length; i++){
                                if (toAddresses[i].getAddr().indexOf(emailAddressDomain) == -1){
                                        foundExternal=true;
                                        break;
                                }
                        }
                } catch (MessagingException e) {
                        e.printStackTrace();
                        return;
                }
                if (foundExternal){ 

                        Dialog dialog = new Dialog(Dialog.D_YES_NO, "This email is addressed to external recipients, continue?", Dialog.NO,

Bitmap.getPredefinedBitmap(Bitmap.EXCLAMATION),0){

                                public void inHolster()
                                {
                                }
                        };
                        dialog.setDialogClosedListener(this);
                       
                        synchronized(Application.getEventLock()){   
                                UiEngine ui = Ui.getUiEngine();
                                ui.pushGlobalScreen(dialog, 1, UiEngine.GLOBAL_QUEUE);
                        }
                }
        }

        public void eventOccurred(long arg0, int arg1, int arg2, Object arg3,
                        Object arg4) {
                if (arg0 == CheckExternalEmailAddresses.key){
                        this.message = (Message)RuntimeStore.getRuntimeStore().remove(CheckExternalEmailAddresses.key);
                        check();
                }

        }

        public void dialogClosed(Dialog dialog, int choice) {
                if (choice != Dialog.NO){
                        try{
                                String subject = message.getSubject();
                                message.setSubject(subject + "OKAY");
                                Transport.send(message);
                        }catch (MessagingException e){
                                e.printStackTrace();
                        }
                }

        }

}

 

It worked for me. This seems to be the only alternative for now.

 

-vamshee

 

 

Please use plain text.
Developer
Posts: 69
Registered: ‎10-27-2008
My Device: Not Specified

Re: Possible bug in OS 5.0 with SendListener?

Finally got around to trying this out (my listener does a TON of work and has many different execution paths, so it was complicated), but it worked.

 

Thanks

M

 

Please use plain text.
Developer
Posts: 69
Registered: ‎10-27-2008
My Device: Not Specified

Re: Possible bug in OS 5.0 with SendListener?

Oh, and before I forget, this workaround has slowed everything down considerably.  I'm guessing it's because it now is executing on a background thread instead of the foreground, so the slice of CPU processing is smaller.  I'm finding it's maybe 2-3 times slower -- but at least it runs.

 

M

 

Please use plain text.