-
기기와 이미지와 센서는 이론보다 늦게 도착합니다AI Agent/flutter 2026. 7. 9. 15:00728x90반응형

컨트롤러 초기화 전에 그려진 빨간 화면 카메라 미리보기 화면을 처음 붙이던 날이었습니다.
위젯을 올리고 앱을 켜자마자, 화면 대신 새빨간 에러 화면이 앱을 뒤덮었습니다.
컨트롤러가 초기화되기 전에 미리보기를 그리려다 null을 만난 겁니다.
이상했던 건 코드 순서상으로는 분명히 초기화를 먼저 호출해뒀다는 점이었습니다.
위에 초기화를 적고 아래에 미리보기를 그렸는데, 왜 아래가 먼저 실행된 것처럼 구는지 한참 갸웃했습니다.
처음엔 제가 initState와 build 순서를 헷갈렸나 싶어 코드를 몇 번이나 다시 읽었죠.코드는 위에서 아래로 읽히지만 하드웨어는 그렇지 않다
에러 메시지를 다시 읽어보니 컨트롤러가 아직 준비되지 않았다는 이야기였습니다.
반신반의하면서initialize()앞뒤와 build 맨 위에 print를 하나씩 심어봤습니다.
로그가 찍힌 순서가 제 예상을 뒤집었습니다.
build가 먼저 지나가고, 초기화가 끝났다는 로그는 한참 뒤에야 찍혔거든요.제가 착각한 건 이겁니다.
initialize()를 build보다 위에 적어뒀으니 당연히 카메라가 먼저 준비될 거라고 믿은 것.
근데 카메라 초기화는 비동기라, 함수를 호출한 그 순간에 끝나 있는 게 아니었습니다.
호출은 먼저 나갔지만 실제로 장치가 열리는 데는 시간이 걸렸고, 그 사이에 화면은 이미 첫 프레임을 그려버렸습니다.
그 프레임이 붙잡은 건 아직 준비 안 된 컨트롤러였고요.await를 걸지 않고 호출만 던져두면, Dart는 그 결과를 기다려주지 않고 곧장 다음 줄로 넘어갑니다.
저는 그 '다음 줄'이 하필 build일 거라고는 생각도 못 했습니다.
코드는 위에서 아래로 읽히지만, 하드웨어가 대답하는 순서는 제 코드 순서를 따라주지 않았습니다.시간을 정해놓고 기다리는 건 답이 아니었다
그래서 처음엔 손쉽게 막아보려 했습니다.
초기화 호출을 initState로 옮겨봤고, 그래도 안 되자 미리보기를 잠깐 늦추면 되겠지 싶어Future.delayed로 몇백 밀리초를 억지로 기다리게도 해봤습니다.
화면은 대충 떴습니다.
근데 기기가 느린 날엔 그 지연으로도 부족해서 가끔 또 빨간 화면이 났습니다.
반대로 빠른 기기에선 괜히 멀쩡한 화면을 몇백 밀리초씩 붙잡아 두는 꼴이었고요.
얼마나 걸릴지는 기기가 정하지 제가 숫자로 정하는 게 아니었습니다.
시간을 걸어놓고 기다리는 건 답이 아니었습니다.준비됐는지를 화면이 직접 물어보게 한다
결국 순서나 시간을 믿는 대신, 화면이 매번 "지금 준비됐어?"를 스스로 묻도록 바꿨습니다.
@override Widget build(BuildContext context) { if (!_controller.value.isInitialized) { return const Center(child: CircularProgressIndicator()); } return CameraPreview(_controller); }핵심은 값이 도착하기 전의 상태를 화면이 정식으로 하나 갖는 것이었습니다.
저는 그동안 준비 안 된 상태를 "잠깐 스쳐가는 예외"쯤으로 여겼는데, 사실 그건 화면이 켜질 때마다 반드시 지나는 정상적인 한 장면이었습니다.
null을 피하려고 방어 코드를 덧대는 게 아니라, 아직 안 온 상태에 자리를 하나 내주는 것.
그렇게 바꾸고 나서는 그 빨간 화면이 다시 안 떴습니다.
덤으로, 로딩 표시가 그 짧은 순간을 채워주니 예전에 카메라가 열리는 동안 화면이 깜빡 비던 것도 같이 사라졌습니다.코드로는 길이 두 가지였습니다.
초기화 Future를 FutureBuilder로 감싸 상태별로 화면을 나누는 방법, 그리고 위처럼 컨트롤러의 value를 직접 확인하는 방법.
저는 화면 흐름이 단순해서 후자를 골랐지만, 둘 다 결국 '준비 전'과 '준비 후'라는 두 장면을 코드에 명시한다는 점은 같았습니다.
하나 더 잊지 말아야 했던 건 화면을 떠날 때 컨트롤러를 dispose로 닫아주는 것이었습니다.
안 그러면 카메라가 계속 열린 채로 남아서, 다음에 이 화면에 들어올 때 또 다른 타이밍 문제로 저를 괴롭혔거든요.아직 안 풀린 게 하나 있다
이 일을 겪고 나서, 이미지든 센서든 하드웨어에 걸린 값은 화면보다 늦게 온다는 걸 아예 기본값으로 놓게 됐습니다.
그런데 이 카메라 화면엔 아직 못 푼 게 하나 남아 있습니다.
유독 오래된 기기 하나에서는 로딩 표시가 뜨기 직전에 화면이 한 프레임 까맣게 깜빡입니다.isInitialized로 분명히 막았는데도 그 한 프레임이 왜 그 기기에서만 새는지, 저는 아직 이유를 못 찾았습니다.
다음에 그 기기가 다시 제 손에 들어오면, 거기서부터 로그를 심어볼 참입니다.원문 기준
원문 기준: https://api.flutter.dev/flutter/widgets/precacheImage.html
원문 본 날짜: 2026-07-01.
게시 전에 원문 표현이 달라졌는지 한 번 더 대조합니다.728x90반응형'AI Agent > flutter' 카테고리의 다른 글
Flutter 검증은 exit 0보다 산출물 확인이 먼저입니다 (0) 2026.07.09 iOS에서는 죽고 Android에서는 지나가는 Flutter 코드가 있습니다 (0) 2026.07.09 위젯 생성은 싸지만 작업은 싸지 않습니다 (0) 2026.07.08 작은 상태에는 작은 도구가 더 낫습니다 (0) 2026.07.08 보인다는 말보다 캡처 파일이 더 강합니다 (0) 2026.07.08