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
New Developer
Posts: 13
Registered: ‎10-28-2009
My Device: Not Specified

Problem in MultiThreading....

Hi friends,

 

I am starting one new thread to call the web service.

I was using application.invokelater(thread) method to start the uploading thread. But the problem with this is that

I could not able to close the application on clicking End Button (Read). Because event thread not able to process the messages.

 

So I use the Thread.start() method to start the uploading thread.

 

But now the problem is that, I want to show any message or exception using Dialog.alert() in uploding thread then it giving me the exception PushModel Excepiton . Please tell me how to solved the problem

Developer
Posts: 4,764
Registered: ‎07-21-2008
My Device: Not Specified

Re: Problem in MultiThreading....

invokeLater() is used from a non-event thread to interact with the UI (for example, to push or pop a screen).

 

Developer
Posts: 19,636
Registered: ‎07-14-2008
My Device: Not Specified

Re: Problem in MultiThreading....

As I suggested on this Thread, when you asked this question previously:

http://supportforums.blackberry.com/t5/Java-Development/Application-is-not-closing-when-click-to-End...

you need to understand the Event Thread, so review the Video I pointed you at.

http://www.blackberry.com/DevMediaLibrary/view.do?name=WhatistheEventThread

 

If that is not enough, then I recommend that you purchase and review this book:

http://supportforums.blackberry.com/t5/Java-Development/Beginning-BlackBerry-Development-by-Anthony-...

There is a good discussion on the Event Thread in there.

 

There are also plenty of posts on this forum that discuss similar problems to yours that I recommend you review.  If you identify the exact text of your exception and use that to search the forum, I'm sure you will find some matching items that will help you.

 

 

Developer
Posts: 1,415
Registered: ‎07-30-2008
My Device: Not Specified

Re: Problem in MultiThreading....

I guess also as a design issue you may want to consider a global screen if you have

long task and user may want to know right away when it completes. I've played with

some things where a user can que up a bunch of requests ( location points from a server

DB ) and have them load in background but try to preserve phone function for checking

email etc. Then, user gets note when task is no longer blocking on IO.

 

All these GUI's need to somehow serialize asynchronous events, BB has the eventlock object

and something called event thread that isn't much different from a message loop thread.

Basically if it complains with lock try it without (LOL) but keep in mind that this can create hard

to find errors if you guess wrong and no one happened to check Smiley Happy Certainly deadlock comes up

but failing to get lock can produce inconsistent results too.

 

New Developer
Posts: 13
Registered: ‎10-28-2009
My Device: Not Specified

Re: Problem in MultiThreading....

Hi,

 

Thanks for your reply's. But my problem not yet solved. I seen the Event Thread Video but not getting much idea.

 

What I am doing is as follows,

 

When my application starts initially, I also starts GPS Thread which finds GPS locations.

See the Code Below

 

 

public class GPS extends Thread {  
  
    private double latitude;
    private double longitude;
    private String satCountStr;
    private float accuracy;
    private double heading;
    private double altitude;
    private double speed;
  
    private int interval = 1; // time in seconds to get new gps data  
  
    /** 
     * This will start the GPS 
     */  
    public GPS() {  
        // Start getting GPS data  
    	Log.debug("Start getting GPS data");
        if (currentLocation()) {  
            // This is going to start to try and get me some data!  
        }  
    }  
  
    private boolean currentLocation() {  
        boolean retval = true;  
    	Log.debug("in current Location");
        try {  
            LocationProvider lp = LocationProvider.getInstance(null);  
            if (lp != null) {  
                lp.setLocationListener(new LocationListenerImpl(), interval, 1, 1);  
            } else {  
            	Log.error("GPS is not supported, that sucks!");
                // GPS is not supported, that sucks!  
                // Here you may want to use UiApplication.getUiApplication() and post a Dialog box saying that it does not work  
                retval = false;  
            }  
        } catch (LocationException e) {  
            System.out.println("Error: " + e.toString());
        }  
  
        return retval;  
    }  
  
    private class LocationListenerImpl implements LocationListener {
        public void locationUpdated(LocationProvider provider, Location location) {
            if (location.isValid()) {
            	Log.debug("Location is valid");
                heading = location.getCourse();
                longitude = location.getQualifiedCoordinates().getLongitude();
                latitude = location.getQualifiedCoordinates().getLatitude();
                altitude = location.getQualifiedCoordinates().getAltitude();
                speed = location.getSpeed();
                
                Log.debug(heading + "");
                Log.debug(longitude + "");
                Log.debug(latitude + "");
                Log.debug(altitude + "");
                Log.debug(speed + "");
                
                // This is to get the Number of Satellites
                String NMEA_MIME = "application/X-jsr179-location-nmea";
                satCountStr = location.getExtraInfo("satellites");
                if (satCountStr == null) {
                    satCountStr = location.getExtraInfo(NMEA_MIME);
                }
  
                // this is to get the accuracy of the GPS Cords  
                QualifiedCoordinates qc = location.getQualifiedCoordinates();
                accuracy = qc.getHorizontalAccuracy();
            }
        }
  
        public void providerStateChanged(LocationProvider provider, int newState) {
            // no-op  
        }
    }
}

 And to update the one global variable gpsLocation I also started one Timer Thread which updates this variable in some specific time. See the Code below

 

 

public class CheckGPS extends TimerTask{  
        public CheckGPS() {  
        }  
  
