Надо проверить массив на длину. И если он пустой создать маркеры, а если нет - обновлять их местоположение. Но никак не могу достучаться до массива маркеров. Сволоч объявлен final
.
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
Marker[] marker = new Marker[fullDrivers.size()];
final Marker[] finalMarker = marker;
MapsActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
if (fullDrivers.size()>=1) {
for (int i = 0; i < fullDrivers.size(); i++) {
if (finalMarker[i]!=null){
finalMarker[i].setPosition(transfomation(fullDrivers.get(i).getLatlng()));
}
finalMarker[i] = mMap.addMarker(new MarkerOptions().position(transfomation(fullDrivers.get(i).getLatlng())));
}
}
}
});
}
},0,6000);
Я вынужден его так делать. Как мне обойти это?
Модификатор final
не делает переменную константой, он всего лишь делает константой ссылку на переменную. В случае с примитивами, если ссылка становится константой, то и переменная тоже (не Ваш случай), в случаях с объектами это значит, что переменную нельзя поменять на другую, но параметры текущей можно изменять.
Проблема не в модификаторe final
, а в непонимании его сути, но так как Вы не расписали, что значит достучаться
, сложно предположить в чем настоящая проблема - ругается компилятор или ошибка в процессе выполнения? Вы везде опираетесь на fullDrivers.size()
, особенно в цикле, хотя правильнее было бы опираться на finalMarker.length
, вдруг за промежуток времени до выполнения в главном потоке у Вас изменился размер fullDrivers.size()
и Вы лезете за пределы массива? runOnUiThread
не гарантирует моментальное выполнения в главном потоке, он всего лишь ставит Ваш блок кода в очередь на выполнение в главном потоке.
Могу предложить вариант написания кода без модификатора final
у массива маркеров:
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
Marker[] marker = new Marker[fullDrivers.size()];
for (int i = 0; i < marker.length; i++) {
if (marker[i]!=null){
marker[i].setPosition(transfomation(fullDrivers.get(i).getLatlng()));
}
marker[i] = mMap.addMarker(new MarkerOptions().position(transfomation(fullDrivers.get(i).getLatlng())));
}
handler.postDelayed(this, 6000);
}
};
runnable.run();
А когда надо остановите повтор выполнения методом:
handler.removeCallbacks(runnable);
Хотя если почитать документацию, то можно оставить Ваш вариант с таймером без метода runOnUiThread
, в документации я не увидел, чтобы TimerTask
в Timer
выполнялся в другом потоке.
if(finalMarker[i]!=null)
никогда не выполнится. Такой вариант:
private Map<Driver, Marker> markers = new HashMap<>();
private Timer timer = new Timer();
void initTimer(){
timer.scheduleAtFixedRate(new TimerTask(){
void run(){
runOnUIThread(new Runnable(){
void run(){
updateMarkers();
}
});
}
}, 0, 6000);
}
void updateMarkers(){
for(Driver driver: fullDrivers){
Marker marker = markers.get(driver);
if(marker == null){
// добавляем новый маркер
markers.add(driver, mMap.addMarker(
new MarkerOptions()
.position(transfomation(driver.getLatlng())));
} else {
// изменяем существующий
marker.setPosition(transfomation(driver.getLatlng()));
}
}
//Удаляем лишние маркеры
if(markers.size() > fullDrivers.size()){
Iterator<Map.Entry<Driver, Marker>> it = markers.entrySet().iterator();
while (it.hasNext()){
Map.Entry<Driver, Marker> entry = it.next();
if(!fullDrivers.contains(entry.getKey())){
// Удаляем маркер. Что-то типа
mMap.removeMarker(entry.getValue());
it.remove();
}
}
}
}
Вы не можете изменить переменную с модификатором final, это обозначения констант а тут finalMarker[i] = mMap.addMarker(new MarkerOptions().position(transfomation(fullDrivers.get(i).getLatlng())));
вы ей присваиваете новое значения, уберите финал или у вас есть другой массив маркеров.
Ну а если уж очень нужно, то вроде рефлекшен может менять все что угодно, то вот сылка:
private + final = "Нельзя изменить"
private void updateMarkers() {
for(FullDriver driver: fullDrivers){
Marker marker = markers.get(driver);
if(marker == null){
// добавляем новый маркер
markers.put((List<FullDriver>) driver, mMap.addMarker(
new MarkerOptions()
.position(transfomation(driver.getLatlng()))));
} else {
// изменяем существующий
marker.setPosition(transfomation(driver.getLatlng()));
}
}
}
вот и ошибка
05-12 15:43:16.341 3324-3324/xyz.justart.getallandposition E/AndroidRuntime: FATAL EXCEPTION: main
Process: xyz.justart.getallandposition, PID: 3324
java.lang.ClassCastException: xyz.justart.getallandposition.FullDriver cannot be cast to java.util.List
at xyz.justart.getallandposition.MapsActivity.updateMarkers(MapsActivity.java:207)
at xyz.justart.getallandposition.MapsActivity.access$100(MapsActivity.java:32)
at xyz.justart.getallandposition.MapsActivity$2$1.run(MapsActivity.java:194)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7325)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Можно ли сделать так чтобы видео играло одновременно на разных компютерах(браузерах) ?
Здравствуйте, я совсем новичок, требуется создать форму, при заполнении которой значения будут улетать в БД, наведите на путь правильный...
На сайте использую angular, появилась необходимость встроить на сайт картуВыбрал leaflet, но офф решений для angular не нашел, однако нашел angular-leaflet-directive