So, this is what I have now:
public void receiveMessage(BinaryMessage binaryMsg) {
...
if ( validateMessage(binaryMsg) ) {
final TrafficMessage message =
createMessage(binaryMsg);
Log.i( CoCarMapView.TAG, "traffic
messages vector size: " + new
Integer(CoCarMapView.trafficMessages.size()).toString() );
// update the UI - show the messages
/* the traffic container and the UI
update should be
* executed from the UI and not from
the receiving
* thread, therefore a handler is used
to return
* these operations to the UI thread
*/
handler.post(new Runnable() {
public void run() {
addTrafficMessage(message, CoCarMapView.trafficMessages);
CoCarMapView.showTrafficMessages();
}
});
}
}
....
} // end of method
I assumed I had to put addTrafficMessage inside the handler thread, as
the collection is modified here. The exception is gone!
Thanks,
Lex
On Aug 28, 10:12 am, Lex <[email protected]> wrote:
> Zsolt,
>
> the methods are defined as follows:
>
> - receiveMessage() - Service Class
> - showTrafficMessages() - Activity Class
> - updateOverlay - ItemizedOverlay Class
>
> The receiveMessage() method is called in the run method of the
> receiving thread object. I see now that other methods are then
> executed in the receiving thread (due to callback) as well.
>
> I will check out the Handler and get back to you later. Thanks a lot
> for your advice!
>
> Lex
>
> On Aug 27, 6:40 pm, Zod <[email protected]> wrote:
>
> > Hi!
>
> > It's not clear where your code is located and called. If it's in the
> > thread which receives the messages, than you're modifying UI elements
> > from another thread which is really bad.
>
> > If your code is in the activity object, and you call it directly from
> > the network thread, than you also execute code in a thread which is
> > not the UI thread (very bad again), and therefore if the Overlay is
> > currently drawn and at that moment you receive a new message you will
> > try to modify a List while it is accessed by another thread (the UI).
>
> > There is already a facility in the android api which can help you put
> > your data into the UI thread in a safe way.
>
> > See:http://developer.android.com/reference/android/os/Handler.html
>
> > Heres a simple example using Handler.post()
>
> > In you activity where your UI components are. Create a Handler object,
> > (eg: mHandler = new Handler())
>
> > Pass this mHandler object to your network thread. When your network
> > thread receives a message use this handler to send a Runnable object
> > to be executed in the UI thread. Eg:
>
> > receiveMessage(String msg) {
> > // send a runnable to execution in the thread which created the
> > handler
> > mHandler.post(new Runnable() { // implement the Runnable interface
> > public void run() {
> > activity.updateUI(); // <- what to call in the
> > handler thread.
> > }
> > });
>
> > }
>
> > If your thread is implemented as an inner class of your activity, you
> > can call the necessary method directly in the Runnable.run method.
>
> > I hope this helps.
>
> > Zsolt.
>
> > On Aug 27, 12:41 pm, Lex <[email protected]> wrote:
>
> > > This post is in addition
> > > to:http://groups.google.com/group/android-developers/browse_thread/threa...
>
> > > I have exactly the same problem and Doug pinpointed what's probably
> > > the issue in my case exactly:
>
> > > So here's the deal: I have a Vector containing traffic messages
> > > (received from a server via UDP in an own thread). Each time a message
> > > is received, I create a new overlay object and populate it with the
> > > traffic messages:
>
> > > public void receiveMessage(BinaryMessage binaryMsg) {
>
> > > ....
> > > TrafficMessage message = createMessage(binaryMsg);
> > > // adds message to vector
> > > addTrafficMessage(message,
> > > CoCarMapView.trafficMessages);
> > > CoCarMapView.showTrafficMessages();
> > > ....
>
> > > }
>
> > > public static void showTrafficMessages() {
> > > List<Overlay> overlays = mapView.getOverlays();
> > > if (overlays.size() > 1) {
> > > overlays.remove(1);
> > > }
> > > Drawable warningIcon = context.getResources().getDrawable
> > > (R.drawable.sign_warning_small);
> > > CoCarItemizedOverlay trafficEventsOverlay = new
> > > CoCarItemizedOverlay
> > > (warningIcon);
>
> > > // the overlay is populated here
> > > trafficEventsOverlay.updateOverlay(trafficMessages);
>
> > > mapView.getOverlays().add(trafficEventsOverlay);
> > > mapView.postInvalidate();
>
> > > }
>
> > > public void updateOverlay(Vector<TrafficMessage> messages) {
> > > for(int i=0; i < messages.size(); i++) {
>
> > > TrafficMessage message = messages.elementAt(i);
> > > Drawable messageIcon = getMessageIcon(message);
> > > GeoPoint point = getGeoPoint(message);
> > > OverlayItem messageItem = createItem(messageIcon,
> > > point);
> > > this.addItem(messageItem);
>
> > > }
>
> > > }
>
> > > I don't understand yet exactly where the error is caused, that is
> > > where to start improving stuff...
>
> > > Thanks for your advice,
>
> > > Lex
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---