BlackBerry Forums Support Community
              

Closed Thread
 
Thread Tools
Old 09-15-2008, 09:31 AM   #1
goulamass
Talking BlackBerry Encyclopedia
 
Join Date: Jan 2008
Location: France
Model: 8310
PIN: N/A
Carrier: Vodafone
Posts: 217
Default Thread

Please Login to Remove!

Hi everyone.

I have a thread that recover some information from a web service.

I want to make this update my displaying with the new information found.

In fact I try to add a NullField to my display and plays with its method such a fieldChangeNotify.

And my thread launch a method that try to change the field.

I use setMuddy(true/false) alternatively but nothing appends.

Any idea???
Offline  
Old 09-15-2008, 09:44 AM   #2
Ivanov
Talking BlackBerry Encyclopedia
 
Join Date: Apr 2008
Location: Germany, BW
Model: -
PIN: N/A
Carrier: -
Posts: 310
Default

calling invalidate() on the screen/fieldmanager should update the fields which belong to it

edit: invalidate() on a field should update only that field...

Last edited by Ivanov; 09-15-2008 at 09:50 AM..
Offline  
Old 09-15-2008, 09:59 AM   #3
goulamass
Talking BlackBerry Encyclopedia
 
Join Date: Jan 2008
Location: France
Model: 8310
PIN: N/A
Carrier: Vodafone
Posts: 217
Default

Allright but I have to recreate a new field with the new value.

In fact I want that the thread is able to launch a method .

As it's a thread it can only access static method.

So I create a static method to update the method I want.

This static method change the state of the field and this change make the field calling a method.

I know that maybe it's not clear but it's want I want to make
Offline  
Old 09-15-2008, 10:10 AM   #4
Ivanov
Talking BlackBerry Encyclopedia
 
Join Date: Apr 2008
Location: Germany, BW
Model: -
PIN: N/A
Carrier: -
Posts: 310
Default

i would create an interface for updating your screen and pass it to the constructor of your thread. the thread would call that interface to update the screen...

I'll post a sample if I find one...
Offline  
Old 09-15-2008, 10:22 AM   #5
goulamass
Talking BlackBerry Encyclopedia
 
Join Date: Jan 2008
Location: France
Model: 8310
PIN: N/A
Carrier: Vodafone
Posts: 217
Default

It's a way to proceed as I want.

I will continue the way I'm looking for this evening.

Thanks for your help
Offline  
Old 09-15-2008, 10:29 AM   #6
Ivanov
Talking BlackBerry Encyclopedia
 
Join Date: Apr 2008
Location: Germany, BW
Model: -
PIN: N/A
Carrier: -
Posts: 310
Default

it should look like this:

The Interface:
Code:
public interface IWebServiceResponseListener
{
	void onResponseReceived(String answer); // update to your needs
}
Thread:
Code:
    public class WebServiceCall extends Thread
    {
        private IWebServiceResponseListener _listener;

        public WebServiceCall(IWebServiceResponseListener listener)
        {
            _listener = listener;
        }

        public void run()
        {
           ... call the webservice ...

           // pass the answer to the listener
           _listener.onResponseReceived("WS ANSWER");
        }
    }
Screen:
Code:
        IWebServiceResponseListener _internallistener = new IWebServiceResponseListener()
        {
            public void onResponseReceived(String answer)
            {
                  // evtl. you need to get the event lock before updating
                  MyField.setText(answer);
            }
        };
Offline  
Old 09-15-2008, 11:11 AM   #7
goulamass
Talking BlackBerry Encyclopedia
 
Join Date: Jan 2008
Location: France
Model: 8310
PIN: N/A
Carrier: Vodafone
Posts: 217
Default

Thanks it looks great.

I will test it tomorrow.
Offline  
Old 09-15-2008, 11:44 AM   #8
holy3daps
Thumbs Must Hurt
 
Join Date: Apr 2006
Location: Boston
Model: 8900
Carrier: AT&T
Posts: 98
Default

Hi!

