fixed concurrency issues
This commit is contained in:
parent
a8f6aadcc2
commit
39e5534072
3 changed files with 60 additions and 31 deletions
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue