Tech & Programming/모바일(Android, Flutter)

[Flutter] 웹뷰 하이브리드 모드 관련 이슈 해결

소스코드 요리사 2021. 11. 2. 23:28

서문

이제 네이티브 앱을 플러터로 변경하고, 앱의 디자인 까지 변경한 디지털페이지 5.0 프로젝트가 막바지로 접어들었습니다.

11월 중에는 끝이 날 것 같은데, 끝이 나면 이 프로젝트에 대해 회고글을 시리즈로 한번 써볼까 합니다.

많은 분들이 플러터를 쓰기를 결정하는 데 참고가 되었으면 좋겠고, 프로젝트를 하는데에도 도움이 되었으면 합니다.

아무튼 빨리 바쁜 것이 끝났으면 좋겠네요.

배경

이번에는 안드로이드 플랫폼에서 웹뷰 하이브리드 관련 이슈가 났었던 것을 공유하려고 합니다.

저희 디지털페이지 5.0은 에디터 Core 는 웹으로 동작하기 때문에 웹뷰의 사용을 피할 수 없습니다.

웹뷰를 사용하다 보면  키보드 노출이 안된다 던지 한글을 사용할 수 없는 키보드 이슈를 보게 됩니다.

 

인터넷 Search 를 해보면 이 키보드 이슈는 안드로이드의 웹뷰를 Flutter 에 embed 해서 사용하는 Hybrid composition mode 를 사용하라고 가이드가 나와 있습니다. (https://pub.dev/packages/webview_flutter)

이 Hybrid composition mode 는 Android SDK 19 이상이 필요하고 가상 디스플레이 모드에는 Android SDK 20 이상이 필요합니다.

저희는 이 조건을 만족하기에 Hybrid composition mode 를 사용하였는데, 그런데 또 다른 문제를 발생했습니다.

 

문제의 현상

이 문제는 저희의 신규 UI 와 관련이 있었습니다.

아래와 같이 신규 UI 는 에디터에 스타일 및 객체를 삽입하기 위해서 Bottom Sheet 를 사용합니다.

이러한 Bottom Sheet 위에 Google MapView(https://pub.dev/packages/google_maps_flutter) 가 올라가면 Draw Rate 가 떨어지면서 앱이 죽는 현상이 발생했습니다.

원인

원인을 파악해보니 이 구글 맵뷰 플러그인은 Android 의 Goggle map SDK 를 이용하고 있었습니다. 

이 것은 플러터의 View 가 아닌 안드로이드의 뷰를 embed 해서 쓰는 Hybrid composition mode 처럼 동일하게 사용하고 있었습니다. 

그리고, Bottom Sheet 의 특성상 반투명하게 처리되기 때문에 아래의 웹뷰와 Google Map view 가 겹쳐질 때 Draw Rate 가 급격히 떨어지면서 앱이 죽었습니다.

 

테스트 해본 결과 Bottom Sheet 뿐만 아니라 Dialog, Route 를 빌드하면서 opaque 옵션을 줘서 반투명하게 만들면 동일하게 발생합니다. 그리고, InAppWebView(https://pub.dev/packages/flutter_inappwebview) 플러그인에서도 동일하게 발생합니다.

 

해결

결국, Google Map View 를 사용하는 Bottom Sheet 가 노출 하기전 Hybrid composition mode 를 끄는 방법으로 문제를 해결했습니다. 

상세히 정리하면 안드로이드 플랫폼만 다른 플랫폼에서 사용되는 기본(Common) State 를 상속 받아 아래 로직으로 build 되도록 변경했습니다.

현재 Web View 의 상태(Slelection, Scroll Position, 키보드 노출 유무, html) 저장 -> Hybrid composition mode disable -> rebuild -> onLoad -> WebView 의 상태 복원 -> Bottom Sheet 노출

Bottom Sheet 를 Close 할 때는 위와 동일한 순서로 Hybrid composition mode enable 하여 문제를 해결했습니다.

 

마무리 

사실, 이 문제 해결 방법은 Cost가 큰 것 같아 방법이 마음에 들지는 않습니다. 혹시 다른 대안을 알고 계신 분이 있다면 댓글 달아주세요.

그리고, 안드로이드 자체의 View 를 embed 한 위젯을 사용할 때 불투명한 Route 에서 겹쳐지면 충돌이 난다는 것을 기억하고 UI 를 구성하면 더 좋을 것 같습니다.