It is necessary to check the array for length. And if it is empty, create markers, and if not, update their location. But I can’t reach the array of markers. The bastard is declared 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); 

I have to do it like this. How do I get around this?

  • 3
    Why bypass it? Well, you can create a field in a class and access it. Without this, just contact. - Rou1997
  • @ Rou1997 can not understand more clearly? - elik
  • one
    Remove final?) - FORTRAN
  • then tried finalMarker [i] .setPosition (transfomation (fullDrivers.get (i) .getLatlng ())); swears that announce the final - elik
  • Specify the complete error message and the line on which it occurs. - default locale

4 answers 4

The final modifier does not make a variable a constant; it merely makes a constant reference to the variable. In the case of primitives, if the link becomes a constant, then the variable is also (not your case), in cases with objects, this means that the variable cannot be changed to another, but the parameters of the current can be changed.

The problem is not in the final modifier, but in the lack of understanding of its essence, but since you didn’t describe what it means достучаться , it’s hard to guess what the real problem is - is the compiler cursing or the error is in progress? Everywhere you fullDrivers.size() on fullDrivers.size() , especially in the cycle, although it would be more correct to rely on finalMarker.length , suddenly you have changed the size of fullDrivers.size() and you climb out of the array for the period before the execution in the main thread? runOnUiThread does not guarantee instant execution in the main thread, it just puts your block of code in the queue for execution in the main thread.

I can offer a variant of writing code without the final modifier for an array of markers:

 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(); 

And when you need to stop the execution of the repeat method:

 handler.removeCallbacks(runnable); 
    1. You re-create the array each time. The if(finalMarker[i]!=null) branch will never be executed.
    2. Every 6 seconds, all the markers will be doubled, and then triple, and so on .... For all that, the array does not make sense, the code is equivalent to creating markers every 6 seconds. Probably else missed.

    This option:

     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(); } } } } 
    • Right now I will try your method - elik
    • where did driver come from ??? - elik
    • From List<Driver> fullDrivers . Perhaps you have some other class name there, you did not indicate in the question what is lying there. - Yura Ivanov
    • yes .List <FullDriver> fullders = new ArrayList <> (); - elik
    • Tried to do so - elik

    You cannot change a variable with the final modifier, these are the notation for constants and here finalMarker[i] = mMap.addMarker(new MarkerOptions().position(transfomation(fullDrivers.get(i).getLatlng()))); you assign a new value to it, remove the final, or you have another array of markers. Well, if you really need it, then something like reflexion can change anything, then here is the link: private + final = "You can not change"

       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())); } } } 

      here is the mistake

       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) 
      • 1. Questions in questions. 2. Read the error message. - Qwertiy
      • error says that Full Draver cannot be attached to the list - elik
      • one
        So how is this error related to final if you have the wrong type there? - Qwertiy
      • @Qwertiy yes I am not right. How to fix it? I do - elik
      • for (List <FullDriver> driver: fullDrivers) the compiler underlines it with red - elik