generated from Grigo/AndroidTemplate
feat: новая архитектура UI и расширенная визуализация AIS
Архитектурные улучшения: - Внедрен UIRenderingCoordinator с централизованным throttling - Решены проблемы зависания UI через батчинг операций карты - Добавлен VesselPathController для отслеживания маршрутов - Реализован MapLibreMapImpl как альтернатива Яндекс.Картам Визуализация AIS: - Добавлены векторные иконки для всех типов судов - Разделение Class A/B судов с соответствующими иконками - Иконки навигационных статусов (anchor, moored, engine, sail) - Улучшенный CursorOverlay с информацией о судах Производительность: - Throttling UI обновлений (vessel: 500ms, AIS: 1s, paths: 2s) - Устранение утечек Handler объектов - Оптимизация GeoJSON операций в MapLibre
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
# Анализ и исправление зависаний UI в MainActivity
|
||||
|
||||
## Выявленные проблемы:
|
||||
|
||||
### 1. **Основная причина зависания**: `updateControlPanelPosition()`
|
||||
- Функция вызывается **слишком часто** (7+ мест вызова)
|
||||
- Выполняет **дорогие операции в главном потоке**:
|
||||
- Множественные `getHeight()` вызывают **layout pass**
|
||||
- `setLayoutParams()` - одна из **самых дорогих операций** в Android UI
|
||||
- Множество логирования в главном потоке
|
||||
- Вызывается каждые несколько секунд из-за автоматических обновлений
|
||||
|
||||
### 2. **Цепочка блокировок**:
|
||||
```
|
||||
coordinatesWidget.updateVessel()
|
||||
→ invalidate()
|
||||
→ onDraw()
|
||||
→ getHeight()
|
||||
→ onDockResize callback
|
||||
→ updateControlPanelPosition()
|
||||
→ setLayoutParams() ← BLOCKING!
|
||||
```
|
||||
|
||||
### 3. **Множественные UI обновления**:
|
||||
- `messageAgeRunnable` - каждую секунду
|
||||
- `bottomSheetUpdateRunnable` - каждую секунду
|
||||
- `timeUpdateRunnable` - каждую секунду
|
||||
- Все в главном UI потоке без throttling
|
||||
|
||||
## Внесенные исправления:
|
||||
|
||||
### 1. **Throttling для `updateControlPanelPosition`**:
|
||||
```java
|
||||
// Добавлены переменные для throttling
|
||||
private android.os.Handler controlPanelUpdateHandler;
|
||||
private Runnable controlPanelUpdateRunnable;
|
||||
private boolean controlPanelUpdatePending = false;
|
||||
private static final long CONTROL_PANEL_UPDATE_DELAY = 200; // 200ms throttling
|
||||
|
||||
// Переработана функция с оптимизациями
|
||||
private void updateControlPanelPositionSafe() {
|
||||
// Проверки на нулевые размеры (избегаем layout pass)
|
||||
if (compassHeight <= 0) return;
|
||||
if (coordinatesHeight <= 0) return;
|
||||
|
||||
// Изменения только если отличаются от текущих
|
||||
if (params.topMargin != topMargin || params.bottomMargin != bottomMargin) {
|
||||
// Применяем изменения
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. **Безопасные UI обновления**:
|
||||
```java
|
||||
private void updateVesselPositionUI(Vessel vessel) {
|
||||
if (isFinishing() || isDestroyed()) return; // Защита
|
||||
|
||||
runOnUiThread(() -> {
|
||||
try {
|
||||
updateUIActivity(); // Обновляем watchdog
|
||||
// ... безопасные операции
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Ошибка в updateVesselPositionUI: " + e.getMessage(), e);
|
||||
}
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### 3. **Дополнительная диагностика**:
|
||||
```java
|
||||
// Добавлен счетчик вызовов updateControlPanelPosition
|
||||
private int controlPanelUpdateCount = 0;
|
||||
|
||||
// Улучшен UI Watchdog с диагностикой handler'ов
|
||||
Log.i(TAG, "UI WATCHDOG: Handler status - " +
|
||||
"watchdog=" + watchdogActive +
|
||||
", controlPanelCount=" + controlPanelUpdateCount);
|
||||
|
||||
// Принудительная остановка при превышении лимита
|
||||
if (controlPanelUpdateCount > 50) {
|
||||
// Останавливаем слишком частые обновления
|
||||
}
|
||||
```
|
||||
|
||||
### 4. **Очистка ресурсов**:
|
||||
```java
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
// Добалена очистка throttling handler'а
|
||||
if (controlPanelUpdateHandler != null) {
|
||||
controlPanelUpdateHandler.removeCallbacks(controlPanelUpdateRunnable);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Ожидаемый результат:
|
||||
|
||||
1. **Значительное снижение нагрузки** на главный UI поток
|
||||
2. **Устранение блокировок** от `setLayoutParams()`
|
||||
3. **Throttling обновлений** control panel до безопасного уровня
|
||||
4. **Улучшенная диагностика** для понимания проблем в рантайме
|
||||
5. **Автоматическое восстановление** при превышении лимитов
|
||||
|
||||
## Мониторинг:
|
||||
|
||||
Следите за логами:
|
||||
- `"Control panel updates count: X за последние 10 сек"` - количество обновлений
|
||||
- `"UI WATCHDOG: Handler status"` - состояние всех handler'ов
|
||||
- `"Control panel updated: top=X, bottom=Y"` - фактические обновления
|
||||
|
||||
## Если проблема остается:
|
||||
|
||||
1. Проверьте количество вызовов updateControlPanelPosition
|
||||
2. Рассмотрите полную отключение тестового обновления coordinatesWidget
|
||||
3. Увеличьте CONTROL_PANEL_UPDATE_DELAY до 500мс
|
||||
4. Добавьте дополнительный throttling для BottomSheet обновлений
|
||||
Reference in New Issue
Block a user