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
canamgroup
Posts: 117
Registered: ‎07-16-2008
My Device: Not Specified
Accepted Solution

A couple of questions regarding Threads and LocationListener

Hi,

 

I did an application a long time ago that gets GPS coordinates from the Blackberry and sends them to a Web Server. It works fine, but I'm sure it's far from being perfect (it was my first and only BB app).

 

Now, I want to modify it to include peter_strange great recommendations for points validation:

http://supportforums.blackberry.com/t5/Java-Development/GPS-coordinates-are-sometimes-not-accurate/t...

 

While I'm there, I want to improve my code by using a LocationListener instead of a repeated .getLocation... but I have a few questions about threads (and others if you don't mind).

 

Here's my sample code:

public class MyApp extends UiApplication {
    private static double _lat;
    private static double _lng;
    private static int _sat;

    public MyApp() {
        pushScreen(new MyScreen());
        try {
            BlackBerryCriteria myCriteria = new BlackBerryCriteria(GPSInfo.GPS_MODE_AUTONOMOUS);
            try {
                BlackBerryLocationProvider myProvider = (BlackBerryLocationProvider)LocationProvider.getInstance(myCriteria);        
                myProvider.setLocationListener(new MyLocationListener(), 60, -1, -1);
            } catch(LocationException lex) {
                return;
            }
        } catch(UnsupportedOperationException ex) {
            return;
        }
    }

    private static class MyLocationListener implements LocationListener {
        public void locationUpdated(LocationProvider provider, Location location) {
            if (location.isValid()) {
                if (location instanceof BlackBerryLocation) {
                    BlackBerryLocation myLocation = (BlackBerryLocation)location;
                    _lat = myLocation.getQualifiedCoordinates().getLatitude();
                    _lng = myLocation.getQualifiedCoordinates().getLongitude();
                    _sat = myLocation.getSatelliteCount();    

                    ConnectionThread thread = new ConnectionThread();
                    thread.start();
                }
            } else {
                // invalid location
            }
        }

        public void providerStateChanged(LocationProvider provider, int newState) {
            if (newState == LocationProvider.OUT_OF_SERVICE) {
                // GPS unavailable
            } else if (newState == LocationProvider.TEMPORARILY_UNAVAILABLE) {
                // no GPS fix
            }
        }
    }

    private static class ConnectionThread extends Thread {
        public void run() {
            String data = "Lat: " + _lat + "\n" + "Lng: " + _lng + "\n" + "Sat: " + _sat;
            try {
                HttpConnection con = (HttpConnection)Connector.open("URL"); // open the URL connection
                con.setRequestMethod(HttpConnection.POST); // POST method
                con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                OutputStream out = con.openOutputStream(); // post data as a stream
                out.write(data.getBytes());
                int responseCode = con.getResponseCode(); // push data and receive response code
                if (responseCode == HttpConnection.HTTP_OK) {
                    // success
                }
                if (con!=null) con.close(); // close the URL connection
            } catch(Exception e) {
                // do something
            }
        }
    }
    
