简体   繁体   中英

Drawing markers after mapbox map loads in Android Studio [Java]

It's my first project in Android Studio, basically I'm trying to develop a map with multiple markers using Mapbox. So, my problem is when loading the markers on the map it takes a lot of time to load ~3-5 seconds and the app freezes until i get the json from my API call. Here is my retrofit2 call to API:

private void getNearbyStations() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("***")//my API, not relevant
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        jsonPlaceHolderApi = retrofit.create(JsonPlaceHolderApi.class);
        Utilizator utilizator = Utilizator.getUtilizatorInstance();
        Call<ResponseNearbyStations> call = jsonPlaceHolderApi.getNearbyStations(utilizator.getAuthentificationKey(), 47.1744354, 27.5746688);//Static Lat and Long for test, in future will use current location
        try {
            ResponseNearbyStations body = call.execute().body();
            JsonObject jsonObject = body.getData();
                    JsonArray ja_data = jsonObject.getAsJsonArray("stationAround");
                    Station[] statiiPrimite = gson.fromJson(ja_data, Station[].class);
                    stationList = new ArrayList<>(Arrays.asList(statiiPrimite));
        } catch (IOException e) {
            e.printStackTrace();
        }
}

I'm saving all my Stations in an ArrayList called stationList. In Station class i have the lat and long coordinates besides other information.

Here is my addMarkers function:

    private void addMarkers(@NonNull Style loadedMapStyle) {
        List<Feature> features = new ArrayList<>();

        for(Station statie:stationList){    
 features.add(Feature.fromGeometry(Point.fromLngLat(Double.valueOf(statie.getCoordinates().getLongitude()),
Double.valueOf(statie.getCoordinates().getLatitude()))));
        }

        loadedMapStyle.addSource(new GeoJsonSource(MARKER_SOURCE, FeatureCollection.fromFeatures(features)));

        loadedMapStyle.addLayer(new SymbolLayer(MARKER_STYLE_LAYER, MARKER_SOURCE)
                .withProperties(
                        PropertyFactory.iconAllowOverlap(true),
                        PropertyFactory.iconIgnorePlacement(true),
                        PropertyFactory.iconImage(MARKER_IMAGE),
                        PropertyFactory.iconOffset(new Float[]{0f, -52f})
                ));
    }

So after several searching i find out that the "problem" here is that i'm using call.execute() in getNearbyStations() which is not async so the main thread is waiting for the Stations to load. I tried to use call.enqueue but after that i got another problem, in my function addMarkers i get NullPointerException because stationList doesn't have enough time to load in

for(Station statie:stationList){    
 features.add(Feature.fromGeometry(Point.fromLngLat(Double.valueOf(statie.getCoordinates().getLongitude()),
Double.valueOf(statie.getCoordinates().getLatitude()))));
        }

I'm guessing that i have to use some sort of Threading to solve this problem, but i'm a beginner in using Threads for Android Studio, and i couldn't figure it out. I think the solution would be:

1.Display the map empty

2.Add markers after they load.

In this way the user doesn't experience any freezing. Any idea how to solve this problem is welcome.

Since the problem is that you want the application not to wait of the synchronous function, I would recommend to use an asynchronous task for that. You can then execute the addMarkers function once the onPostExecute callback of the async task is invoked. But make sure to run the addMarkers only after the style has been set in your onMapReady

Please see this documentation on how to use an asynchronous task: https://developer.android.com/reference/android/os/AsyncTask

The nice side effect you get by using an aysnchronous task, is that Android will execute it in a different thread and thereby will take load off the main thread.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM