# РЕАЛЬНОЕ исправление зависаний карты и кнопок ## НАЙДЕНА ИСТИННАЯ ПРИЧИНА! **Главная проблема**: В `MapLibreMapImpl.updateOwnVesselPosition()` вызывалось **ТРИ отдельных** `uiHandler.post()` операции: ```java // СТАРЫЙ КОД - ПРОБЛЕМНЫЙ: uiHandler.post(() -> updateOwnVesselPathSource("own_vessel", pathCoords)); // 1 uiHandler.post(() -> updateOwnVesselPredictionSource("own_vessel", vessel)); // 2 uiHandler.post(() -> refreshGeoJson()); // 3 ``` ## Проблемы создававшие блокировки: ### 1. **Множественные UI операции** Каждое обновление GPS/NMEA вызывало **4 раза** `updateOwnVesselPosition` из AppController: - Из GPS `onLocationUpdated` (2 раза) - Из NMEA `onVesselUpdated` (2 раза) ### 2. **Тяжелые операции в UI потоке**: - `refreshGeoJson()` - пересоздание всей GeoJSON каждый раз - `updateOwnVesselPathSource()` - обновление источника с множеством координат - `updateOwnVesselPredictionSource()` - расчет прогноза ### 3. **reffreshGeoJson() проблематичен**: ```java private void refreshGeoJson() { JSONObject fc = new JSONObject(); fc.put("type", "FeatureCollection"); JSONArray features = new JSONArray(); for (JSONObject f : idToFeature.values()) { // Итерация по ВСЕМ судам features.put(f); // Объект преобразуется в JSON } fc.put("features", features); source.setGeoJson(fc.toString()); // Создание большой строки! } ``` ## ВНЕСЕННЫЕ ИСПРАВЛЕНИЯ: ### 1. **Throttling система в MapLibreMapImpl**: ```java // Новые переменные для throttling private final android.os.Handler mapUpdateHandler = new android.os.Handler(android.os.Looper.getMainLooper()); private Runnable mapUpdateRunnable; private boolean mapUpdatePending = false; private static final long MAP_UPDATE_DELAY = 500; // 500ms throttling ``` ### 2. **Переработанный updateOwnVesselPosition**: ```java @Override public void updateOwnVesselPosition(Vessel vessel) { // Данные обновляются СРАЗУ (не блокирующее) JSONObject feature = buildFeature(...); idToFeature.put("own_vessel", feature); // Throttled обновление карты updateMapThrottled(vessel); } ``` ### 3. **Батчевое обновление карты**: ```java private void updateMapBatched(Vessel vessel) { uiHandler.post(() -> { // ВСЕ операции в ОДНОМ UI вызове: updateOwnVesselPathSource("own_vessel", pathCoords); updateOwnVesselPredictionSource("own_vessel", vessel); refreshGeoJson(); // Только один раз! }); } ``` ### 4. **Убрали дублированные вызовы в AppController**: - Удалили **2 избыточных** вызова `updateOwnVesselPosition` - Теперь остается только **1 throttled** вызов вместо **4 обычных** ## Результат: - ✅ **Throttling**: вместо постоянных обновлений - 1 раз в 500мс - ✅ **Батчинг**: вместо 3 отдельных UI вызовов - 1 объединенный - ✅ **Дедупликация**: вместо 4 вызовов из AppController - 1 throttled - ✅ **Защита от зависания**: cleanup handler'ов в cleanup() ## Ожидаемый эффект: 1. **Карта и кнопки перестанут зависать** 2. **Доквиджеты продолжат работать** (они не затрагивались) 3. **Фоновые процессы не пострадают** 4. **Обновления карты станут плавными** вместо лагающих **Ключевая диагностика**: Смотрите в логах `"Карта обновлена батчом"` - это означает что throttling работает правильно.