Calculate route using Executer instead of Thread

This commit is contained in:
max-klaus 2020-12-20 18:59:48 +03:00
parent cf916a5da7
commit c860f8eea4
3 changed files with 213 additions and 179 deletions

View file

@ -10,11 +10,19 @@ import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.router.RouteCalculationProgress;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import static net.osmand.plus.notifications.OsmandNotification.NotificationType.NAVIGATION;
class RouteRecalculationThreadHelper {
class RouteRecalculationHelper {
private static final int RECALCULATE_THRESHOLD_COUNT_CAUSING_FULL_RECALCULATE = 3;
private static final int RECALCULATE_THRESHOLD_CAUSING_FULL_RECALCULATE_INTERVAL = 2 * 60 * 1000;
@ -22,17 +30,19 @@ class RouteRecalculationThreadHelper {
private final OsmandApplication app;
private final RoutingHelper routingHelper;
private Thread currentRunningJob;
private final ExecutorService executor = new RouteRecalculationExecutor();
private final Map<Future<?>, RouteRecalculationTask> tasksMap = new LinkedHashMap<>();
private RouteRecalculationTask lastTask;
private long lastTimeEvaluatedRoute = 0;
private String lastRouteCalcError;
private String lastRouteCalcErrorShort;
private long recalculateCountInInterval = 0;
private int evalWaitInterval = 0;
private boolean waitingNextJob;
private RouteCalculationProgressCallback progressRoute;
RouteRecalculationThreadHelper(@NonNull RoutingHelper routingHelper) {
RouteRecalculationHelper(@NonNull RoutingHelper routingHelper) {
this.routingHelper = routingHelper;
this.app = routingHelper.getApplication();
}
@ -50,7 +60,14 @@ class RouteRecalculationThreadHelper {
}
boolean isRouteBeingCalculated() {
return currentRunningJob instanceof RouteRecalculationThread || waitingNextJob;
synchronized (routingHelper) {
for (Future<?> future : tasksMap.keySet()) {
if (!future.isDone()) {
return true;
}
}
}
return false;
}
void resetEvalWaitInterval() {
@ -58,24 +75,31 @@ class RouteRecalculationThreadHelper {
}
void stopCalculation() {
Thread job = currentRunningJob;
if (job instanceof RouteRecalculationThread) {
((RouteRecalculationThread) job).stopCalculation();
synchronized (routingHelper) {
for (Entry<Future<?>, RouteRecalculationTask> taskFuture : tasksMap.entrySet()) {
taskFuture.getValue().stopCalculation();
taskFuture.getKey().cancel(false);
}
}
}
void stopCalculationIfParamsChanged() {
Thread job = currentRunningJob;
if (job instanceof RouteRecalculationThread) {
RouteRecalculationThread thread = (RouteRecalculationThread) job;
if (!thread.isParamsChanged()) {
thread.stopCalculation();
void stopCalculationIfParamsNotChanged() {
synchronized (routingHelper) {
boolean hasPendingTasks = tasksMap.isEmpty();
for (Entry<Future<?>, RouteRecalculationTask> taskFuture : tasksMap.entrySet()) {
RouteRecalculationTask task = taskFuture.getValue();
if (!task.isParamsChanged()) {
taskFuture.getKey().cancel(false);
task.stopCalculation();
}
}
if (hasPendingTasks) {
if (isFollowingMode()) {
getVoiceRouter().announceBackOnRoute();
}
}
}
}
private OsmandSettings getSettings() {
return routingHelper.getSettings();
@ -130,8 +154,6 @@ class RouteRecalculationThreadHelper {
}
}
// trigger voice prompt only if new route is in forward direction
// If route is in wrong direction after one more setLocation it will be recalculated
if (!wrongMovementDirection || newRoute) {
@ -144,18 +166,15 @@ class RouteRecalculationThreadHelper {
void startRouteCalculationThread(RouteCalculationParams params, boolean paramsChanged, boolean updateProgress) {
synchronized (routingHelper) {
final Thread prevRunningJob = currentRunningJob;
getSettings().LAST_ROUTE_APPLICATION_MODE.set(getAppMode());
RouteRecalculationThread newThread = new RouteRecalculationThread("Calculating route", params, paramsChanged);
currentRunningJob = newThread;
RouteRecalculationTask newTask = new RouteRecalculationTask(this, params, paramsChanged);
lastTask = newTask;
startProgress(params);
if (updateProgress) {
updateProgress(params);
}
if (prevRunningJob != null) {
newThread.setWaitPrevJob(prevRunningJob);
}
currentRunningJob.start();
Future<?> future = executor.submit(newTask);
tasksMap.put(future, newTask);
}
}
@ -165,7 +184,7 @@ class RouteRecalculationThreadHelper {
return;
}
// do not evaluate very often
if ((currentRunningJob == null && System.currentTimeMillis() - lastTimeEvaluatedRoute > evalWaitInterval)
if ((!isRouteBeingCalculated() && System.currentTimeMillis() - lastTimeEvaluatedRoute > evalWaitInterval)
|| paramsChanged || !onlyStartPointChanged) {
if (System.currentTimeMillis() - lastTimeEvaluatedRoute < RECALCULATE_THRESHOLD_CAUSING_FULL_RECALCULATE_INTERVAL) {
recalculateCountInInterval++;
@ -234,11 +253,7 @@ class RouteRecalculationThreadHelper {
public void run() {
RouteCalculationProgress calculationProgress = params.calculationProgress;
if (isRouteBeingCalculated()) {
Thread t = currentRunningJob;
if (t instanceof RouteRecalculationThread && ((RouteRecalculationThread) t).params != params) {
// different calculation started
return;
} else {
if (lastTask != null && lastTask.params == params) {
progressRoute.updateProgress((int) calculationProgress.getLinearProgress());
if (calculationProgress.requestPrivateAccessRouting) {
progressRoute.requestPrivateAccessRouting();
@ -268,23 +283,21 @@ class RouteRecalculationThreadHelper {
}
}
private void showMessage(final String msg) {
app.runInUIThread(new Runnable() {
@Override
public void run() {
app.showToastMessage(msg);
}
});
}
class RouteRecalculationThread extends Thread {
private static class RouteRecalculationTask implements Runnable {
private final RouteRecalculationHelper routingThreadHelper;
private final RoutingHelper routingHelper;
private final RouteCalculationParams params;
private final boolean paramsChanged;
private Thread prevRunningJob;
public RouteRecalculationThread(String name, RouteCalculationParams params, boolean paramsChanged) {
super(name);
String routeCalcError;
String routeCalcErrorShort;
int evalWaitInterval = 0;
public RouteRecalculationTask(@NonNull RouteRecalculationHelper routingThreadHelper,
@NonNull RouteCalculationParams params, boolean paramsChanged) {
this.routingThreadHelper = routingThreadHelper;
this.routingHelper = routingThreadHelper.routingHelper;
this.params = params;
this.paramsChanged = paramsChanged;
if (params.calculationProgress == null) {
@ -300,39 +313,26 @@ class RouteRecalculationThreadHelper {
params.calculationProgress.isCancelled = true;
}
private OsmandSettings getSettings() {
return routingHelper.getSettings();
}
private void showMessage(final String msg) {
final OsmandApplication app = routingHelper.getApplication();
app.runInUIThread(new Runnable() {
@Override
public void run() {
app.showToastMessage(msg);
}
});
}
@Override
public void run() {
synchronized (routingHelper) {
routingHelper.resetRouteWasFinished();
currentRunningJob = this;
waitingNextJob = prevRunningJob != null;
}
if (prevRunningJob != null) {
while (prevRunningJob.isAlive()) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// ignore
}
}
synchronized (routingHelper) {
if (params.calculationProgress.isCancelled) {
return;
}
currentRunningJob = this;
waitingNextJob = false;
}
}
lastRouteCalcError = null;
lastRouteCalcErrorShort = null;
RouteProvider provider = routingHelper.getProvider();
OsmandSettings settings = getSettings();
RouteCalculationResult res = provider.calculateRouteImpl(params);
if (params.calculationProgress.isCancelled) {
synchronized (routingHelper) {
currentRunningJob = null;
}
return;
}
final boolean onlineSourceWithoutInternet = !res.isCalculated() &&
@ -353,37 +353,54 @@ class RouteRecalculationThreadHelper {
params.resultListener.onRouteCalculated(res);
}
} else {
evalWaitInterval = Math.max(3000, evalWaitInterval * 3 / 2); // for Issue #3899
evalWaitInterval = Math.max(3000, routingThreadHelper.evalWaitInterval * 3 / 2); // for Issue #3899
evalWaitInterval = Math.min(evalWaitInterval, 120000);
}
currentRunningJob = null;
}
OsmandApplication app = routingHelper.getApplication();
if (res.isCalculated()) {
if (!params.inSnapToRoadMode && !params.inPublicTransportMode) {
setNewRoute(prev, res, params.start);
routingThreadHelper.setNewRoute(prev, res, params.start);
}
} else if (onlineSourceWithoutInternet) {
lastRouteCalcError = app.getString(R.string.error_calculating_route)
routeCalcError = app.getString(R.string.error_calculating_route)
+ ":\n" + app.getString(R.string.internet_connection_required_for_online_route);
lastRouteCalcErrorShort = app.getString(R.string.error_calculating_route);
showMessage(lastRouteCalcError); //$NON-NLS-1$
routeCalcErrorShort = app.getString(R.string.error_calculating_route);
showMessage(routeCalcError);
} else {
if (res.getErrorMessage() != null) {
lastRouteCalcError = app.getString(R.string.error_calculating_route) + ":\n" + res.getErrorMessage();
lastRouteCalcErrorShort = app.getString(R.string.error_calculating_route);
showMessage(lastRouteCalcError); //$NON-NLS-1$
routeCalcError = app.getString(R.string.error_calculating_route) + ":\n" + res.getErrorMessage();
routeCalcErrorShort = app.getString(R.string.error_calculating_route);
} else {
lastRouteCalcError = app.getString(R.string.empty_route_calculated);
lastRouteCalcErrorShort = app.getString(R.string.empty_route_calculated);
showMessage(lastRouteCalcError);
routeCalcError = app.getString(R.string.empty_route_calculated);
routeCalcErrorShort = app.getString(R.string.empty_route_calculated);
}
showMessage(routeCalcError);
}
app.getNotificationHelper().refreshNotification(NAVIGATION);
lastTimeEvaluatedRoute = System.currentTimeMillis();
}
}
public void setWaitPrevJob(Thread prevRunningJob) {
this.prevRunningJob = prevRunningJob;
private class RouteRecalculationExecutor extends ThreadPoolExecutor {
public RouteRecalculationExecutor() {
super(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
}
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
RouteRecalculationTask task = null;
synchronized (routingHelper) {
if (r instanceof Future<?>) {
task = tasksMap.remove(r);
}
}
if (t == null && task != null) {
evalWaitInterval = task.evalWaitInterval;
lastRouteCalcError = task.routeCalcError;
lastRouteCalcErrorShort = task.routeCalcErrorShort;
}
lastTimeEvaluatedRoute = System.currentTimeMillis();
}
}
}

View file

@ -54,7 +54,7 @@ public class RoutingHelper {
private OsmandSettings settings;
private final RouteProvider provider;
private final VoiceRouter voiceRouter;
private final RouteRecalculationThreadHelper routeRecalculationHelper;
private final RouteRecalculationHelper routeRecalculationHelper;
private final TransportRoutingHelper transportRoutingHelper;
private boolean isFollowingMode = false;
@ -94,7 +94,7 @@ public class RoutingHelper {
settings = context.getSettings();
voiceRouter = new VoiceRouter(this);
provider = new RouteProvider();
routeRecalculationHelper = new RouteRecalculationThreadHelper(this);
routeRecalculationHelper = new RouteRecalculationHelper(this);
transportRoutingHelper = context.getTransportRoutingHelper();
transportRoutingHelper.setRoutingHelper(this);
setAppMode(settings.APPLICATION_MODE.get());
@ -505,7 +505,7 @@ public class RoutingHelper {
routeRecalculationHelper.recalculateRouteInBackground(currentLocation, finalLocation, intermediatePoints, currentGPXRoute,
previousRoute.isCalculated() ? previousRoute : null, false, !targetPointsChanged);
} else {
routeRecalculationHelper.stopCalculationIfParamsChanged();
routeRecalculationHelper.stopCalculationIfParamsNotChanged();
}
double projectDist = mode != null && mode.hasFastSpeed() ? posTolerance : posTolerance / 2;

View file

@ -13,37 +13,42 @@ import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.data.LatLon;
import net.osmand.data.QuadRect;
import net.osmand.osm.edit.Node;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.settings.backend.CommonPreference;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.render.NativeOsmandLibrary;
import net.osmand.plus.routing.RouteCalculationParams.RouteCalculationResultListener;
import net.osmand.plus.routing.RouteProvider.RouteService;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.CommonPreference;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.router.GeneralRouter;
import net.osmand.router.NativeTransportRoutingResult;
import net.osmand.router.RouteCalculationProgress;
import net.osmand.router.RoutingConfiguration;
import net.osmand.router.TransportRoutePlanner;
import net.osmand.router.TransportRouteResult;
import net.osmand.router.TransportRoutePlanner.TransportRouteResultSegment;
import net.osmand.router.TransportRoutingContext;
import net.osmand.router.TransportRouteResult;
import net.osmand.router.TransportRoutingConfiguration;
import net.osmand.router.NativeTransportRoutingResult;
import net.osmand.router.TransportRoutingContext;
import net.osmand.util.MapUtils;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import static net.osmand.plus.notifications.OsmandNotification.NotificationType.NAVIGATION;
@ -53,10 +58,14 @@ public class TransportRoutingHelper {
private List<WeakReference<IRouteInformationListener>> listeners = new LinkedList<>();
private OsmandApplication app;
private final OsmandApplication app;
private ApplicationMode applicationMode = ApplicationMode.PUBLIC_TRANSPORT;
private RoutingHelper routingHelper;
private final ExecutorService executor = new RouteRecalculationExecutor();
private final Map<Future<?>, RouteRecalculationTask> tasksMap = new LinkedHashMap<>();
private RouteRecalculationTask lastTask;
private List<TransportRouteResult> routes;
private Map<Pair<TransportRouteResultSegment, TransportRouteResultSegment>, RouteCalculationResult> walkingRouteSegments;
private int currentRoute = -1;
@ -64,11 +73,9 @@ public class TransportRoutingHelper {
private LatLon startLocation;
private LatLon endLocation;
private Thread currentRunningJob;
private String lastRouteCalcError;
private String lastRouteCalcErrorShort;
private long lastTimeEvaluatedRoute = 0;
private boolean waitingNextJob;
private TransportRouteCalculationProgressCallback progressRoute;
@ -170,16 +177,16 @@ public class TransportRoutingHelper {
this.currentRoute = currentRoute;
}
public void addListener(IRouteInformationListener l){
public void addListener(IRouteInformationListener l) {
listeners.add(new WeakReference<>(l));
}
public boolean removeListener(IRouteInformationListener lt){
public boolean removeListener(IRouteInformationListener lt) {
Iterator<WeakReference<IRouteInformationListener>> it = listeners.iterator();
while(it.hasNext()) {
while (it.hasNext()) {
WeakReference<IRouteInformationListener> ref = it.next();
IRouteInformationListener l = ref.get();
if(l == null || lt == l) {
if (l == null || lt == l) {
it.remove();
return true;
}
@ -212,18 +219,14 @@ public class TransportRoutingHelper {
private void startRouteCalculationThread(TransportRouteCalculationParams params) {
synchronized (this) {
final Thread prevRunningJob = currentRunningJob;
app.getSettings().LAST_ROUTE_APPLICATION_MODE.set(routingHelper.getAppMode());
RouteRecalculationThread newThread =
new RouteRecalculationThread("Calculating public transport route", params,
RouteRecalculationTask newTask = new RouteRecalculationTask(this, params,
app.getSettings().SAFE_MODE.get() ? null : NativeOsmandLibrary.getLoadedLibrary());
currentRunningJob = newThread;
lastTask = newTask;
startProgress(params);
updateProgress(params);
if (prevRunningJob != null) {
newThread.setWaitPrevJob(prevRunningJob);
}
currentRunningJob.start();
Future<?> future = executor.submit(newTask);
tasksMap.put(future, newTask);
}
}
@ -250,10 +253,7 @@ public class TransportRoutingHelper {
if (isRouteBeingCalculated()) {
float pr = calculationProgress.getLinearProgress();
progressRoute.updateProgress((int) pr);
Thread t = currentRunningJob;
if (t instanceof RouteRecalculationThread && ((RouteRecalculationThread) t).params != params) {
// different calculation started
} else {
if (lastTask != null && lastTask.params == params) {
updateProgress(params);
}
} else {
@ -268,7 +268,23 @@ public class TransportRoutingHelper {
}
public boolean isRouteBeingCalculated() {
return currentRunningJob instanceof RouteRecalculationThread || waitingNextJob;
synchronized (this) {
for (Future<?> future : tasksMap.keySet()) {
if (!future.isDone()) {
return true;
}
}
}
return false;
}
private void stopCalculation() {
synchronized (this) {
for (Map.Entry<Future<?>, RouteRecalculationTask> taskFuture : tasksMap.entrySet()) {
taskFuture.getValue().stopCalculation();
taskFuture.getKey().cancel(false);
}
}
}
private void setNewRoute(final List<TransportRouteResult> res) {
@ -322,9 +338,7 @@ public class TransportRoutingHelper {
}
});
this.endLocation = newFinalLocation;
if (currentRunningJob instanceof RouteRecalculationThread) {
((RouteRecalculationThread) currentRunningJob).stopCalculation();
}
stopCalculation();
}
private void setCurrentLocation(LatLon currentLocation) {
@ -335,15 +349,6 @@ public class TransportRoutingHelper {
recalculateRouteInBackground(currentLocation, endLocation);
}
private void showMessage(final String msg) {
app.runInUIThread(new Runnable() {
@Override
public void run() {
app.showToastMessage(msg);
}
});
}
@Nullable
public QuadRect getTransportRouteRect(@NonNull TransportRouteResult result) {
TransportRoutingHelper transportRoutingHelper = app.getTransportRoutingHelper();
@ -403,7 +408,7 @@ public class TransportRoutingHelper {
}
}
private class WalkingRouteSegment {
private static class WalkingRouteSegment {
TransportRouteResultSegment s1;
TransportRouteResultSegment s2;
LatLon start;
@ -436,18 +441,24 @@ public class TransportRoutingHelper {
}
}
private class RouteRecalculationThread extends Thread {
private static class RouteRecalculationTask implements Runnable {
private final TransportRoutingHelper transportRoutingHelper;
private final RoutingHelper routingHelper;
private final TransportRouteCalculationParams params;
private Thread prevRunningJob;
private final Queue<WalkingRouteSegment> walkingSegmentsToCalculate = new ConcurrentLinkedQueue<>();
private Map<Pair<TransportRouteResultSegment, TransportRouteResultSegment>, RouteCalculationResult> walkingRouteSegments = new HashMap<>();
private boolean walkingSegmentsCalculated;
private NativeLibrary lib;
private final NativeLibrary lib;
public RouteRecalculationThread(String name, TransportRouteCalculationParams params, NativeLibrary library) {
super(name);
String routeCalcError;
String routeCalcErrorShort;
public RouteRecalculationTask(@NonNull TransportRoutingHelper transportRoutingHelper,
@NonNull TransportRouteCalculationParams params, @Nullable NativeLibrary library) {
this.transportRoutingHelper = transportRoutingHelper;
this.routingHelper = transportRoutingHelper.routingHelper;
this.params = params;
this.lib = library;
if (params.calculationProgress == null) {
@ -459,9 +470,9 @@ public class TransportRoutingHelper {
params.calculationProgress.isCancelled = true;
}
/**
* TODO Check if native lib available and calculate route there.
*
* @param params
* @return
* @throws IOException
@ -473,18 +484,18 @@ public class TransportRoutingHelper {
BinaryMapIndexReader[] files = params.ctx.getResourceManager().getTransportRoutingMapFiles();
params.params.clear();
OsmandSettings settings = params.ctx.getSettings();
for(Map.Entry<String, GeneralRouter.RoutingParameter> e : config.getRouter(params.mode.getRoutingProfile()).getParameters().entrySet()){
for (Map.Entry<String, GeneralRouter.RoutingParameter> e : config.getRouter(params.mode.getRoutingProfile()).getParameters().entrySet()) {
String key = e.getKey();
GeneralRouter.RoutingParameter pr = e.getValue();
String vl;
if(pr.getType() == GeneralRouter.RoutingParameterType.BOOLEAN) {
if (pr.getType() == GeneralRouter.RoutingParameterType.BOOLEAN) {
CommonPreference<Boolean> pref = settings.getCustomRoutingBooleanProperty(key, pr.getDefaultBoolean());
Boolean bool = pref.getModeValue(params.mode);
vl = bool ? "true" : null;
} else {
vl = settings.getCustomRoutingProperty(key, "").getModeValue(params.mode);
}
if(vl != null && vl.length() > 0) {
if (vl != null && vl.length() > 0) {
params.params.put(key, vl);
}
}
@ -509,7 +520,6 @@ public class TransportRoutingHelper {
@Nullable
private RouteCalculationParams getWalkingRouteParams() {
ApplicationMode walkingMode = ApplicationMode.PEDESTRIAN;
final WalkingRouteSegment walkingRouteSegment = walkingSegmentsToCalculate.poll();
@ -517,13 +527,14 @@ public class TransportRoutingHelper {
return null;
}
OsmandApplication app = routingHelper.getApplication();
Location start = new Location("");
start.setLatitude(walkingRouteSegment.start.getLatitude());
start.setLongitude(walkingRouteSegment.start.getLongitude());
LatLon end = new LatLon(walkingRouteSegment.end.getLatitude(), walkingRouteSegment.end.getLongitude());
final float currentDistanceFromBegin =
RouteRecalculationThread.this.params.calculationProgress.distanceFromBegin +
RouteRecalculationTask.this.params.calculationProgress.distanceFromBegin +
(walkingRouteSegment.s1 != null ? (float) walkingRouteSegment.s1.getTravelDist() : 0);
final RouteCalculationParams params = new RouteCalculationParams();
@ -547,8 +558,8 @@ public class TransportRoutingHelper {
float p = Math.max(params.calculationProgress.distanceFromBegin,
params.calculationProgress.distanceFromEnd);
RouteRecalculationThread.this.params.calculationProgress.distanceFromBegin =
Math.max(RouteRecalculationThread.this.params.calculationProgress.distanceFromBegin, currentDistanceFromBegin + p);
RouteRecalculationTask.this.params.calculationProgress.distanceFromBegin =
Math.max(RouteRecalculationTask.this.params.calculationProgress.distanceFromBegin, currentDistanceFromBegin + p);
}
@Override
@ -571,7 +582,7 @@ public class TransportRoutingHelper {
params.resultListener = new RouteCalculationResultListener() {
@Override
public void onRouteCalculated(RouteCalculationResult route) {
RouteRecalculationThread.this.walkingRouteSegments.put(new Pair<>(walkingRouteSegment.s1, walkingRouteSegment.s2), route);
RouteRecalculationTask.this.walkingRouteSegments.put(new Pair<>(walkingRouteSegment.s1, walkingRouteSegment.s2), route);
}
};
@ -619,26 +630,18 @@ public class TransportRoutingHelper {
}
}
private void showMessage(final String msg) {
final OsmandApplication app = routingHelper.getApplication();
app.runInUIThread(new Runnable() {
@Override
public void run() {
synchronized (TransportRoutingHelper.this) {
currentRunningJob = this;
waitingNextJob = prevRunningJob != null;
}
if (prevRunningJob != null) {
while (prevRunningJob.isAlive()) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// ignore
}
}
synchronized (TransportRoutingHelper.this) {
currentRunningJob = this;
waitingNextJob = false;
app.showToastMessage(msg);
}
});
}
@Override
public void run() {
List<TransportRouteResult> res = null;
String error = null;
try {
@ -651,38 +654,52 @@ public class TransportRoutingHelper {
log.error(e);
}
if (params.calculationProgress.isCancelled) {
synchronized (TransportRoutingHelper.this) {
currentRunningJob = null;
}
return;
}
synchronized (TransportRoutingHelper.this) {
routes = res;
TransportRoutingHelper.this.walkingRouteSegments = walkingRouteSegments;
synchronized (transportRoutingHelper) {
transportRoutingHelper.routes = res;
transportRoutingHelper.walkingRouteSegments = walkingRouteSegments;
if (res != null) {
if (params.resultListener != null) {
params.resultListener.onRouteCalculated(res);
}
}
currentRunningJob = null;
}
OsmandApplication app = routingHelper.getApplication();
if (res != null) {
setNewRoute(res);
transportRoutingHelper.setNewRoute(res);
} else if (error != null) {
lastRouteCalcError = app.getString(R.string.error_calculating_route) + ":\n" + error;
lastRouteCalcErrorShort = app.getString(R.string.error_calculating_route);
showMessage(lastRouteCalcError);
routeCalcError = app.getString(R.string.error_calculating_route) + ":\n" + error;
routeCalcErrorShort = app.getString(R.string.error_calculating_route);
showMessage(routeCalcError);
} else {
lastRouteCalcError = app.getString(R.string.empty_route_calculated);
lastRouteCalcErrorShort = app.getString(R.string.empty_route_calculated);
showMessage(lastRouteCalcError);
routeCalcError = app.getString(R.string.empty_route_calculated);
routeCalcErrorShort = app.getString(R.string.empty_route_calculated);
showMessage(routeCalcError);
}
app.getNotificationHelper().refreshNotification(NAVIGATION);
lastTimeEvaluatedRoute = System.currentTimeMillis();
}
}
public void setWaitPrevJob(Thread prevRunningJob) {
this.prevRunningJob = prevRunningJob;
private class RouteRecalculationExecutor extends ThreadPoolExecutor {
public RouteRecalculationExecutor() {
super(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
}
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
RouteRecalculationTask task = null;
synchronized (TransportRoutingHelper.this) {
if (r instanceof Future<?>) {
task = tasksMap.remove(r);
}
}
if (t == null && task != null) {
lastRouteCalcError = task.routeCalcError;
lastRouteCalcErrorShort = task.routeCalcErrorShort;
}
lastTimeEvaluatedRoute = System.currentTimeMillis();
}
}
}