        public void run() {  
        	Log.debug("CheckGPS run() method:");
            double lat;  
            double lng;  
            lat = 0;  
            lng = 0;  
  
            lat = gps.getLatitude();  
            lng = gps.getLongitude();
        	Log.debug("Locations: " +lat + "," + lng);
  
            if (lat != 0.0 & lng != 0.0) { 
            	Log.debug("Got locations...");
            	removeProgressBar();
        		invalidate();
                synchronized (app.getAppEventLock()) {  
                    gpsLocations = lat + "," + lng;
                    Log.debug("GPS: " + gpsLocations);
                }
            } else {
            	if(!gpsFlag) {
            		gpsFlag = true;
            		DialogFieldManager manager = new DialogFieldManager();
	    			popup = new PopupScreen(manager);
	    			manager.addCustomField(new LabelField("Initializing Application..."));
            		synchronized (app.getAppEventLock()) {
            			if(popup != null){
            				Log.debug("Progress Bar is adding...");
    		    			app.pushScreen(popup); // original
            			}		    			
            		}
            	}else {
            		removeProgressBar();
            		invalidate();
            	}
            }  
        }
        
        private void removeProgressBar() {
	    	synchronized (app.getAppEventLock()) {
	    		if (popup != null) {
	    			Log.debug("Progress bar is removing...");
	    			app.popScreen(popup);
	    			popup = null;
	    		}
	    	}
	    }
    }

 

It's working fine (Here initially when application starts and we request for the GPS service it takes some time get initialization, therefore I am using progress screen to wait some time) (If you want to suggest the best way than this please suggest me that also)

 

 

 

 

I have one MenuItem uploadPendingCases , when we click it One new Thread starts which call the web service and get back the response. I want to show that response in Dialog.alert("");

 

 

private final class UploadThread extends Thread
	{
		private final String _uploadType;
		
		private UploadThread(String uploadType)
		{
			Log.debug("UploadThread Initialise");
			this._uploadType = uploadType;
		}
		
		public void run() 
		{
			if(_uploadType.equals("New"))
			{
				Log.debug("Uploading New Case started by UploadThread");
				upload();
			}
			else if(_uploadType.equals("Pending"))
			{
				Log.debug("Uploading pending cases started by UploadThread");
    			StatusInfo info = GetDataFromLocal.getInstance().readDataFromXML();
    			showMessage(info.getMessage());
			}

			removeProgressBar();
    		invalidate();
    		Log.debug("UploadThread terminating...");
		}

	    private void removeProgressBar() 
	    {
	    	synchronized (app.getAppEventLock()) 
	    	{
	    		if (popup != null) 
	    		{
	    			Log.debug("Progress bar is removing...");
	    			app.popScreen(popup);
	    			popup = null;
	    		}
	    	}
	    }
	}

 readDataFromXML()  method has web service calling logic. It call web service successfully.

Now I want to show the response msg. I am calling showMessage("msg"); 

 

 

private static void showMessage(String message) 
	{
		synchronized (FieldReportSystem.getEventLock()) 
		{
			Dialog.alert(message);
		}
	}

 

One more thing,

 

to start the Threads, I am using Thread.start(), and not  application.invokeLater() becuase

If I use application.invokeLater() I am not able to close (or get application background) by clicking End Button (Red Button) of blackberry. But here I can able to show messages in Dialog.alert()

 

So I am using Thread.start() to start the thread. But now can not show the Message in Dialog.alert();

 

 

Now I explain in detail what I want to do.

Please tell me the solution.

If you want to suggest any improvement (or mistake) in above code please let me know.

 

Thanks & Regards,

Manesh

 

 

 

Developer
Posts: 19,636
Registered: ‎07-14-2008
My Device: Not Specified

Re: Problem in MultiThreading....

Have you done what I suggested I suggested in my previous Post including:

 

"There are also plenty of posts on this forum that discuss similar problems to yours that I recommend you review.  If you identify the exact text of your exception and use that to search the forum, I'm sure you will find some matching items that will help you."

 

Speaking personally, I prefer to help people who are clearly trying to help themselves and won't help people who are just asking me to do their work for them.  I'm a little concerned this is the case here.  This is not me being mean.  If I give you an answer then you have learned nothing, and when the answer breaks, you will not understand how to fix it.  I would prefer you learnt something. 

 

And have you tried changing your showMessage to the following?

 

private static void showMessage(String message)
{
UiApplication.getUiApplication.invokeLater(new Runnable()
{
public void run()
{
Dialog.alert(message);
}
});
}

// code is not tested or compiled, but you should get the idea

 

If this change does not fix your problem can you tell us exactly what the error message (the full text) and which line it occurs on.

 

 

 

Developer
Posts: 1,415
Registered: ‎07-30-2008
My Device: Not Specified

Re: Problem in MultiThreading....

"to start the Threads, I am using Thread.start(), and not  application.invokeLater() becuase"

 

you can't just uniformly do one or the other. Anything that needs to be serialized with respect to

GUI operations should be on event thread or use the lock. Othewise, your threads can

hang GUI or cause GUI to stop. See sun.com tutorials on synchronization and even the AWT

gui may be of some help but I can't actually remember anymore. For that matter, see stuff

on windoze message loop structure as it is not a lot different.

As they say, "stuff happens" but sometimes you need to synchronize the stuff, sometimes you don't.