I'm writing an Android application with the following basic structure:
MyActivity.java - sets view as MyView.
MyThread.java - contains surfaceHolder, calls update() and render() functions in MyView.java
MyView.java - draws to canvas using render() function, updates MyPuzzle class, handles touch events.
MyPuzzle.java - contains an ArrayList/Vector of elements.
My question is:
In the MyView class, in the render() function I loop through the contents of the ArrayList/Vector held within the MyPuzzle class and draw them to the canvas. However, I was occasionally getting indexOutOfBounds errors (perhaps once every 10 times), despite looping from i=0; i<arraylist.size()...
In the same MyView class, in the onTouchEvent function, I have code which adds/removes items from the ArrayList/Vector which is being drawn.
Are my index out of bounds errors likely caused by the onTouchEvents being processed at the same time as the render() function is looping through the ArrayList/Vector and drawing the elements to the screen?
I tried implementing a system whereby the onTouchEvents were not dealt with immediately, but were added to an ArrayList queue, and only processed before render() is called. This seems to have fixed the problem, with the limited testing I've done of it. Does this sound about right? It's been driving me somewhat mad.
Thanks for your help in advance, apologies for the badly written question, I can add any more detail you may require.
The IndexOutOfBounds is probably a direct result of a situation where the iterating thread will intially see the List at size N and starting iterating from 0 to N. Thread-2 Comes in and removes from the list making it effectively N-1, so if Thread-1 attempts to read at list.get(N) you get your exception.
If the depth of the list isn't very large and you are not removing and adding a whole lost swap the List implementation with CopyOnWriteArrayList. Otherwise you will need to synchronize on all actions of the list including the iterating for example
public void render(){
synchronized(list){
for(int i =0; i <list.size();i++){
//....
}
}
}
public void update(Object element){
synchronized(list){
list.remove(element);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With