Ivanov's solution is good; he suggests that the "onResponseReceived" method will require you to get the event lock before updating the screen. This is to make sure that the change you make to a field on-screen is performed within the context of the "main event thread", which is what governs the contents of the screen. Another approach is to call
Code:
UiApplication.getUiApplication().invokeLater( new Runnable()
{
    public void run()
    {
        MyField.setText( text );
    }
});
This will cause a short-lived thread to get added to the queue that your application has for screen-handling. You cannot pass parameters (such as "text") to it in this fashion, but there are ways for dealing with that.

Cheers,

karl
__________________
Karl G. Kowalski
---------------
Owns a RAZR
Develops for BlackBerry
So next phone will be........an iPhone 3G!
Offline  
Old 09-16-2008, 03:12 AM   #9
goulamass
Talking BlackBerry Encyclopedia
 
Join Date: Jan 2008
Location: France
Model: 8310
PIN: N/A
Carrier: Vodafone
Posts: 217
Default

I'm not sure to understand exactly what you want to mean karl.

Maybe a short exemple will light me up
Offline  
Old 09-16-2008, 01:11 PM   #10
holy3daps
Thumbs Must Hurt
 
Join Date: Apr 2006
Location: Boston
Model: 8900
Carrier: AT&T
Posts: 98
Default

Okay. Concept first.

Ivanov suggested that you would need to "get the event lock." When your code is executing in a thread that is Not The Main Event Thread (i.e., not the thread that is responding to user input, among other things), any changes you make to the UI (for instance, the text in the labels on the screen, or the length of a progress bar, etc.) will not show up. This is not an absolute - sometimes they might show up, but you cannot depend on behavior that has a "might show up" prospect. If you want the display (the UI) to reflect the modifications your code is making from within a background thread (which is any thread other than the Main Event Thread), you will need to do something special.

One approach is to use the "event lock" mechanism. This is in net.rim.device.api.system.Application, and can be acquired by the execution of the following code:

Code:
UiApplication.getUiApplication().getEventLock()
Check the method call in the RIM API description for the complete set of data regarding this call. Basically, it says you can use this to permit a "worker" thread (a background thread) to halt the Main Event Thread, manipulate the display, and then let it go (it means the changes that the worker thread makes to the UI will be implemented to the display).

Personally, I prefer the following approach. Instead of halting the event lock then modifying the dispaly and then releasing the event lock, I use the "invokeLater" method of the UiApplication to install a Runnable object that UiApplication will execute at some point during the Main Event Thread. Basically, the Main Event Thread is a big "while" loop, which checks for user input and other "events" that it might need to respond to. At some point before a pass through the loop is completed, the Main Event Thread looks for items placed in this "invokeLater" queue (I'm wild-azz guessing here, but it's pretty close to what happens) and executes their "run" method (since they all must be Runnables and therefore must have a run() method somewhere). This means that the code in the objects sitting in the "invokeLater" queue will get executed, eventually, but at least the modifications to the UI will get executed from within the Main Event Thread.

So, here's an example.

Code:
class MyWorkerThread extends Thread
{
    private LabelField _labelIWillChange;

    public MyWorkerThread( LabelField inLabelToChange )
    {
        _labelIWillChange = inLabelToChange;
    }

    public void run()
    {
        // do your background task here
        // when your task completes - or at its "I need to update" phase
        UiApplication.getUiApplication().invokeLater( new UpdateRunnable( newText, _labelIWillChange ) );
    }
}

class UpdateRunnable implements Runnable
{
    private String _newText;
    private LabelField _label;
    public UpdateRunnable( String inNewText, LabelField inLabel )
    {
        _newText = inNewText;
        _label = inLabel;
    }

    public void run()
    {
        _label.setText( _newText );
    }
}
The above code snippet should work. It's not clear whether you also need to get the event lock as mentioned above, within the run() method of the UpdateRunnable. There are more compact ways of achieving the same thing (the UpdateRunnable class is not completely necessary, but it separates the issues so that you can see what's going on). Look through the RIM Development guides for more assistance.

Good luck, and may The Force be with you.

Cheers,

karl
__________________
Karl G. Kowalski
---------------
Owns a RAZR
Develops for BlackBerry
So next phone will be........an iPhone 3G!
Offline  
Old 09-17-2008, 03:24 AM   #11
goulamass
Talking BlackBerry Encyclopedia
 
Join Date: Jan 2008
Location: France
Model: 8310
PIN: N/A
Carrier: Vodafone
Posts: 217
Default

