简体   繁体   English

在 Android Studio [Java] 中加载 mapbox map 后的绘图标记

[英]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.这是我在 Android Studio 中的第一个项目,基本上我正在尝试使用 Mapbox 开发具有多个标记的 map。 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.所以,我的问题是,当在 map 上加载标记时,加载大约需要 3-5 秒,并且应用程序冻结,直到我从 API 调用中获得 json。 Here is my retrofit2 call to API:这是我对 API 的改造 2 调用:

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.我将所有站保存在名为 stationList 的 ArrayList 中。 In Station class i have the lat and long coordinates besides other information.在车站 class 除了其他信息外,我还有纬度和经度坐标。

Here is my addMarkers function:这是我的 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.所以经过几次搜索后,我发现这里的“问题”是我在getNearbyStations() 中使用 call.execute()不是异步的,所以主线程正在等待 Stations 加载。 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我尝试使用call.enqueue但之后我遇到了另一个问题,在我的 function addMarkers中我得到 NullPointerException 因为 stationList 没有足够的时间加载

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.我猜我必须使用某种线程来解决这个问题,但我是在 Android Studio 中使用线程的初学者,我想不通。 I think the solution would be:我认为解决方案是:

1.Display the map empty 1.显示map为空

2.Add markers after they load. 2.加载后添加标记。

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.由于问题是您希望应用程序不要等待同步 function,因此我建议为此使用异步任务。 You can then execute the addMarkers function once the onPostExecute callback of the async task is invoked.然后,您可以在调用异步任务的onPostExecute回调后执行addMarkers function。 But make sure to run the addMarkers only after the style has been set in your onMapReady但请确保仅在您的addMarkers中设置样式后运行onMapReady

Please see this documentation on how to use an asynchronous task: https://developer.android.com/reference/android/os/AsyncTask请参阅此文档以了解如何使用异步任务: 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.使用异步任务获得的好处是 Android 将在不同的线程中执行它,从而减轻主线程的负载。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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