fixed concurrency issues

This commit is contained in:
madwasp79 2019-04-17 17:45:22 +03:00
parent a8f6aadcc2
commit 39e5534072
3 changed files with 60 additions and 31 deletions

View file

@ -3,7 +3,7 @@ package net.osmand.aidl;
import java.util.Map;
public interface AidlCallbackListener{
void addAidlCallback(IOsmAndAidlCallback callback, int key);
long addAidlCallback(IOsmAndAidlCallback callback, int key);
boolean removeAidlCallback(long id);
Map<Long, OsmandAidlService.AidlCallbackParams> getAidlCallbacks();
}

View file

@ -78,6 +78,7 @@ import org.apache.commons.logging.Log;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import static net.osmand.aidl.OsmandAidlConstants.CANNOT_ACCESS_API_ERROR;
import static net.osmand.aidl.OsmandAidlConstants.MIN_UPDATE_TIME_MS;
@ -97,7 +98,7 @@ public class OsmandAidlService extends Service implements AidlCallbackListener {
private Handler mHandler = null;
HandlerThread mHandlerThread = new HandlerThread("OsmAndAidlServiceThread");
private long aidlCallbackId = 0;
private final AtomicLong aidlCallbackId = new AtomicLong(0);
private OsmandApplication getApp() {
return (OsmandApplication) getApplication();
@ -128,7 +129,6 @@ public class OsmandAidlService extends Service implements AidlCallbackListener {
super.onCreate();
OsmandAidlApi api = getApi("setting_listener");
if(api != null) {
LOG.debug("aidl api not null!");
api.aidlCallbackListener = this;
}
}
@ -136,15 +136,27 @@ public class OsmandAidlService extends Service implements AidlCallbackListener {
@Override
public void onDestroy() {
super.onDestroy();
mHandlerThread.quit();
callbacks.clear();
OsmandAidlApi api = getApi("clear_listener");
if(api != null) {
api.aidlCallbackListener = null;
}
mHandlerThread.quit();
}
private long getCallbackId() {
return aidlCallbackId.get();
}
private long getAndIncrementCallbackId() {
return aidlCallbackId.getAndIncrement();
}
@Override
public void addAidlCallback(IOsmAndAidlCallback callback, int key) {
aidlCallbackId++;
callbacks.put(aidlCallbackId, new AidlCallbackParams(callback, key));
public long addAidlCallback(IOsmAndAidlCallback callback, int key) {
callbacks.put(getAndIncrementCallbackId(), new AidlCallbackParams(callback, key));
return getCallbackId();
}
@Override
@ -748,9 +760,9 @@ public class OsmandAidlService extends Service implements AidlCallbackListener {
public long registerForUpdates(long updateTimeMS, IOsmAndAidlCallback callback) {
try {
if (updateTimeMS >= MIN_UPDATE_TIME_MS) {
addAidlCallback(callback, KEY_ON_UPDATE);
startRemoteUpdates(updateTimeMS, aidlCallbackId, callback);
return aidlCallbackId;
long id = addAidlCallback(callback, KEY_ON_UPDATE);
startRemoteUpdates(updateTimeMS, id, callback);
return getCallbackId();
} else {
return MIN_UPDATE_TIME_MS_ERROR;
}
@ -1034,9 +1046,9 @@ public class OsmandAidlService extends Service implements AidlCallbackListener {
removeAidlCallback(params.getCallbackId());
return -1;
} else {
addAidlCallback(callback, KEY_ON_NAV_DATA_UPDATE);
api.registerForNavigationUpdates(aidlCallbackId);
return aidlCallbackId;
long id = addAidlCallback(callback, KEY_ON_NAV_DATA_UPDATE);
api.registerForNavigationUpdates(id);
return id;
}
} else {
return -1;

View file

@ -26,6 +26,7 @@ import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
@ -39,8 +40,8 @@ public class RoutingHelper {
private static final float POSITION_TOLERANCE = 60;
private List<WeakReference<IRouteInformationListener>> listeners = new CopyOnWriteArrayList<>();
private List<WeakReference<IRoutingDataUpdateListener>> updateListeners = new CopyOnWriteArrayList<>();
private List<WeakReference<IRouteInformationListener>> listeners = new LinkedList<>();
private List<WeakReference<IRoutingDataUpdateListener>> updateListeners = new LinkedList<>();
private OsmandApplication app;
private TransportRoutingHelper transportRoutingHelper;
@ -267,20 +268,30 @@ public class RoutingHelper {
}
public void addDataUpdateListener(IRoutingDataUpdateListener listener) {
updateListeners.add(new WeakReference<>(listener));
}
public boolean removeDataUpdateListener(IRoutingDataUpdateListener listener) {
Iterator<WeakReference<IRoutingDataUpdateListener>> it = updateListeners.iterator();
while(it.hasNext()) {
WeakReference<IRoutingDataUpdateListener> wrl = it.next();
IRoutingDataUpdateListener l = wrl.get();
if(listener == l) {
List<WeakReference<IRoutingDataUpdateListener>> copyList = new ArrayList<>(updateListeners);
Iterator<WeakReference<IRoutingDataUpdateListener>> it = copyList.iterator();
while (it.hasNext()) {
WeakReference<IRoutingDataUpdateListener> ref = it.next();
IRoutingDataUpdateListener l = ref.get();
if (l == null) {
it.remove();
return true;
}
}
return false;
copyList.add(new WeakReference<>(listener));
updateListeners = copyList;
}
public void removeDataUpdateListener(IRoutingDataUpdateListener listener) {
List<WeakReference<IRoutingDataUpdateListener>> copyList = new ArrayList<>(updateListeners);
Iterator<WeakReference<IRoutingDataUpdateListener>> it = copyList.iterator();
while (it.hasNext()) {
WeakReference<IRoutingDataUpdateListener> ref = it.next();
IRoutingDataUpdateListener l = ref.get();
if (l == null || l == listener) {
it.remove();
}
}
updateListeners = copyList;
}
public boolean removeListener(IRouteInformationListener lt){
@ -288,7 +299,7 @@ public class RoutingHelper {
while(it.hasNext()) {
WeakReference<IRouteInformationListener> ref = it.next();
IRouteInformationListener l = ref.get();
if(l == lt) {
if(l == null || lt == l) {
it.remove();
return true;
}
@ -521,13 +532,19 @@ public class RoutingHelper {
currentRoute = newCurrentRoute + 1;
app.getNotificationHelper().refreshNotification(NotificationType.NAVIGATION);
if (!updateListeners.isEmpty()) {
for (WeakReference<IRoutingDataUpdateListener> ref : updateListeners) {
if (ref.get() != null) {
ref.get().onRoutingDataUpdate();
ArrayList<WeakReference<IRoutingDataUpdateListener>> tmp = new ArrayList<>(updateListeners);
Iterator<WeakReference<IRoutingDataUpdateListener>> it = tmp.iterator();
while (it.hasNext()) {
WeakReference<IRoutingDataUpdateListener> ref = it.next();
IRoutingDataUpdateListener l = ref.get();
if (l == null) {
it.remove();
} else {
l.onRoutingDataUpdate();
}
updateListeners = tmp;
}
}
} else {
break;
}