Allright.

But in fact I don't want to just change a text of a label but launch from the main a method.

And I can't really see how can I launch a method of the main from the thread.

When I launch it again it will update the display as I want.

Maybe I have to show you want I mean.
Code:
Main => Method
       => Thread
The method display some informations that the thread recover but as it take time the method display few information.

That I want it th method is called again at each loop of the thread until it ends

Last edited by goulamass; 09-17-2008 at 03:29 AM..
Offline  
Old 09-17-2008, 03:28 AM   #12
Ivanov
Talking BlackBerry Encyclopedia
 
Join Date: Apr 2008
Location: Germany, BW
Model: -
PIN: N/A
Carrier: -
Posts: 310
Default

call your function in your callback implementation. And take care about the event lock for the reasons Karl wrote above.

Code:
        IWebServiceResponseListener _internallistener = new IWebServiceResponseListener()
        {
            public void onResponseReceived(String answer)
            {
                  ... call your screen update function here ...
            }
        };
__________________
Blessed is the end user who expects nothing, for he/she will not be disappointed. (Franklin's Rule)
Offline  
Old 09-17-2008, 03:44 AM   #13
goulamass
Talking BlackBerry Encyclopedia
 
Join Date: Jan 2008
Location: France
Model: 8310
PIN: N/A
Carrier: Vodafone
Posts: 217
Default

Yes it's what I try and understand about your method ivanov.

It's works fine except one thing.

On my method I have a list with the following element :

Button EditField

And when the thread is complete I have 10 time the above elements.

In fact if I want the call to the web service, it's to allow the user to select the first for example without waiting the complete loading.

And with your method, I can't select until the thread finish.

The display is correctly updated.

Any idea???
Offline  
Old 09-17-2008, 04:02 AM   #14
Ivanov
Talking BlackBerry Encyclopedia
 
Join Date: Apr 2008
Location: Germany, BW
Model: -
PIN: N/A
Carrier: -
Posts: 310
Default

Actually I do not clearly understand everything...

You start a connection thread from your main screen. It is running in the background asynchronously with your screen. In your screen you are notified when the thread dies and calls the callback function.

Your main screen is on the main event dispatcher thread so you can do what ever you want during the ws call is running at the same time in another thread.

why do you have 10 copies of your elements? Is it inteded as part of the GUI?
__________________
Blessed is the end user who expects nothing, for he/she will not be disappointed. (Franklin's Rule)
Offline  
Old 09-17-2008, 04:11 AM   #15
goulamass
Talking BlackBerry Encyclopedia
 
Join Date: Jan 2008
Location: France
Model: 8310
PIN: N/A
Carrier: Vodafone
Posts: 217
Default

No in fact I have to make 10 calls to a web service to recover the information of 10 POI.

And your method works but blocks the screen in the way I can't clic on a button before the last call.

I test your method with another thread that recover the GPS and it's the same problem. The siplay is blocked until the thread finish.

What's wrong???
Offline  
Old 09-17-2008, 04:18 AM   #16
Ivanov
Talking BlackBerry Encyclopedia
 
Join Date: Apr 2008
Location: Germany, BW
Model: -
PIN: N/A
Carrier: -
Posts: 310
Default

post your code for the corresponding parts. that might help to find the problem.
__________________
Blessed is the end user who expects nothing, for he/she will not be disappointed. (Franklin's Rule)
Offline  
Old 09-17-2008, 04:45 AM   #17
goulamass
Talking BlackBerry Encyclopedia
 
Join Date: Jan 2008
Location: France
Model: 8310
PIN: N/A
Carrier: Vodafone
Posts: 217
Default

Allright

My method wich launch the GPS thread
Code:
public void attente()
        {
            removeAllMenuItems();
            deleteAll();
            ab = 0;
            //Allow me to make a background color
             VerticalFieldManager vfmPar = new VerticalFieldManager(Manager.VERTICAL_SCROLL)
            {
                protected void paint( Graphics graphics ) 
                {

                    graphics.setBackgroundColor( 0x99caf3 );
                    graphics.clear();

                    // calling super.paint() will create the white background
                    // so instead we will call subpaint() ourselves
                    subpaint( graphics );
                }
                protected void sublayout( int maxWidth, int maxHeight ) 
                {
                    super.sublayout( maxWidth, maxHeight );
                    XYRect extent = getExtent();
                    int width = Math.max( extent.width, Display.getWidth() );
                    int height = Math.max( extent.height, Display.getHeight() );
                    setExtent( width, height );
                }
            };
            
            tmp2 = new EditField("GPS en cours d'acquisition", "" , 20 , EditField.READONLY);
            vfmPar.add(tmp2);
            add(vfmPar);
            
            doPaint();
            
            IWebServiceResponseListener _internallistener = new IWebServiceResponseListener()
            {
                public void onResponseReceived()
                {
                    if(lat > -90 && lat < 90 && lon > -180 && lon < 180)
                    {
                        // Launch the map loading with the correct coordonates
                        Carte();
                    }
                    else
                        //reload the method to try to acquire the GPS again
                        attente();
                }
            };

                GPS gps = new GPS(_internallistener);
                t = new Thread(gps);       
                t.start();
            
            addMenuItem(menu1);
            
            System.out.println("Latitude " + String.valueOf(lat));
            
            System.out.println("Longitude " + String.valueOf(lon));
            
          
    }
The Interface :
Code:
interface IWebServiceResponseListener
{
    void onResponseReceived(); // update to your needs
}
And the GPS thread
Code:
class GPS implements Runnable
{  
        private IWebServiceResponseListener _listener;
    
        public GPS(IWebServiceResponseListener listener)
        {
            _listener = listener;
        }
        
        public void run()
        {
            //Récupérer les coordonnées GPS
            try
            {
                // Create a Criteria object for defining selection criteria
                Criteria cr= new Criteria();
                
                cr.setCostAllowed(false);
                
                LocationProvider lp = LocationProvider.getInstance(cr);
                javax.microedition.location.Location l = lp.getLocation(3000);
            
                Coordinates co = null;
                                                
                if ( l != null && l.isValid() )     
                {
                    co = l.getQualifiedCoordinates();
                
            }
                if(co != null ) 
                {
                    // Use coordinate information
                    GeoTourismeScreen.lat = co.getLatitude();
                    GeoTourismeScreen.lon = co.getLongitude();
                }
                else
                {
                    GeoTourismeScreen.lat = -200;
                    GeoTourismeScreen.lon = -200;
                }
            }
        
            catch(LocationException e)
            {
                GeoTourismeScreen.lat = -400;
                GeoTourismeScreen.lon = -400;
            }
        
            catch(Exception e) 
            {   
                GeoTourismeScreen.lat = -600;
                GeoTourismeScreen.lon= -600;
                System.out.println("Erreur " +e);
            }
            
            _listener.onResponseReceived();
        }
}
Offline  
Old 09-17-2008, 06:05 AM   #18
Ivanov
Talking BlackBerry Encyclopedia
 
Join Date: Apr 2008
Location: Germany, BW
Model: -
PIN: N/A
Carrier: -
Posts: 310
Default

use the call back function to return values - this is what it is inteded for. Using static variables from a parallel thread is not "elegant".

Where is the code for getting the event lock to update the screen?
The code above should work.
__________________
Blessed is the end user who expects nothing, for he/she will not be disappointed. (Franklin's Rule)
Offline  
Old 09-17-2008, 08:16 AM   #19
goulamass
Talking BlackBerry Encyclopedia
 
Join Date: Jan 2008
Location: France
Model: 8310
PIN: N/A
Carrier: Vodafone
Posts: 217
Default

I know taht using static variable isn't elegant but it's the way I use first because it works and I have no time to try something else.

But I'm not sure to understand whant you want to mean.

The code that updating the screen is on the first code I post
Offline  
Old 09-17-2008, 09:14 AM   #20
Ivanov
Talking BlackBerry Encyclopedia
 
Join Date: Apr 2008
Location: Germany, BW
Model: -
PIN: N/A
Carrier: -
Posts: 310
Default

I've tested your code on the emulator with some modifications (event lock holding, setting editfield editable to test gui block) and the GUI was not blocked while the GPS Thread was sleeping in the background.

Code:
	public static class MyScreen2 extends FullScreen
	{
	    public static  double lat = 0;
	    public static double lon = 0;
	    int ab;
	    
	    Thread t;
	       EditField tmp2;
	        
	    private MenuItem _miStart = new MenuItem("start gps", 200000, 10) {
	        public void run()
	        {
	            attente();
	        }
	    };
	    
	    protected void makeMenu(Menu menu, int instance)
	    {
	        menu.add(_miStart);
	        menu.addSeparator();
	        super.makeMenu(menu, instance);
	    }
	    
		public MyScreen2()
		{
			super(Screen.DEFAULT_CLOSE | Screen.DEFAULT_MENU);

		}
		
		  public void attente()
		    {
		        deleteAll();
		        ab = 0;
		        //Allow me to make a background color
		         VerticalFieldManager vfmPar = new VerticalFieldManager(Manager.VERTICAL_SCROLL)
		        {
		            protected void paint( Graphics graphics ) 
		            {

		                graphics.setBackgroundColor( 0x99caf3 );
		                graphics.clear();

		                // calling super.paint() will create the white background
		                // so instead we will call subpaint() ourselves
		                subpaint( graphics );
		            }
		            protected void sublayout( int maxWidth, int maxHeight ) 
		            {
		                super.sublayout( maxWidth, maxHeight );
		                XYRect extent = getExtent();
		                int width = Math.max( extent.width, Display.getWidth() );
		                int height = Math.max( extent.height, Display.getHeight() );
		                setExtent( width, height );
		            }
		        };
		        
		        tmp2 = new EditField("GPS en cours d'acquisition", "");
		        vfmPar.add(tmp2);
		        add(vfmPar);
		        
		        doPaint();
		        
		        IWebServiceResponseListener _internallistener = new IWebServiceResponseListener()
		        {
		            public void onResponseReceived()
		            {
		                synchronized (Application.getEventLock()) // this is actually a bad idea because the event lock should be hold only as short as necessary to update the gui, while here it is doing much more...
		                {
		                    attente();
		                }
		                    
		            }
		        };

		            GPS gps = new GPS(_internallistener);
		            t = new Thread(gps);       
		            t.start();
		        
		        System.out.println("Latitude " + String.valueOf(lat));
		        
		        System.out.println("Longitude " + String.valueOf(lon));     
		}

	}
in GPS I just added a sleep to simulate the delay when getting the gps fix.
By the way, the timeout in getLocation is a value in seconds...
Code:
...
                javax.microedition.location.Location l = lp.getLocation(10);
                
                Thread.sleep(10000);
            
                Coordinates co = null;
...
__________________
Blessed is the end user who expects nothing, for he/she will not be disappointed. (Franklin's Rule)

Last edited by Ivanov; 09-17-2008 at 09:17 AM..
Offline  
Closed Thread



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


Utility Aluminum Trim Coil 24

Utility Aluminum Trim Coil 24" x 40-45 FT Long with Minor Scratches and Dents

$84.95



D4PE12029AA 6 Volt Ignition Coil Fits Ford/New Holland Tractor 600 700 800 picture

D4PE12029AA 6 Volt Ignition Coil Fits Ford/New Holland Tractor 600 700 800

$26.44



1100-0541 6 Volt Ignition Coil for Ford Tractor 2N 8N 9N Front Mount 9N12024 picture

1100-0541 6 Volt Ignition Coil for Ford Tractor 2N 8N 9N Front Mount 9N12024

$27.36



Dental Orthodontic Niti Open Coil Spring Spool .008/010/012/014 Inch 914mm picture

Dental Orthodontic Niti Open Coil Spring Spool .008/010/012/014 Inch 914mm

$74.79



NEW AFTERMARKET FITS 9-1891-13 9-1891-1 9-1891-3 9-1891-7 9-1891-2 9-1891-5 COIL picture

NEW AFTERMARKET FITS 9-1891-13 9-1891-1 9-1891-3 9-1891-7 9-1891-2 9-1891-5 COIL

$144.00



Ignition Coil For Briggs And Stratton 395491 397358; IBS3002 picture

Ignition Coil For Briggs And Stratton 395491 397358; IBS3002

$40.22







Copyright © 2004-2016 BlackBerryForums.com.
The names RIM © and BlackBerry © are registered Trademarks of BlackBerry Inc.