    private static class MyScreen extends MainScreen {
        public MyScreen() {
            super();
            setTitle("BlackBerryLocationContinuousFix");
            add(new RichTextField("Getting GPS fixes... \n"));        
        }
    }

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

 

(It seems to work fine by the way)

 

1- As I understand it, the code inside my LocationListener is executed on the main thread, is it ok since it's a very small code?

2- I create a new thread each time in my LocationListener to send GPS coordinates to my Web Server.  I read that network connections should be done in a separate thread and that a thread terminates when the run() method has completed.  Am I right so far?

3- Is it OK to create a new thread each time, or should I create only one and always use the same? If the latter, how can I do that? I tried creating a new thread in my constructor, and only using thread.start() in my LocationListener, but that returned an error.

4- If I want to add validations, and do some more processing, I assume this should be done in the run() method intead of in my LocationListener?

 

Non-related to threads:

5- I understand that my instances variables had to be "static" cause my LocationListener class was "static" too and that static methods cannot access instance variables... but why has my LocationListener class to be static? (they said to make it static in the RIM documentation).

6- Regarding the above, do my Thread class and my Screen inner class has to be static too?

 

Sorry for the big post and all the questions, I'm just trying to improve my understanding of Blackberry development.  BTW, I found the new class extension (for Location) makes it easier than in the past.

 

Thanks!

Please use plain text.
Developer
canamgroup
Posts: 117
Registered: ‎07-16-2008
My Device: Not Specified

Re: A couple of questions regarding Threads and LocationListener

Anyone?

Please use plain text.
Developer
peter_strange
Posts: 19,601
Registered: ‎07-14-2008
My Device: Not Specified

Re: A couple of questions regarding Threads and LocationListener

1- As I understand it, the code inside my LocationListener is executed on the main thread, is it ok since it's a very small code?

 

As I understand it, this is actually run on a separate Background Thread provided by the LocationProvider. 

 

2- I create a new thread each time in my LocationListener to send GPS coordinates to my Web Server.  I read that network connections should be done in a separate thread and that a thread terminates when the run() method has completed.  Am I right so far?

 

Yes

 

3- Is it OK to create a new thread each time, or should I create only one and always use the same? If the latter, how can I do that? I tried creating a new thread in my constructor, and only using thread.start() in my LocationListener, but that returned an error.

 

You can have just one 'connection Thread, then you would create a Queue for it process.  When there is nothing in the queue it can pause.  You can wake it up again with wait/notidy.  I'm not sure this is needed in your case - but you need to think about what happens if the GPS location can not be sent back.  Do you store it for later.  IOn whhc case a continuous Thread clearing out any unsent GSP values would probably be a good idea. 

 

4- If I want to add validations, and do some more processing, I assume this should be done in the run() method intead of in my LocationListener?

 

It certainly can be done there and that seems an appropriate place.

 

Non-related to threads:

5- I understand that my instances variables had to be "static" cause my LocationListener class was "static" too and that static methods cannot access instance variables... but why has my LocationListener class to be static? (they said to make it static in the RIM documentation).

 

Where do they say that?  Doesn't make sense to me.  But then I have never really understood the value of a static class.

 

6- Regarding the above, do my Thread class and my Screen inner class has to be static too?

 

See above.  I would avoid making things static. 

Please use plain text.
Developer
canamgroup
Posts: 117
Registered: ‎07-16-2008
My Device: Not Specified

Re: A couple of questions regarding Threads and LocationListener

1- OK, so a new thread is automaticaly created for me.  That explains why every sample code I found on the web didn't actually create a new thread.

 

2- At least, I was right about this one.

 

3- That's the most difficult part.  I indeed want to store my GPS coordinate if I wasn't able to send it over the network.  I then want to send it later with the new GPS coordinate as well (keep at least the last 5 GPS coordinates).  I've been looking at the gpsdemo sample all day and still haven't quite understood those wait/notify thread, queues and all those synchronized blocks.

 

4- Good.

 

5- I'm with you, I don't know why this class should be static.

"In the class, create a private static class that implements the LocationListener interface."

p. 35 of the "BlackBerry Java Application Location-Based Services 5.0" guide found here:

http://docs.blackberry.com/en/developers/deliverables/11944/index.jsp?name=Location-Based+Services+-...

 

6- I won't make them static then.

 

 

You pretty much answered all my questions again!

I'm just still a big confused about #3 with those wait/notify and thread clearing.

Could you elaborate a bit more?

I'll continue investigating  the gpsdemo code, maybe I'll figure it out.

 

Thanks for your help!

Please use plain text.
Developer
peter_strange
Posts: 19,601
Registered: ‎07-14-2008
My Device: Not Specified

Re: A couple of questions regarding Threads and LocationListener

Sorry I am really not the best for explaining multi-threaded stuff.  However if you search the forum, you will find that Simon Hain has pointed a few people who have asked about this sort of thing to various java tutorials.  Google search too. 

 

There are however two parts to this:

 

1) The most important part if understanding how a pattern like this should work.  In this case you have a single Server (the Thread that is sending the requests t the Host, and you need to add entries to a queue for this to process, then wake the processing up to send it.  You need to look for a pseudo code or simple example of this implementation so that you understand in principle what you are doing

 

2) Then you need to understand notify/wait so that you understand exactly how you are going to do it. 

 

The first part is actually the most involved and also the one where you will find examples.  However people often write clever complicated things.  In this case you just need a Vector to act as a queue, then you need to take the top off the queue, process it, and when processed, delete the top off the queue and pick up the next one.  You must synchronize to make sure that you don't take one off the queue at the same time as someone is adding a location to the queue to send.  And then the final trick is being able to find the queue and persist it, but  that is easy if the Vector is in PersistentStore. 

 

Anyway, look round for more...

Please use plain text.
Developer
canamgroup
Posts: 117
Registered: ‎07-16-2008
My Device: Not Specified

Re: A couple of questions regarding Threads and LocationListener

I wish RIM made a guide for multi-threaded stuff.

There are many good guides here (for UI, Location, Multimedia, etc...):

http://docs.blackberry.com/en/developers/subcategories/?userType=21&category=Development+Guides&subC...

 

But nothing talks in-depth about threads (unless I missed it).

 

Your explanations are very helpful.

I'll continue playing with this :smileyhappy:

 

Thanks again!

Please use plain text.
Developer
peter_strange
Posts: 19,601
Registered: ‎07-14-2008
My Device: Not Specified

Re: A couple of questions regarding Threads and LocationListener

Threads are not RIM specific, so they assume, probably correctly, that there are loads of good tutorials on things like this already. 

Please use plain text.
Developer
canamgroup
Posts: 117
Registered: ‎07-16-2008
My Device: Not Specified

Re: A couple of questions regarding Threads and LocationListener

Good point, I should have thought about that.

I'll probably need to read more about threads in Java in general.

Please use plain text.