I’m trying to implement a way to trigger a request for map overlay data (from an external web server) only when it seems necessary.
To do this i’m thinking about having screen touch events trigger a counter in an external thread, if the user hovers over a map area without touching the screen for about a second a request is sent.
Event flow would look something like this:
UI Thread -down press-----release-----down---release---------------------->
v v v
Worker Thread -----------------start------stop----start---------------send---->
timer======timer timer==============request
<1s 1s
I’m having trouble getting the UIthread to stop the wait() call in a method and throw an InterruptionException, hence stepping out of the method body before it can execute the request.
I basically want to just bypass any msg queue for the thread and have it stop execution instantly though I’m not sure this is possible. Am I on track here? My code for this is shown below:
public class ExtendedMapView extends MapView {
private final static int DOWN_PRESS = 1;
private final static int RELEASE_PRESS = 2;
private Handler countThreadHandler;
private TouchThread touchMonitor ;
public ExtendedMapView(Context context, AttributeSet attrs) {
super(context, attrs);
touchMonitor = new TouchThread();
touchMonitor.start();
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch(ev.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.d("TEST", "Touch Screen");
touchMonitor.interrupt();
break;
case MotionEvent.ACTION_UP:
Log.d("TEST", "Touch released");
countThreadHandler.sendMessage(Message.obtain(countThreadHandler,RELEASE_PRESS));
break;
default:
break;
}
return super.onTouchEvent(ev);
}
private class TouchThread extends Thread {
@Override
public void interrupt() {
super.interrupt();
Log.d("TEST", "Thread interrupted");
}
@Override
public synchronized void run() {
try {
Looper.prepare();
countThreadHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case DOWN_PRESS:
runOnDown();
break;
case RELEASE_PRESS:
runOnUp();
break;
}
};
Looper.loop();
Log.d("TEST", "thread started");
} catch (Throwable t) {
t.printStackTrace();
Log.d("TEST", "thread not started");
}
}
private synchronized void runOnUp() {
Log.d("TEST", "count started");
downPressed = false;
try {
Log.d("TEST", "Timer started");
wait(1000);
//SEND REST MSG BASED OFF RECIEVED MAP FILL CO-ORDS
Log.d("TEST", "send Rest msg--------------------->");
} catch (InterruptedException e) {
e.printStackTrace();
Log.d("TEST", "Received Interruption NIIICE");
}
}
}
}
I will keep reading and trying in the mean-time. Thanks 😀
Maybe you should consider using the
postDelayedmethod in the Handler instead of calling wait. So you would want to create a Runnable that will make your request and then in runOnUp you would do something like.myHandler.postDelayed(onUpRunnable, 1000)If then it comes time to cancel that request you just callmyHandler.removeCallbacks(onUpRunnable)I hope this helps!edit: note this will only stop the runnable from starting if it hasn’t already started. If it has started it will have no effect.