Hello Droid devs,
I'm porting C application using NDK and have problems with proper touch
events handling. I tried to apply the solution with "event queue" (here
http://www.rbgrn.net/content/342-using-input-pipelines-your-android-game) but
from some reason the event processing locks the aplication when events are
rapidly fired on the Java side. Here is the scenario:
-The native C code is executed in separate thread.(precisely HandlerThread)
-Once the native code is executed it goes to SELECT() based loop waiting
for network changes.
-then in the SELECT() loop it calls Java side(thru JNI) to poll for any
touch events (pollEvents()) that could be available in the Java event queue.
-Events in the queue are processed using native call (dispatchEvent()) back
to the C code
But at some point(when lot of MOVE events is generated by user) the
pollEvents()
function stops being called (because the C side is busy with all the event
processing??) and only feedInput() calls are made. This leads to
application lock because there is no more free event instances available in
the Java pool putting the inputObjectPool.take() call to waiting and the
app stops responding.
It all seems to be logical to me but I don't understand why the C thread
stops processing when inputObjectPool.take() call waits in the UI thread? I
thought while the UI thread waits the C thread can catch up, process the
pending events and put 'used' event instances back to the pool so the
waiting is canceled and UI thread can continue? Am I missing something here?
I hope my explanation is not too confusing so if you get to this point you
may look at the code below to see what I'm trying to achieve.
Any helpful feedback is welcome!
Thanks,
Rick
Here is simplified code part:
loop on the C side:
while (1) {
if (halted) break;
...
//poll for network changes etc.(using BSD sockets)
...
//call pollEvents() on Java side to check and process events
(*jni_env)->CallVoidMethod(jni_env, jni_obj, jni_pollEvents);
..
select(...); //wait for 16msecs
}
Java side:
private final Object inputQueueMutex = new Object();
private native void dispatchEvent(int action, int x, int y);
public void pollEvents(){
synchronized(inputQueueMutex) {
ArrayBlockingQueue<InputObject> inputQueue = this.inputQueue;
while (!inputQueue.isEmpty()) {
//process the events in queue
try {
InputObject input = inputQueue.take();
//following function dispathes the event for processing on the C side
dispatchEvent(input.action, input.x, input.y);
input.returnToPool();
} catch (InterruptedException e) {
}
}
}
}
public void feedInput(InputObject input) {
synchronized(inputQueueMutex) {
try {
//queue the event
inputQueue.put(input);
} catch (InterruptedException e) {
}
}
}
@Override
public boolean onTouchEvent(final MotionEvent event) {
try {
//get "free" instance from the pool
InputObject input = inputObjectPool.take();
//fill the event data and detect event type
if (!input.useEvent(event)) {
//let OS process events we don't care about
input.returnToPool();
return false;
}
//queue the event
feedInput(input);
} catch (InterruptedException e) {
}
// don't allow more than 60 motion events per second
try {
Thread.sleep(16);
} catch (InterruptedException e) {
}
return true;
}
--
--
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
---
You received this message because you are subscribed to the Google Groups
"Android Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.