Управление ресурсами
Skija — это Java-обёртка вокруг библиотеки Skia на C++. Это означает, что многие Java-объекты поддерживаются нативными ресурсами C++. Понимание того, как управляются эти ресурсы, критически важно для создания стабильных и эффективных приложений.
Автоматическое управление памятью
По умолчанию Skija управляет памятью автоматически. Большинство объектов Skija наследуются от класса Managed. Когда Java-объект удаляется сборщиком мусора, Skija гарантирует, что соответствующий нативный ресурс C++ также будет освобождён.
void drawSomething(Canvas canvas) {
Paint paint = new Paint(); // Нативный ресурс выделен
canvas.drawCircle(50, 50, 20, paint);
} // paint выходит из области видимости, будет очищен сборщиком мусора в будущемДля большинства случаев использования это поведение "безопасное по умолчанию" — именно то, что нужно.
Ручное освобождение ресурсов
В высокопроизводительных приложениях или при работе с множеством короткоживущих объектов может потребоваться немедленно освобождать нативные ресурсы, не дожидаясь сборщика мусора.
Все объекты Managed реализуют интерфейс AutoCloseable, поэтому можно использовать паттерн try-with-resources:
void drawCircle(Canvas canvas) {
try (Paint p = new Paint()) {
canvas.drawCircle(50, 50, 20, p);
} // Нативный ресурс освобождается НЕМЕДЛЕННО здесь
}Предупреждение: После закрытия объекта его нельзя использовать повторно. Попытка использовать закрытый объект приведёт к исключению или сбою.
Повторное использование объектов
Поскольку создание нативных объектов может иметь некоторую накладную нагрузку, часто лучше повторно использовать их, особенно в цикле отрисовки.
class MyApp {
private final Paint paint = new Paint().setColor(0xFFFF0000);
void onRender(Canvas canvas) {
canvas.drawCircle(100, 100, 50, paint); // Повторное использование того же объекта paint
}
}Инкапсуляция и геттеры
Skija использует определённое соглашение для своих классов данных (таких как Rect, Color4f). Вы часто будете видеть публичные поля, начинающиеся с подчёркивания (например, _r, _g, _b в Color4f).
Соглашение:
- Поля, начинающиеся с
_, следует рассматривать как приватные/внутренние. - Всегда используйте предоставленные геттеры (например,
getR(),getG()) для доступа через публичный API.
Color4f color = new Color4f(1f, 0f, 0f);
float r = color._r; // ИЗБЕГАТЬ: Доступ к внутреннему полю
float r2 = color.getR(); // РЕКОМЕНДУЕТСЯ: Использование публичного геттераТакой подход позволяет Skija поддерживать стабильный API, даже если внутренняя реализация этих классов данных изменится в будущих версиях.