์ฌ์ฉ์ ์ง์ ์์ฑ ๊ฒฉ๋ฆฌ์์ ํ๋ซํผ ์ฑ๋ ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ค๊ณ ํ๋ฉด ์ฑ์ด ์ฌํ๊ฒ ์ถฉ๋ํฉ๋๋ค(iOS ๋ฐ Android ๋ชจ๋์์). ์ด๊ฒ์ด ์์๋๋์ง ์ฌ๋ถ๋ฅผ ์์ ๋ด๋ ค๊ณ ๋ ธ๋ ฅํ๊ณ ์์ต๋๋ค.
๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ ์ด๋๊ฐ์ ์ธ๊ธํ ๊ฐ์น๊ฐ ์์ต๋๋ค.
์ด์จ๋ ๋๋ ์ด๊ฒ์ด ์ ์ฌ์ ์ผ๋ก ๊ฐ๋ ฅํ ํ๊ณ๊ฐ ๋ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋ณด์กฐ ๊ฒฉ๋ฆฌ์์ ํ๋ซํผ ํ๋ฌ๊ทธ์ธ์ ํธ์ถํ ์ ์๋ ๋ฐฉ๋ฒ์ด ์์ต๋๊น?
๋ถ๋ฅ๋ฅผ ์ํ cc @mravn-google
์์ง ์ฝ๋๋ null์ ์ญ์ฐธ์กฐํ๊ณ ๋ณด์กฐ ๊ฒฉ๋ฆฌ์์ ํ๋ซํผ ๋ฉ์์ง๋ฅผ ๋ณด๋ด๋ ค๊ณ ํ ๋ ์ถฉ๋ํฉ๋๋ค. ๋๋ ์์ง ์ ํํ ์ด๋๋ฅผ ์ง์ ํ์ง ์์๋ค; ๋๋ ๋ฌ๋น๋ฅผ ์ป์์ง๋ง ๊ทธ๋ฌํ ๊ฒ์ ํด์ํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์์ผํฉ๋๋ค.
(์ํฌ๋ฅธ) ํด๊ฒฐ ๋ฐฉ๋ฒ์ผ๋ก ๋ ๋ฒ์งธ ๊ฒฉ๋ฆฌ๋ ๊ธฐ๋ณธ ๊ฒฉ๋ฆฌ์ ๋ฉ์์ง๋ฅผ ๋ณด๋ด๋๋ก ์์ฒญํ ์ ์์ต๋๋ค.
@sroddy 2์ฐจ ๊ฒฉ๋ฆฌ๋ก ๋ฌด์์ ํ๋ ค๋์ง ์ฌ์ญค๋ด๋ ๋ ๊น์?
๋ค์ํ ์ฌ์ฉ ์ฌ๋ก๊ฐ ์์ต๋๋ค. ์:
์ผ๋ฐ์ ์ผ๋ก ์ด๋ค ๊ณต๊ฐ ๋ฉ์๋๋ฅผ ์ ์ธํ๋ ์ข ์์ฑ์ ์ฌ์ฉํ์ฌ ๊ฒฐ๊ตญ์๋ ํ๋ซํผ๋ณ ์ฝ๋๋ฅผ ์ฌ์ฉํ์ฌ ์์ ์ ์ํํ ์ง ์ฌ๋ถ๋ฅผ ์ ์ ์๋ ๊ฒฝ์ฐ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค(์: flutterfire์ ๋ํด ์๊ฐํ๊ณ ์์ต๋๋ค). ๊ทธ๊ฒ๋ค์ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ก ์ฐ์ฌ์ง ๊ฒ ๋์ ์ ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ๋ณํ ์ ์๋ ๊ตฌํ ์ธ๋ถ ์ฌํญ์ด์ด์ผ ํฉ๋๋ค.
๋ฐ์ดํฐ๊ฐ ์ด๋ฏธ ๋ฉ์๋ ์ฑ๋์ ์ ๋ฌ๋๋ ๋ฐฉ์์ผ๋ก ์ธ์ฝ๋ฉ๋์ด ์๊ธฐ ๋๋ฌธ์ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ํ์ฌ๋ก์๋ ๊ด์ฐฎ๊ณ ๊ตฌํํ๊ธฐ๊ฐ ์๋์ ์ผ๋ก ์ด๋ ต์ง ์์ ๊ฒ ๊ฐ์ต๋๋ค. ์ด๋ฌํ ์ด์ ๋ก ๊ฒฉ๋ฆฌ ํฌํธ๋ฅผ ํตํด์๋ ์ฝ๊ฒ ์ ๋ฌ๋์ง๋ง ์ฑ๋ฅ์ ์ฐจ์ ์ฑ ์ด ๋ ๊ฒ์ ๋๋ค. .
๊ทธ๋ฌ๋ ๊ตฌํํ๋ ๋์ ์ฝ๊ฐ ๋งํ์ต๋๋ค. ๊ธฐ๋ณธ ๊ฒฉ๋ฆฌ์์ ๋ณด์กฐ ๋ฉ์๋์์ ์ ์ ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ์ฌ์ด ๋ฐฉ๋ฒ์ ์๋ฅผ ์ ๊ณตํ ์ ์์ต๋๊น?
๊ฐ์ฌ ํด์
@sroddy ๋ฐฐ๊ฒฝ ์ ๋ณด๋ฅผ ์ ๊ณตํด ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค.
๊ธฐ๋ณธ ๊ฒฉ๋ฆฌ์์ ์ ์ ๋ฉ์๋ ํธ์ถ ์ ๋ณด: ์ง์ ์ง์๋์ง ์์ผ๋ฉฐ ํฌํธ๋ฅผ ์ฌ์ฉํ์ฌ ๊ตฌํํด์ผ ํฉ๋๋ค. ์ด ํจํค์ง ๋ ํด๋น ๊ธฐ๋ฅ์ ์ ๊ณตํ ์ ์์ต๋๋ค(์: here . ๊ทธ๋๋ ์ง์ ์๋ํ์ง๋ ์์์ต๋๋ค.
๊ทธ๋ฌ๋ ์ฌ๊ธฐ์ ์ฐ๋ฆฌ๋ ํ๋ซํผ ์ฑ๋ ํต์ ์ด ํ๋ฌ๊ทธ์ธ ๋๋ ๊ธฐํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ตฌํ์ ์ผ๋ถ๋ก ์ํ๋ ๋๋ ์๋ํ๋ ๋ณด๋ค ์ผ๋ฐ์ ์ธ ์๋ฃจ์ ์ ์ฐพ์์ผ ํฉ๋๋ค.
์์ง ์ด์ ๋ํ ํํฌ๊ฐ ์์ง๋ง ๊ธฐ๋ณธ ๊ฒฉ๋ฆฌ๊ฐ ์๋ ๋ณด์กฐ ๊ฒฉ๋ฆฌ์์ ์ฌ์ฉํ ์๋ ค์ง ์ฑ๋ ์ด๋ฆ ์ธํธ ๊ฐ ์๋ค๊ณ ์ ์ ๊ฐ์ ํ ์ ์๋ค๋ฉด ์ผ๋ฐ์ ์ผ๋ก ๋ค์์ ์ํํ ์ ์์ด์ผ ํฉ๋๋ค. ํด๋น ์ฑ๋์ ๋ํด ํ๋ซํผ ๋ฉ์์ง ์ฒ๋ฆฌ๋ฅผ ์ฌ๊ตฌ์ฑํ๊ณ ๋ ๊ฒฉ๋ฆฌ ๊ฐ์ ํ์ํ ๋ฐ์ด๋๋ฆฌ ๋ฉ์์ง ๋ฐ ์๋ต ์ ๋ฌ์ ํฌ๋ช ํ๊ฒ ๊ตฌํํฉ๋๋ค. ํ๋ฌ๊ทธ์ธ์ ๊ทธ ์ฐจ์ด๋ฅผ ๊ฒฐ์ฝ ์์ง ๋ชปํ ๊ฒ์ ๋๋ค.
์๋ฃจ์ ์ ์๋์ ์ค์ผ์น๋์ด ์์ต๋๋ค.
๊ธฐ๋ณธ ๊ฒฉ๋ฆฌ์ ํฌํธ M1 ๋ฐ R1์ ์ค์ ํ๊ณ ๋ณด์กฐ ๊ฒฉ๋ฆฌ์ M2, R2๋ฅผ ์ค์ ํ๋ค๊ณ ๊ฐ์ ํฉ๋๋ค. M์ ๋ฉ์์ง, R์ ๋ต์ฅ์ ๋๋ค.
BinaryMessages.setMockMessageHandler
๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ซํผ์ ๋ํ ๋ฉ์์ง๋ฅผ M1(ํด๋น ์ฑ๋๊ณผ ํจ๊ป BinaryMessage.send๋ฅผ ์ฌ์ฉํ๋ ํ๋ฌ๊ทธ์ธ์ ํฌ๋ช
ํ๊ฒ ์ ๋ฌ)์ผ๋ก ์ ๋ฌํฉ๋๋ค. ์๋ต ์ฝ๋ฐฑ์ ์ ์ฅํ๊ณ ๋ฉ์์ง์ ๋ํ ์๋ต ์์ ์ ์ฌ๋ฐ๋ฅธ ์ฝ๋ฐฑ์ ํธ์ถํ๋ ํธ๋ค๋ฌ๋ก R2๋ฅผ ๊ตฌ์ฑํ์ญ์์ค. BinaryMessages.handlePlatformMessage
๋ก ์ ๋ฌํ๋ ํธ๋ค๋ฌ๋ก M2๋ฅผ ๊ตฌ์ฑํ์ญ์์ค. ํ์ ์ฝ๋ฐฑ์ ๊ตฌํํ์ฌ R1์ ํ์ ์ ์ ๋ฌํฉ๋๋ค.BinaryMessages.send
๋ก ์ ๋ฌํ๋ ์ฒ๋ฆฌ๊ธฐ๋ก M1์ ๊ตฌ์ฑํฉ๋๋ค. ํ๋ซํผ์์ R2๋ก ์๋ต์ ์ ๋ฌํ๋ ์๋ต ์ฝ๋ฐฑ์ ์ค์ ํฉ๋๋ค. ๋ํ ๊ฐ ์ฑ๋์ ๋ํด BinaryMessages.setMessageHandler
๋ฅผ ํธ์ถํ์ฌ M2๋ก ์ ๋ฌํ๋ ํ๋ซํผ์์ ๋ค์ด์ค๋ ๋ฉ์์ง ์ฒ๋ฆฌ๊ธฐ๋ฅผ ์ค์ ํฉ๋๋ค. ์๋ต ์ฝ๋ฐฑ์ ์ ์ฅํ๊ณ ๋ณด์กฐ ๊ฒฉ๋ฆฌ์์ ์๋ต์ ์์ ํ๋ฉด ์ฌ๋ฐ๋ฅธ ์ฝ๋ฐฑ์ ํธ์ถํ๋ ํธ๋ค๋ฌ๋ก R1์ ๊ตฌ์ฑํ์ญ์์ค.@Hixie ๋ค์ ์ด์ ํ๋ก ์ด๋ํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ํด๊ฒฐ ๋ฐฉ๋ฒ์ด ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ข์ ์๋ฃจ์ ์๋ ์ฝ๊ฐ์ API ์ค๊ณ ์์ ๊ณผ ๋ฐ๋ณต ์์ ์ด ํ์ํฉ๋๋ค.
๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค. ์ด ๋ฌธ์ ์ ๋ํ ์์์ด ์์ต๋๊น?
@mravn-google ์ด๊ฒ์ ๋ํ ์ ๋ฐ์ดํธ๊ฐ ์์ต๋๊น? ๋๋ ๊ฐ์ ๋ฌธ์ ๋ฅผ ๊ฒช์์ต๋๋ค (์๋ฅผ ๋ค์ด ํ๋ซํผ ์ธก์์ RSA 2048 ํค ์์ ์์ฑํด์ผ ํ๋ฉฐ ์ด๋ ์ด์ ์ฅ์น์์ ์๊ฐ์ด ๊ฑธ๋ฆฌ๊ฑฐ๋ ๋ฐ์ดํฐ๋ฅผ ์ํธํ/๋ณตํธํํฉ๋๋ค). Android ๋ฐ iOS ํ๋ซํผ ๋ชจ๋์ ๋ํด ๊ตฌํ๋์ด์ผ ํ๋ฏ๋ก ํ๋ซํผ ์ธก์์ ์์ ์ ๋ ๋ฐฐ๋ก ๋๋ฆฌ๋ ์ค๋ ๋ ๋๋ ์๋น์ค๋ฅผ ๋ง๋๋ ๊ฒ์ ํผํ๊ณ ์ถ์ต๋๋ค. Dart์์ ํ๋ซํผ๋ณ ์์ ์ ๋น๋๊ธฐ์์ผ๋ก ์ฝ๊ฒ ์คํํ ์ ์๋ ๋ฐฉ๋ฒ์ด ์์ต๋๊น? ๊ทํ์ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ๊ด์ฐฎ์ ๊ฒ ๊ฐ์ง๋ง Flutter ๋ฐ Dart๋ฅผ ์ฒ์ ์ ํ๊ธฐ ๋๋ฌธ์ ์ด๋ฅผ ๊ตฌํํ๋ ๋ฐ ๋ช ๊ฐ์ง ๋ฌธ์ ๊ฐ ์๋ ๊ฒ ๊ฐ์ต๋๋ค(Isolate ๋ฑ์ ๋ํ ๋ฉ์์ง๋ฅผ ์ ๋ฌํ๋ ์ฒ๋ฆฌ๊ธฐ๋ฅผ ๊ตฌ์ฑํ๋ ๋ฐฉ๋ฒ์ ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค). ์ฃ์กํฉ๋๋ค. ๊ทธ๊ฒ์ ๋ํด.
๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.
Android/iOS ์ธก์์ PDF๋ฅผ ์์ฑํด์ผ ํ๋๋ฐ ์๊ฐ์ด ์ข ๊ฑธ๋ฆฌ๊ณ ๊ฑฐ๊ธฐ์์ ํธ์ถ์ ์คํํ๋ฉด compute(...) ๋ฉ์๋๊ฐ ์ฑ์ ์ถฉ๋์ํต๋๋ค.
์ด ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋๋ฐ ์ด์ ๋งํ์ต๋๋ค.
์ฑ์ด ํฌ๊ทธ๋ผ์ด๋์ ์์ง ์๋๋ผ๋ ๋ฐฑ๊ทธ๋ผ์ด๋ ๊ฒฉ๋ฆฌ์์ ๊ณต์ ๊ธฐ๋ณธ ์ค์ ์์ accessToken์ ์ฝ๊ณ ์ถ์ต๋๋ค(๊ธฐ๋ณธ ๊ฒฉ๋ฆฌ๊ฐ ์คํ๋๊ณ ์์ง ์์ ์ ์์ผ๋ฉฐ ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค).
๊ทธ๋์ ๋๊ตฐ๊ฐ๊ฐ ๋ฐฑ๊ทธ๋ผ์ด๋ ๊ฒฉ๋ฆฌ์์ ์ง์ ๋ฐ์ดํฐ๋ฅผ ์ฝ๋ ์๋ฃจ์
์ ๋งํด ์ค ์ ์์ต๋๊น?
์ง๊ธ ์ ๋ง ๊ณค๋ํด์.
/cc @bkonyi ์ด๊ฒ์ ๋น์ ์ด ์์ ํ๊ณ ์๋ ๊ฒ๊ณผ ๊ด๋ จ์ด ์๋ ๊ฒ ๊ฐ์ต๋๋ค.
๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค. CPU ๋ฐ์ด๋์ ๋ํ ์ฐ๋ฆฌ์ ์ ํ ๊ธฐ๋ฐ. ์ฐ๋ฆฌ๋ ๊ฒฉ๋ฆฌ์์ ํ๋ซํผ ๋ฐฉ๋ฒ์ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์๋ ค์ฃผ์๊ฒ ์ต๋๊น?
@Thomson-Tsui ๋๋ ๋น์ทํ ๋ฌธ์ ๊ฐ ์์๊ณ @bkonyi ์ ๊ทธ์ FlutterGeofencing ์ํ์ ์์ ์ฆ๋ฅ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ด๊ฐ flutter_blue ๋ฐ ๊ธฐํ ํ๋ฌ๊ทธ์ธ๊ณผ ํจ๊ป ์ฌ์ฉํ๊ณ ์๋ ๊ฒฉ๋ฆฌ์์ ์๋ ํ ๋ฌด์ธ๊ฐ ๋ฅผ ์ป์ ์ ์์์ต๋๋ค. ํ ์คํธ๋์ง ์์์ง๋ง ์๋ํด๋ณด์ญ์์ค.
๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค. ์ค์ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
๋๊ตฌ๋ ์ง์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐ ํ์ต๋๊น?
https://pub.dartlang.org/packages/flutter_isolate ๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
๋ฐฑ๊ทธ๋ผ์ด๋์์ ๋ค์ํ ๊ฐ๊ฒฉ์ผ๋ก ์ค๋์ค๋ฅผ ์ฌ์ํด์ผ ํฉ๋๋ค. ๊ทธ๋ ๊ฒ ํ๋ ๊ฐ์ฅ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ ์ค๋์ค๋ฅผ ๊ด๋ฆฌํ๋ ๋ณ๋์ ๊ฒฉ๋ฆฌ๋ฅผ ๊ฐ๋ ๊ฒ์ด์ง๋ง ์ด ๊ธฐ๋ฅ์ด ์์ผ๋ฉด ํฌํธ์ ๊ด๋ จํ์ฌ ์ ๋ง ์ด์ํ ์์ ์ด ํ์ํฉ๋๋ค.
Isolate from dart๋ฅผ ์คํํ ๋ ๊ธฐ๋ณธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ฐ๊ฒฐ๋์ง ์๋๋ค๊ณ ๊ฐ์ ํฉ๋๋ค.
์๋ฅผ ๋ค์ด, ์๋ฐ์์ ํ๋ฌํฐ ์ฝ๋๋ฅผ ์คํํ ๋ ์ด ๋ฉ์๋๊ฐ ํธ์ถ๋ฉ๋๋ค:
ย ย private native void nativeRunBundleAndSnapshotFromLibrary (
ย ย ย ย ย ย long nativePlatformViewId,
ย ย ย ย ย ย <strong i="7">@NonNull</strong> String [] prioritizedBundlePaths,
ย ย ย ย ย ย <strong i="8">@Nullable</strong> String entrypointFunctionName,
ย ย ย ย ย ย <strong i="9">@Nullable</strong> String pathToEntrypointFunction,
ย ย ย ย ย ย <strong i="10">@NonNull</strong> AssetManager manager
ย ย );
๋ชจ๋ ๋ง๋ฒ์ด ์ผ์ด๋๋ ๊ณณ)
์ด๊ฒ์ FlutterNativeView๋ฅผ ์ฌ๋ฌ ๊ฐ ์์ฑํ๊ณ ๊ฐ ์คํ์์ ๋ค์๊ณผ ๊ฐ์ ์ฌ์ค์ ์ํด ํ์ธ๋ฉ๋๋ค.
ย public void runFromBundle (FlutterRunArguments args)
๊ทธ๋ฐ ๋ค์ ๋ช ๊ฐ์ง "dart isolates"๋ฅผ ์ป์ต๋๋ค.
์ฐ๋ฆฌ๋ ๋ํ ์ด ๋ฌธ์ ์ ์ง๋ฉดํด ์์ต๋๋ค. ์ฐ๋ฆฌ๋ ๋ชจ๋ ํ๋ซํผ ์ฑ๋์ ์์กดํ๋ ๋ฐฐ๊ฒฝ ๊ฒฉ๋ฆฌ(์: ์์น, ์์ ๋ฑ)์์ ๋ฐ์ดํฐ๋ฅผ ์์งํด์ผ ํฉ๋๋ค. @mravn-google -- ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ API ์ ๋ฐ์ดํธ์ ๋ํ ์์์ด ์์ต๋๊น?
๋๊ตฌ๋ ๋ฏธ๋์ด ์ฑ์์๋ ์ ๋ง ์ฌ๊ฐํ ๋ฌธ์ ์
๋๋ค.
ํ๋ซํผ ์ค๋ ๋๋ ์ฌ์ด ๋ฐฉ๋ฒ์ด ์๋๋๋ค.
๋๋ ๋ํ ๋น์ทํ ๋ฌธ์ ์ ์ง๋ฉดํ์ฌ ์ง๊ธ ๋งํ์ต๋๋ค.
+1(๋ด ํ๋ก์ ํธ๋ ๊ฒฉ๋ฆฌ๋ ํ๋ซํผ ์ฑ๋์ด ์ฌํ๊ฒ ํ์ํจ)
๋ฐฐ๊ฒฝ์์ ์ด๋ฏธ์ง๋ฅผ ๋ ๋๋งํด์ผ ํฉ๋๋ค. ๊ฐ ์ด๋ฏธ์ง๋ ๋ช ์ด๊ฐ ๊ฑธ๋ฆฌ๊ณ ๋ฉ์ธ ์ค๋ ๋์์ ์ํ๋๋ ๊ฒฝ์ฐ UI๋ฅผ ์ฐจ๋จํ๊ธฐ ๋๋ฌธ์ ๊ฒฉ๋ฆฌ์์ ์ํํด์ผ ํฉ๋๋ค. ๋๋ dart:ui.PictureRecorder ์ ์ฒซ ๋ฒ์งธ ๊ธฐ๋ณธ ํธ์ถ์ ๊ฐํ ์๊ณ ๊ฐ๊ฐ์ ๋ชจ๋ ๊ทธ๋ํฝ ํธ์ถ(๊ธฐ๋ณธ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋)๋ ์๋ํ์ง ์์ ๊ฒ์ด๋ผ๊ณ ๊ฐ์ ํฉ๋๋ค. ์บ๋ฒ์ค์์ ๋ง์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ์ฝ๋ฐฑ ํฌํธ๋ก ์์ ํ๋ ๊ฒ์ ๊ณ ํต์ค๋ฌ์ธ ๊ฒ์ ๋๋ค.
์๋ฃจ์ ์ ๋์ด ํ๊ฐํฉ๋๋ค.
+1 ์ด ๋ฌธ์ ๊ฐ ์์ต๋๋ค
@mravn-google์ด ์ค๋ฅดํ์ค์์ Google ์์ ์ ์ค๋จํ ๊ฒ ๊ฐ์ต๋๋ค. ์ด์ ๋ํด ์กฐ์ฌํ๊ณ ์๋ Google Flutter ํ์ ๋ค๋ฅธ ์ฌ๋์ด ์๋์ง ๊ถ๊ธํฉ๋๋ค. IMO, ์ด๊ฒ์ ํ๋ ฅ์ ์ด๊ณ ๊ฐ๋ ฅํ Flutter ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๊ธฐ ์ํด Flutter๋ฅผ ์ง์งํ๊ฒ ์ฌ์ฉํ๊ธฐ ์ํ ์ฃผ์ ์ผ ์คํ ํผ์ ๋๋ค....
@sethladd ๊ฐ ์ํ๋ฅผ ์ ๊ณตํ ์ ์์ต๋๊น?
+1
์ด์ ๋ํ ์ ๋ฐ์ดํธ๊ฐ ์์ต๋๊น?
+1
์ค์ค๋ก ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ์์ง๋ง ๊ธฐ๋ค๋ฆฌ๊ธฐ๋ง ํ๋ฉด ๋๋ ๋ฒ๊ทธ๋ฅผ ๋ง๋ ๋ ์ด ํ๋ฌํฐ ์์ง๋์ด๊ฐ ๋ ๋๊น์ง์ ๋ง์ง๋ง ํฌ๋ง์ ๋๋ค.
์๋ก์ด flutter/dart ์ฌ์ฉ์๋ฅผ ์ํ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ๋ํ ์์ธํ ์ค๋ช
์ด ํ์ํฉ๋๋ค. ๋๋ ์ดํ ์ ์ isolates๋ฅผ ์ฌ์ฉํ๊ธฐ ์์ํ๊ณ ์ง๋ ์ฃผ์ flutter/dart๋ฅผ ์ฌ์ฉํ๊ธฐ ์์ํ์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ช ๊ฐ์ง ์ฌ๊ฐํ๊ฒ ๋
ธ๋ ์ง์ฝ์ ์ธ ์์
์ ๋ฉ์ธ ์ค๋ ๋๋ฅผ ์ฌ์ฉํด์ผ ํ๋ ๊ฒ์ฒ๋ผ ๋ณด์
๋๋ค. ๋ฐ๋ผ์ ํ์ต ํ๋ฌํฐ๊ฐ ๋์ ์๋ฃจ์
์ด ๋ฉ๋๋ค. ์ฌ์ฉ ๊ฐ๋ฅํ ๋ฉํฐ์ค๋ ๋ฉ์ด ์์ผ๋ฉด Kotlin์ ๋ฐฐ์ฐ๊ณ ์ฑ์ ๋ ๋ฒ ๋น๋ํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ์ฌ๋ฌ๋ถ ๋ชจ๋๊ฐ ์ด๋ณด์๊ฐ ์ดํดํ ์ ์๋ ๊ฒ์ ํจ๊ป ์ป์ ์ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค. ์ง์ฅ์์ ์ฌ์ฉํ ์ ์๋๋ก ํ๋ฌํฐ ํ์ต์ ๊ณ ์ฉ์ฃผ์๊ฒ ์ ๋นํํ ์ ์๊ธฐ๋ฅผ ์ ๋ง ๋ฐ๋๋๋ค.
์ฌ๊ธฐ์ ์๋ค๋ฉด ์๋ง๋ StackOverflow์ ์ง๋ฌธ์ ๊ฒ์ํ์ต๋๋ค: https://stackoverflow.com/q/57466952/6047611
+1 ๊ณง ์์ ๋๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
+1 ๋ด ํ๋ก์ ํธ๋ ๊ฒฉ๋ฆฌ๋ ํ๋ซํผ ์ฑ๋์ด ํ์ํฉ๋๋ค.
์ด ๋์ผํ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ฌ @mravn-google์ด ๊ฒ์ํ ๊ฒ๊ณผ ์ ์ฌํ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ์ฌ ํจํค์ง( Isolate Handler )๋ฅผ ๋ง๋ค์์ต๋๋ค. ๊ทธ๋ฌ๋ ๊ฒฉ๋ฆฌ ์ฒ๋ฆฌ๊ธฐ๋ฅผ ์ฌ์ฉํ๋ฉด ๋ค๋ฅธ ๊ฒฉ๋ฆฌ์ ํจ๊ป ๊ธฐ๋ณธ ๊ฒฉ๋ฆฌ์ ์ฑ๋์ ๋ชจ๋ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๊ฒฉ๋ฆฌ ๋ด์์ ์ง์ MethodChannel
ํธ์ถ์ ์ง์ํ์ง๋ง ํ์ฌ EventChannel
์คํธ๋ฆผ์ ์ง์๋์ง ์์ต๋๋ค. ์ฌ๋๋ค์ด ํ์๋ก ํ๋ ๊ฒ์ผ๋ก ํ๋ช
๋๋ฉด ์ง์์ ์ถ๊ฐํ๋ ๋ฐฉ๋ฒ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
ํด๊ฒฐ ๋ฐฉ๋ฒ์ ํ ๊ฐ์ง ๋จ์ ์ ๊ฒฉ๋ฆฌ ์ฒ๋ฆฌ๊ธฐ์ ์ฑ๋ ์ด๋ฆ์ ์ ๊ณตํด์ผ ํ๋ค๋ ๊ฒ์ ๋๋ค. ๋ด ๋ค์ดํฐ๋ธ ์ฝ๋๋ฅผ ์ง์ ์์ฑํ๊ณ ์๊ธฐ ๋๋ฌธ์ ๋ด ํ๋ก์ ํธ์์๋ ๋ฌธ์ ๊ฐ ๋์ง ์์ง๋ง, ๊ทธ๋ ์ง ์์ผ๋ฉด ํ๋ฌ๊ทธ์ธ์ ์ฐพ๊ธฐ ์ํด ์ฌ์ฉ ์ค์ธ ํ๋ฌ๊ทธ์ธ์ ์์ค ์ฝ๋๋ฅผ ์ดํด๋ด์ผ ํฉ๋๋ค.
์์ ์ด๋ฏธ ๊ฒ์๋ ๋ ๋ค๋ฅธ ์ต์ ์ FlutterIsolate ์ ๋๋ค. ์ด ์ต์ ์ ๋ค๋ฅธ ์ ๊ทผ ๋ฐฉ์์ ์ฌ์ฉํ๋ฉฐ ์ดํด๋ณผ ๊ฐ์น๊ฐ ์์ต๋๋ค.
Flutter ๊ฐ๋ฐ์๊ฐ ๊ณง ์ด ๋ฌธ์ ์ ๋ํ ์์ ํ๊ณ ์ ์ ํ ์๋ฃจ์ ์ ์ ๊ณตํ ์ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
ํธ์งํ๋ค:
๊ฒฐ๊ตญ Flutter ์์ฌ Android ์๋ ๊ด๋ฆฌ์ ํ๋ฌ๊ทธ์ธ๊ณผ ์ ์ฌํ ์ ๊ทผ ๋ฐฉ์์ ์ฌ์ฉํ๋ ๋์ ๊ธฐ๋ณธ ์ธก์์ ๊ฒฉ๋ฆฌ๋ฅผ ์์ํ์ฌ ๋ฌธ์ ๋ฅผ ๋ ๊น๋ํ๊ฒ ํด๊ฒฐํ์ต๋๋ค.
๋ด๊ฐ ํด์ผ ํ๋ ์ ์ผํ ์ผ์ ๋ค์ดํฐ๋ธ ์ฝ๋๋ฅผ ํ๋ฌ๊ทธ์ธ์ผ๋ก ๋ณํํ์ฌ ๋ค์ดํฐ๋ธ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฑ๋กํ ์ ์๋๋ก ํ๋ ๊ฒ๋ฟ์ด์์ต๋๋ค. ์ด๋ ๋น๊ต์ ์ฌ์ด ๋ง์ด๊ทธ๋ ์ด์ ์ด์์ต๋๋ค. pub.dev์ ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ์ํํ๊ฒ ์๋ํด์ผ ํ๋ฏ๋ก ํจ์ฌ ๋ ๊ฐ๋จํฉ๋๋ค.
+1 ์ ๋ฐ์ดํธ๊ฐ ์์ต๋๊น?
+1
์ฌ๊ธฐ์ ๋ด๊ฐ ์ฃผ๋ชฉํ๋ ํฅ๋ฏธ๋ก์ด ์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
์ฌ๋ฌ ํ๋ฌ๊ทธ์ธ์ ๋ฉ์๋ ์ฑ๋ ํธ์ถ์ด Dart์์ ๋ฐฑ๊ทธ๋ผ์ด๋ ์ค๋ ๋๋ก ๋ฉ์์ง๋ฅผ ์ ๋ฌํ๋ค๋ ๊ฐ์ ํ์ ์์ฑ๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ด์ ๊ด๋ จํ์ฌ, ๊ทธ bg ์ง์คํ์ฑ ์์ ๋ฅผ ๋ฐ๋๊ณ ์ด์ ๋ฉ์ธ ์ค๋ ๋๋ก ๋์๊ฐ๋ ๋ฐฉ๋ฒ์ ๊ถ๊ธํดํ๋ ๋งค์ฐ ํผ๋์ค๋ฌ์ด ์ฌ๋๋ค์ด ์์ต๋๋ค...
ํด๋น ํ๋ฌ๊ทธ์ธ ์ฝ๋๋ ์งง์ ์์
์ ์ํํ๋ ๊ฒฝ์ฐ "๋ฒ๋ฒ
๊ฑฐ๋ฆผ"์ ์ผ์ผํค์ง ์์ง๋ง ๊ธฐ๋ณธ์ ์ผ๋ก Android์์๋ "UI ์ค๋ ๋"๋ผ๊ณ ํ๋ ํ๋ซํผ ์ค๋ ๋ ์์ ์คํ๋ฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์์
๋์ด ๋ง์ ๋ ์ ์ค์ฒ๊ฐ ์ค๋จ๋ ์ ์์ผ๋ฉฐ ๋ค๋ฅธ ๋ชจ๋ ๋ฉ์์ง ์ฑ๋๋ ์ฐจ๋จํ ์ ์์์ ์ดํดํฉ๋๋ค.
๊ทธ๋ฐ ๋ค์ ํ๋ฌ๊ทธ์ธ ์์ฑ์์ ์์ง๋์ด๋ง์ ์ข
์๋ฉ๋๋ค. ๋ค์ดํฐ๋ธ ์ฝ๋์ ๋ค๋ฅธ ์ค๋ ๋๋ก ๋ฌด๊ฑฐ์ด ์์
์ ์ด๋ํ ๊ฒฝ์ฐ์๋ง ๋ฉ์๋ ์ฑ๋์ ๊ธฐ๋ค๋ฆฌ๋ ์ฝ๋๋ฅผ ์คํํ๊ฒ ๋ฉ๋๋ค. ์ด๋ฌํ ๋ฉ์์ง ์ฑ๋ ์ ํ๋ซํผ ์ค๋ ๋์์ ์คํ๋์ด์ผ ํฉ๋๋ค.
๋๋ ์ข์ ์น๋ฉ์ด๊ฐ๋ฅด๋๊ฐ ์ฌ๊ธฐ์ ๊ด๋ จ๋ ๊ทผ๊ฑฐ๋ฅผ ์ดํดํ์ง๋ง ๋ค์๊ณผ ๊ฐ์ด ๋์ํฉ๋๋ค.
๊ฒฐ๊ณผ ์ํคํ
์ฒ๊ฐ ํ๋ฌ๊ทธ์ธ ์์ฑ์๋ฅผ ์ํ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ค์ํ ์ํฐ ํจํด์ ์ด์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ธ๋ป๋ณด๊ธฐ์๋ Firebase ml ํ๋ฌ๊ทธ์ธ์กฐ์ฐจ๋ ์ฒ๋ฆฌ๋ฅผ ์ํด ํ๋ซํผ ์ค๋ ๋๋ฅผ ์ฌ์ฉํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
๊ทธ๋์ ๋ฌด๊ฑฐ์ด ๋ฌผ๊ฑด์ ๋๋ ์ฌ๋๋ค์๊ฒ ์ด๋ค ์ข
๋ฅ์ ๊ฐ๋ ฅํ ๊ฒฝ๊ณ ๊ฐ ์ฃผ์ด์ก์ผ๋ฉด ํฉ๋๋ค. ๋ฉ์์ง ์ฑ๋ ํธ์ถ์ด ๋ฐํ๋๋ ๋ฐ ~20ms๋ณด๋ค ์ค๋ ๊ฑธ๋ฆฌ๋ ๊ฒฝ์ฐ ํ๋ฉด ์ค๋ฅ๋ฅผ ์์ฑํ๋ ๊ธฐ๋ณธ ์์ ์ฑ์ ๋ฌธ์ ์ผ ์ ์์ต๋๋ค. ์์งํ ๋งํด์, db ํธ์ถ &c๋ฅผ ๋ง๋๋ ์ฌ๋๋ค์ ์ค๋ํ๋ ๊ฒ์ด ๋ฌด์์ด๋ ๊ฐ์. ์ค๋ ๋๋ฅผ ์ด๋ฏธ ๋ฐ์ผ๋ฌ ๊ฐ๋๋ค.
์, ๊ณต์ง ์ ์ฌ์ ์๋ค, ๊ทธ๊ฑด ํ์คํ...
Java์ Swift๋ฅผ ์ฌ์ฉํ์ฌ ๋ค์ดํฐ๋ธ ํ๋ซํผ ์ค๋ ๋๋ก ๋ฌด๊ฑฐ์ด ์ํฌ๋ก๋๋ฅผ ๊ตฌํํ๊ฒ ๋์์ต๋๋ค. ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ฐพ์ง ๋ชปํ์ต๋๋ค.
@AndruByrne ์ด๊ฒ์ ์ฐธ์ผ๋ก ๋งค์ฐ ํฅ๋ฏธ๋ก์ด ์ ๋ณด์ด๋ฉฐ ์ง๊ธ ๋์ด์ผ ๋ณด๋ฉด ๋ช ๋ฐฑํด ๋ณด์ด๋ ๊ฒ์ฒ๋ผ ๋๋ ๊ทธ๊ฒ์ ์์ง ๋ชปํ์ต๋๋ค. ์ฌ์ฉ์๊ฐ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ๋ฌด๊ฑฐ์ด ์์ ์ ์ํํ๋ ๋ฐฉ๋ฒ์ผ๋ก ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉํ๋ ค๊ณ ํ์ฌ UI๊ฐ ์ ๊ธด ๋ด ํ๋ฌ๊ทธ์ธ๊ณผ ๊ด๋ จ๋ ๋ฌธ์ ๊ฐ ์ด๋ฏธ ํ๋ ์์ต๋๋ค.
๋๋ ๊ฒฝ๊ณ ๊ฐ ์์ด์ผ ํ๋ค๋ ๋ฐ ๋์ํ๊ณ ๋ด ํ๋ฌ๊ทธ์ธ์ ๊ฒฝ๊ณ ๋ฅผ ์ถ๊ฐํ ๊ฒ์ ๋๋ค.
+1์ด ํ์ํฉ๋๋ค
๋ถํํ๋ - Flutter๋ ๋งค์ฐ ๊ธฐ๋ณธ์ ์ด์ง๋ง ๋งค์ฐ ์ค์ํ ๊ฒ์ด ๋ถ์กฑํ๊ธฐ ๋๋ฌธ์ ํฉ๊ธ๊ธฐ๋ฅผ ๋ง์ดํ ์ค๋น๊ฐ ๋์ด ์์ง ์์ต๋๋ค. ๋ชจ๋ Flutter ์ฑ์ด ๊ฐ๋จํ async/await๋ฅผ ์ฌ์ฉํ ์ ์๋ ๊ฒ์ ์๋๋๋ค. ๋ฌด๊ฑฐ์ด ์์ ์ ์ํด์๋ ๊ฒฉ๋ฆฌ๊ฐ ํ์์ ์ด๋ฉฐ ๋ค๋ฅธ ๊ฒฉ๋ฆฌ์์ ํ๋ซํผ ์ฑ๋ ๋ฉ์๋ ํธ์ถ์ ํ์ฉํ ์ ์๋ ํ๋ฌ๊ทธ์ธ์ ๊ทธ๊ฒ๋ค์ ๋ฌด์๋ฏธํ๊ณ ์ค๋ณต๋๊ฒ ๋ง๋ญ๋๋ค. Xamarin์ 1์ผ ์ฐจ๋ถํฐ ์ด๋ฅผ ํ๋ ์์ํฌ์ ๊ตฌ์ถํ์ต๋๋ค. ์ด์ ํ์คํ ์ด๊ฒ์ด ์๋ฃจ์ ์ ๋ํด ํฌํ๋ฅผ ๋ฐ์์ผ ํฉ๋๋ค.
+1์ด ํ์ํฉ๋๋ค
+1
๋ค๋ฅธ ๊ฒฉ๋ฆฌ์์๋ ํ๋ซํผ ์ฑ๋ ๋ฉ์๋๋ฅผ ํธ์ถํด์ผ ํฉ๋๋ค!
+1
+1
+1
+1 ์ด๊ฒ์ ํ์ํ์ ๋๋ค
+1
ํธ์ถํด์ผ ํ๋ ๊ธฐ๋ณธ SDK๊ฐ ์์ต๋๋ค. BackgroundFlutterMethodChannel
์ ๊ฐ์ ๊ฒ์ด ์์ผ๋ฉด ์ข์ ๊ฒ์
๋๋ค.
+1
+1
_์ถฉ๋์ด ์ฌํ๊ฒ_ ์ค์ ๋ก ์ค๋ช ํ๋ ๋ด์ฉ์ ๋ํ ์ ๋ณด๊ฐ ์๋ ์ฌ๋์ด ์์ต๋๊น? ๊ธฐ๋ณธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๊ตฌํํ๋ ๊ฐ๋ ์ฆ๋ช ์ ์์ ์ค์ด๋ฉฐ ๋ฉ์๋ ์ฑ๋์ ํตํด ๋ฉ์์ง๋ฅผ ์ฃผ๊ณ ๋ฐ์ ๋ ๊ฐ์ ์๊ฐ ์ด๊ณผ(0x8badf00d) ๋ฐ ๊ธฐํ ์ด์ํ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
๋๋ ์ด๊ฒ์ด ๋ค๋ฅธ ์ค๋ ๋์์ ํธ์ถ๋ ์ผ๋ถ ๋ฉ์๋[๋ฐ ๊ฒฐ๊ณผ]๋ก ์ธํด ๋ฐ์ํ๋ค๊ณ ์๊ฐํ์ง๋ง ์ ํํ ๋ฌธ์ ๋ฅผ ์ ํํ ์ฐพ์๋ด๋ ๋ฐ ์ง์ ์ ์ด๋ฃจ์ง ๋ชปํ์ต๋๋ค.
+1
+1
+1
+1
+1์ด ํ์ํฉ๋๋ค
+1 ์ด๊ฒ๋ ํ์ํฉ๋๋ค!
์ด ๋ฌธ์ ๋ ์ ์ด๋ P2๋ก ์ฐ์ ์์๊ฐ ์ง์ ๋์ด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
๋ด๊ฐ ์๊ฐํ ์ ์๋ ํ๋ซํผ ์ฑ๋์ ์ฉ๋๋
๊ทธ๋ฆฌ๊ณ ์ด๊ฒ์ ์ฃผ์ ์ฐจ๋จ๊ธฐ์ ๋๋ค.
flutter_downloader ํ๋ฌ๊ทธ์ธ์ ๋ฐฑ๊ทธ๋ผ์ด๋ ๊ฒฉ๋ฆฌ ์ฝ๋๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค. ๋๋ ๊ทธ๊ฒ์ ๋ณผ ๊ฐ์น๊ฐ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
๋๋ ์ด๊ฒ์ด ๋ค์ ๋ฒ์ ์์ ํด๊ฒฐ๋๊ธฐ๋ฅผ ๋ฐ๋์ง๋ง ๋ฒ๊ทธ๋ ์ฌ์ ํ 1.12 ๋ฒ์ ์ ๋จ์ ์์ต๋๋ค!
์ฐ๋ฆฌ์ ํด๋ผ์ด์ธํธ ์ธก ์ฝ๋๋ ์ฑ๋์ ๋ฐ๋ํธ์ ๋ง์ด ์์ผ๋ฉฐ kotlin์ผ๋ก ์์ฑ๋์์ผ๋ฉฐ ์ฑ์ ๊ฐ ๋จ์ผ http ์ฐ๊ฒฐ์ ๋ํด ๊ฑฐ์ ๋ฉ์ท์ต๋๋ค.
ใ ใ ใ ใ ใ ใ ใ ใ ใ !!!!!!!!!!!!!!!!!?!?!?
์ด ํ๋ฌ๊ทธ์ธ์ flutter_isolate ์ ๋์์ด ๋ ์ ์์ต๋๋ค.
+1 ์ฐ๋ฆฌ๋ ์ด๊ฒ์ด ํ์ํฉ๋๋ค ... ์ด์
+1
๋์๊ฒ ๊ฐ์ฅ ํฐ ๋ฌธ์ ๋ Dart์ ๊ธฐ๋ณธ ํ๋ซํผ ๊ฐ์ ํต์ ์ด ๋ฉ์ธ ์ค๋ ๋์์ ๋ฐ์ํ๋ค๋ ์ฌ์ค์ ๋๋ค. UI๊ฐ ์ง์ฐ๋๊ฑฐ๋ ํ์ด์ง ๋ฐ์ดํฐ์ ๋ฒ๊ฑฐ๋ก์ด ์ฝ๋๋ฅผ ์์ฑํ์ง ์๊ณ ๋ ์๋นํ ์์ ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด๋ ๊ฒ์ด ๋ถ๊ฐ๋ฅํฉ๋๋ค.
+1์ด ํ์ํฉ๋๋ค
ํ์ด์ง ๋ฐ์ดํฐ์ ์ฑ๊ฐ์ ์ฝ๋๋ฅผ ์์ฑํฉ๋๋ค.
@lukaszciastko ํ์ด์ง ๋ฐ์ดํฐ์ ์ฝ๋๋ฅผ ์์ฑํ๋ค๋ ๊ฒ์ ๋ฌด์์ ์๋ฏธํฉ๋๊น? ์๋นํ ์์ ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ผ ๋ ์ง์ฐ๋๋ UI๋ฅผ ํด๊ฒฐํ ์ ์๋ ๋ฐฉ๋ฒ์ด ์์ต๋๊น?
@YaredTaddese
ISOLATE๊ฐ ์ํํ๋ ์์ ์ ๋ณต์ก์ฑ๊ณผ UI์ ISOLATE ๊ฐ์ ์ํธ ํต์ ์ ๋ฐ๋ผ - ISOLATE๋ฅผ ํธ์ถํ๊ธฐ ์ ์ ISOLATE๊ฐ ์์ ์ ์ํํ๋ ๋ฐ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ๊ตฌ์กฐํํ์ฌ UI ์ฝ๋์์ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์ต๋๋ค. ํ์ฌ Flutter ์ฑ์ ํ๋ถํ PDF ์์ฑ ๊ธฐ๋ฅ์ด ์์ต๋๋ค. ์ฌ์ฉ์๋ ์์ฑํ ์ฌ๋ฌ PDF๋ฅผ ์ ํํ ์ ์์ต๋๋ค.
๊ฐ๊ฐ์ 1-10,000ํ์ด์ง๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. ๋ด UI๋ ๋ฐ์ํฉ๋๋ค. ๊ฐ ์์ ์ด ์๋ฃ๋๋ฉด ๋ณด๊ณ ์๋ฅผ ํ์ํ๋ TAB๊ฐ ๊ตฌ์ฑ๋ฉ๋๋ค. - ์ฌ์ฉ์๋ TOAST๋ฅผ ํตํด ์์ ์ด ์๋ฃ๋๊ณ UI๊ฐ ์ค๋จ๋์ง ์์ ๋ ์๋ฆผ์ ๋ฐ์ต๋๋ค. - ์ฌ์ฉ์๋ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ์๋น์ค๊ฐ ์๋ค๋ ๊ฒ์ ์ธ์ํ์ง ๋ชปํฉ๋๋ค. ํ๋ถํ PDF ์์ฑ.
์ฐธ๊ณ ๋ก ๋ด PDF ์์ฑ์ ISOLATE์ ๋๋ค. ISOLATE์์๋ CLOUD FIRESTORE์์ ์ด๋ฏธ์ง๋ฅผ ๋ค์ด๋ก๋ํ๊ณ PDF์ ํฌํจํด์ผ ํฉ๋๋ค. ์ด ๋ชจ๋ ๊ฒ์ด ์ํํ๊ฒ ์ด๋ฃจ์ด์ง๋๋ค.
@MsXam ํ์ง๋ง ๋ค๋ฅธ ๊ฒฉ๋ฆฌ์์ ํ๋ซํผ๋ณ ๊ธฐ๋ฅ์ ํธ์ถํ ์ ์์ต๋๋ค... ์ด๋ก ์ธํด ์ฃผ ๊ฒฉ๋ฆฌ์์ ํ๋ซํผ๋ณ ๊ธฐ๋ฅ์ ํธ์ถํ๊ฒ ๋ฉ๋๋ค... ์ด๋ก ์ธํด UI๊ฐ ์ง์ฐ๋ฉ๋๋ค.
๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค. ๋งค์ฐ ์ค์ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
@YaredTaddese
ISOLATE๊ฐ ์ํํ๋ ์์ ์ ๋ณต์ก์ฑ๊ณผ UI์ ISOLATE ๊ฐ์ ์ํธ ํต์ ์ ๋ฐ๋ผ - ISOLATE๋ฅผ ํธ์ถํ๊ธฐ ์ ์ ISOLATE๊ฐ ์์ ์ ์ํํ๋ ๋ฐ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ๊ตฌ์กฐํํ์ฌ UI ์ฝ๋์์ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์ต๋๋ค. ํ์ฌ Flutter ์ฑ์ ํ๋ถํ PDF ์์ฑ ๊ธฐ๋ฅ์ด ์์ต๋๋ค. ์ฌ์ฉ์๋ ์์ฑํ ์ฌ๋ฌ PDF๋ฅผ ์ ํํ ์ ์์ต๋๋ค.
๊ฐ๊ฐ์ 1-10,000ํ์ด์ง๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. ๋ด UI๋ ๋ฐ์ํฉ๋๋ค. ๊ฐ ์์ ์ด ์๋ฃ๋๋ฉด ๋ณด๊ณ ์๋ฅผ ํ์ํ๋ TAB๊ฐ ๊ตฌ์ฑ๋ฉ๋๋ค. - ์ฌ์ฉ์๋ TOAST๋ฅผ ํตํด ์์ ์ด ์๋ฃ๋๊ณ UI๊ฐ ์ค๋จ๋์ง ์์ ๋ ์๋ฆผ์ ๋ฐ์ต๋๋ค. - ์ฌ์ฉ์๋ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ์๋น์ค๊ฐ ์๋ค๋ ๊ฒ์ ์ธ์ํ์ง ๋ชปํฉ๋๋ค. ํ๋ถํ PDF ์์ฑ.
์ฐธ๊ณ ๋ก ๋ด PDF ์์ฑ์ ISOLATE์ ๋๋ค. ISOLATE์์๋ CLOUD FIRESTORE์์ ์ด๋ฏธ์ง๋ฅผ ๋ค์ด๋ก๋ํ๊ณ PDF์ ํฌํจํด์ผ ํฉ๋๋ค. ์ด ๋ชจ๋ ๊ฒ์ด ์ํํ๊ฒ ์ด๋ฃจ์ด์ง๋๋ค.
ํ๋ซํผ๋ณ ์ฝ๋๋ฅผ ํธ์ถํ๊ณ ์์ต๋๊น?
๊ฒฉ๋ฆฌ์์ ํ๋ซํผ ์ฑ๋์ ํธ์ถํ๊ธฐ ์ํ ํด๊ฒฐ ๋ฐฉ๋ฒ์ด ์๋ ์ฌ๋์ด ์์ต๋๊น? UI ์ค๋ ๋์์ ๊ทธ๋ ๊ฒ ํ๋ ค๋ ์์ด๋์ด๋ฅผ ๋ฌดํจํํฉ๋๋ค.
๋๋ ๊ฐ์ ๊ฒ์ ๋ถ์ด์๋ค.
kotlin ์ฝ๋์ getStream.io API๋ฅผ ์ฌ์ฉํ์ฌ methodchannel์ ํธ์ถํ๊ณ ์์ง๋ง ์๋๊ฐ ๋๋ฌด ๋๋ฆฌ๊ณ Flutter UI๊ฐ ์ ์ง๋์ด ์ฌ๊ธฐ์ ์ปดํจํ ์ ์ถ๊ฐํ๊ณ ์ถ์์ง๋ง ๋์ผํ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํ๋์?
์ ๋ ๋ฐฉ๊ธ ์ด๊ฑธ๋ก ๋์ด์์ต๋๋ค. ์ ๋ ์ ์ฑ์ ํ๋กํ ํ์ ์ ๋ง๋ค๊ณ ์๋๋ฐ, ์ค์ ๋ก ์ด ๋ฌธ์ ๋ ์ ์๊ฒ ๊ฐ์ฅ ํฐ ์ถฉ๊ฒฉ์ ์ค ์ ์๊ณ Flutter๊ฐ ์๋ ๋ค๋ฅธ ์๋ฃจ์ ์ ์ดํด๋ณด๊ฒ ํ์ฌ ์ ๋ฅผ ์ฌํ๊ฒ ๋ง๋ค ๊ฒ์ ๋๋ค.
์ด ๋ฌธ์ ์ ๋ํ ์๋ต์ ์์ด ์ ์ ์๋ฏ์ด ์ด๊ฒ์ ์ฃผ์ ๋ฌธ์ ์ด๋ฉฐ Flutter ์ฑ์ ์ปจํ ์คํธ์์ ๊ฒฉ๋ฆฌ์ ์ฃผ์ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ๊ฑฐ์ ๋ฌดํจํํฉ๋๋ค.
์ ๋ ๋ฐฉ๊ธ ์ด๊ฑธ๋ก ๋์ด์์ต๋๋ค. ์ ๋ ์ ์ฑ์ ํ๋กํ ํ์ ์ ๋ง๋ค๊ณ ์๋๋ฐ, ์ค์ ๋ก ์ด ๋ฌธ์ ๋ ์ ์๊ฒ ๊ฐ์ฅ ํฐ ์ถฉ๊ฒฉ์ ์ค ์ ์๊ณ Flutter๊ฐ ์๋ ๋ค๋ฅธ ์๋ฃจ์ ์ ์ดํด๋ณด๊ฒ ํ์ฌ ์ ๋ฅผ ์ฌํ๊ฒ ๋ง๋ค ๊ฒ์ ๋๋ค.
์ด ๋ฌธ์ ์ ๋ํ ์๋ต์ ์์ด ์ ์ ์๋ฏ์ด ์ด๊ฒ์ ์ฃผ์ ๋ฌธ์ ์ด๋ฉฐ Flutter ์ฑ์ ์ปจํ ์คํธ์์ ๊ฒฉ๋ฆฌ์ ์ฃผ์ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ๊ฑฐ์ ๋ฌดํจํํฉ๋๋ค.
์, ์ด๊ฒ์ ํฐ ๋ฌธ์ ์ ๋๋ค. ์ต๋ํ ๋นจ๋ฆฌ ์์ ํด์ผ ํฉ๋๋ค.
๋๋ 10์ผ ๋์ ํ๋ฌํฐ๋ฅผ ๋ฐฐ์ ๊ณ ์ง๊ธ๊น์ง ๊ทธ๊ฒ์ ์ฌ๋ํ์ง๋ง ์ ์ ์คํํ ํ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๊ธฐ ์์ํ๊ณ ๋จ์ ์ ๋ณด๊ธฐ ์์ํฉ๋๋ค. ์ด ๋ฌธ์ ๋ 2018๋ 1์ 5์ผ๋ถํฐ ์ด๋ ธ์ต๋๋ค.
์ด ๋ฒ๊ทธ๋ฅผ ์์ ํ์ญ์์ค.
๊ณง ์ง์ํ๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
@jpsarda , @klaszlo8207 ์จ ์ฐธ์ง ๋ง์ธ์. ๊ทธ๋ฆฌ๊ณ ์, ์ค๋๊น์ง ๋ฌธ์ ์ ๋ํ ํด๊ฒฐ์ฑ ์ด ์์์ต๋๋ค: https://pub.dev/packages/isolate_handler. ํ๋ก๊ทธ๋๋จธ๋ Flutter์ ์ต๊ทผ ๋ณ๊ฒฝ(๋ช ์ผ ์ )์ผ๋ก ์ธํด ๋ ์ด์ ํด๋น ๊ฒฝ๋ก๋ฅผ ๋ฐ๋ผ๊ฐ ์ ์์๊ธฐ ๋๋ฌธ์ ์ค๋ ํ๋ฌ๊ทธ๋ฅผ ๋ฝ์์ผ ํ์ต๋๋ค.
๊ทธ๋ฌ๋ ์ด๊ฒ์ด ์ค์ ๋ก ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ์๋ฏธํ์ง๋ ์๋๋ค๋ ๊ฒ์ ์์์ผ ํฉ๋๋ค. ๋ชจ๋ฐ์ผ ์ฑ์์๋ ๊ทธ๋ ๊ฒ ๋ณด์ผ ์ ์๊ณ ๋ชจ์์ด ์ค์ํ์ง๋ง ํ๋ซํผ ์ฝ๋๋ ์ด์จ๋ ๋ฉ์ธ ์ค๋ ๋์์ ์คํ๋๋ฏ๋ก ๊ฒฉ๋ฆฌ์์ ๋ฉ์ธ ์ค๋ ๋๋ก ๊ธด ์์ ์ ๋ค์ ์์ํด๋ ์ค์ ๋ก ์๋ฌด ๊ฒ๋ ๋ฌ์ฑํ์ง ๋ชปํ์ต๋๋ค.
๋น๋๊ธฐ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ๋๋ง๋ค ๊ธฐ๋ณธ์ ์ผ๋ก ๋ค์ค ์ค๋ ๋ฉ์ ์ฒ๋ฆฌํ๋ ๋คํธ๊ฐ ์์ผ๋ฉด ์ข์ ๊ฒ์ ๋๋ค.
@spiderion Async๋ ๋ค๋ฅธ ๋ง์ ํ๋ซํผ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ฉํฐ์ค๋ ๋ฉ์ ์๋ํ์ง ์์์ต๋๋ค. ์ ๋ฅผ ์คํดํ์ง ๋ง์ธ์. ํ๋ซํผ ์ฑ๋ ์ ํ์ด ํฐ ๋ฌธ์ ๊ฐ ์๋๋ผ๋ ๋ง์ ํ์ง ์๊ฒ ์ต๋๋ค. ์๋ํ๋ฉด (๋ด ์ฑ์ ์ด์ ๊น์ง ์ธ๊ธํ ํ๋ฌ๊ทธ์ธ๊ณผ ํจ๊ป ์๋ํ๊ณ ์์๊ณ ์ด์ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ฐพ์์ผ ํจ) async/ await๋ ์ฒ์๋ถํฐ ๋ฉํฐ์ค๋ ๋ฉ์ ๊ดํ ๊ฒ์ด ์๋์์ต๋๋ค.
@zoechi ์ด ๋ฌธ์ ์ ๋ํ ์
๋ฐ์ดํธ๊ฐ ์๊ฑฐ๋ ์์ ํ ๊ณํ์ด ์๋์ง ์๊ณ ์ถ์ต๋๋ค.
๊ฐ์ฌํฉ๋๋ค.
@spiderion ๊ทธ๋ค์ ๊ทธ๊ฒ์ ์ค์ ๋ก ๊ณ ์น ์ ์์ผ๋ฉฐ ๊ฒฉ๋ฆฌ๊ฐ ์๋ํ๋ ๋ฐฉ์์ ๋ฐ๋ฆ ๋๋ค. ๋ค์ UI ์์ง์ด ์์ผ๋ฏ๋ก ํ๋ซํผ ์ฑ๋ ํต์ ์ด ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋์์ด ๋๋ ๋ ๊ฐ์ง ํ๋ฌ๊ทธ์ธ์ด ์์ต๋๋ค.
https://pub.dev/packages/flutter_isolate ๋ ์์ฒด UI ์ง์์ ์์ฑํ๊ธฐ ๋๋ฌธ์ ํ๋ฌ๊ทธ์ธ๊ณผ ํต์ ํ ์ ์๋ ๋์ฒด ๊ฒฉ๋ฆฌ๋ฅผ ์ ๊ณตํฉ๋๋ค(๊ธฐ์ ์ ์ผ๋ก๋ง ๋ณด๊ฑฐ๋ ์ฒ๋ฆฌํด์ผ ํ๋ ๊ฒ์ ์์).
https://pub.dev/packages/isolate_handler ๋ ์ต๊ทผ Flutter ๋ณ๊ฒฝ์ผ๋ก ์ธํด ์ด์ ๋ฐฉ์์ด ๋ถ๊ฐ๋ฅํ๊ฒ ๋์๊ธฐ ๋๋ฌธ์ ์์ ํจํค์ง์ ์์กดํ๋๋ก ์์ ํ์ต๋๋ค. flutter_isolate
์์ฒด๊ฐ ์๋ ์ด ํจํค์ง๋ฅผ ์ฌ์ฉํ ๋์ ์ด์ ์ ์ฒ๋ฆฌ ๊ธฐ๋ฅ์ด ์ถ๊ฐ๋๊ณ ์ฌ๋ฌ ๊ฒฉ๋ฆฌ๋ฅผ ์์ํ๊ณ ์ถ์ ํ ์ ์์ผ๋ฉฐ ๊ฒฉ๋ฆฌ์ ๊ธฐ๋ณธ ํต์ ์ ์ค์ ํ ํ์๊ฐ ์๋ค๋ ๊ฒ์
๋๋ค. ์ค๋ ๋(์๋ ์คํก Isolate
๋ฐ FlutterIsolate
๋ชจ๋ ์๋์ผ๋ก ์ํํด์ผ ํ๋ ์์
)๋ ์ถ์ํ๋๊ณ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์
๋๋ค.
๋๋ ๋ ๋ฒ์งธ๋ฅผ ์๋ฒฝํ ์ฑ๊ณต์ผ๋ก ์ฌ์ฉํฉ๋๋ค. ์ฌ์ค, ๋๋ ๊ฝค ์ค๋ซ๋์ ๊ทธ๊ฒ์ ์ฌ์ฉํด ์์ผ๋ฉฐ Flutter์ ์ฃผ์ ๋ณ๊ฒฝ ์ฌํญ์ด ์์ ๋ ๋ด ์ฑ๋ ๋ง๊ฐ์ก๋ค๋ ์ด์ ๋ก ํ๋ก๊ทธ๋๋จธ๊ฐ ์๋ก์ด ์๋ฃจ์ ์ผ๋ก ๋์ด๊ฐ๋๋ก ๋์์ต๋๋ค. :-)
๋ฐ๋ผ์ ์ฝ์ด์์ ์๋ฃจ์ ์ ๊ธฐ๋ํ๋ ๊ฒ์ด ํฉ๋ฆฌ์ ์ด์ง ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ํนํ ๋๋ถ๋ถ์ ์ฌ์ฉ ์ฌ๋ก๋ ํ๋ซํผ ์ฑ๋ ํต์ ์ ์๊ตฌํ์ง ์์ผ๋ฏ๋ก ์ง์ UI ์์ง์ ๋ชจ๋ ๊ฒฉ๋ฆฌ์ ์ถ๊ฐํ๊ณ ์ถ์ ๊ฒ์ด ์๋๋๋ค. ์ถ๊ฐ ๊ธฐ๋ฅ์ด ํ์ํ ๋ ๊ธฐ์กด ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค.
์๋ ํ์ธ์ @deakjahn ๋น ๋ฅธ ๋ต๋ณ ๊ฐ์ฌํฉ๋๋ค.
๊ทํ๊ฐ ์ ๊ณตํ ์๋ฃจ์ ์ ๋งค์ฐ ์ ์ฉํด ๋ณด์ ๋๋ค. ๊ทธ๋ฌ๋ ๊ทธ๊ฒ์ด ๋ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋์ง ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ํ์ฌ ์ฑ์์ ์ฌ์ฉ์๊ฐ Instagram๊ณผ ์ ์ฌํ ์ด์ผ๊ธฐ๋ฅผ ๋ง๋๋ ์ํฉ์ด ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ ์ฑ์ ์ ๋ก๋ํ๋ ๋ฐ ์๊ฐ์ด ๋งค์ฐ ์ค๋ ๊ฑธ๋ฆด ์ ์๋ ๋์์ ๋ฐ ํ์ผ ๋ชฉ๋ก(์ฐ๊ฒฐ์ด ๋๋ฆฐ ๊ฒฝ์ฐ ์ฝ 15๋ถ)์ Firebase ์ ์ฅ์์ ์ ๋ก๋ํด์ผ ํ๋ฉฐ, ํ์ผ์ด ์ ๋ก๋๋ ํ ์ฑ์์ ์์ฑํด์ผ ํฉ๋๋ค. Firebase ํด๋ผ์ฐ๋, Firestore์ ์๋ ๋ฌธ์์ ๋๋ค. ๋ด๊ฐ ๋ง๋ ๋ฌธ์ ๋ ํ์ผ์ด ์ ๋ก๋๋๋ ๋์ ์ฌ์ฉ์๊ฐ ์ฑ์ ์ข ๋ฃํ๋ฉด ์ ์ฒด ์์ ์ด ์์ ํ ์คํ๋์ง ์๋๋ค๋ ๊ฒ์ ๋๋ค.
๊ทธ๊ฒ์ ์ค์ ๋ก ๊ฒฉ๋ฆฌ์ ์ฑ ์์ด ์๋๋ผ ์ง์ํ ๋๋ก ์ํํ ๋ฟ์ ๋๋ค. ๋ด๊ฐ ์ง์ ์ฌ์ฉํ ์ ์ ์์ง๋ง Firebase๋ ๋ด๊ฐ ๋ณผ ์ ์๋ ํ ์ค์ง๋ ์ธ๋ก๋๋ฅผ ์ฌ๊ฐํ ์ ์์ต๋๋ค.
getBatteryLevel ์์ ๋ฅผ ์คํํ๋ ค๊ณ ํฉ๋๋ค.
https://flutter.dev/docs/development/platform-integration/platform-channels?tab=android-channel-java-tab
Android ๊ธฐ๊ธฐ์์ ์คํํ๋ ค๊ณ ํ ๋๋ง๋ค ์ถฉ๋ํฉ๋๋ค. ๋๊ตฐ๊ฐ ๋์์ฃผ์๊ฒ ์ต๋๊น? ๋ก๊ทธ๊ฐ ์๊ณ ๋ฌดํ ๋ฃจํ์์ ๊ณ์ ์คํ๋๊ณ ์ ํํ ๋์ผํ ์ฝ๋๋ฅผ ์ฌ์ฉํ๊ณ ์๊ธฐ ๋๋ฌธ์ ์ค๋ฅ๋ฅผ ํ์ธํ๋ ๋ฐฉ๋ฒ์กฐ์ฐจ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค.
์ด ๋ฌธ์ ์ P5 ๋ ์ด๋ธ ์ง์ ??? ๐ฅต
์ด์ ๋๊ธ์ ํ์ธํด์ฃผ์ธ์. ๋๋ถ๋ถ์ ๊ฒฉ๋ฆฌ์๋ ํ์ํ์ง ์์ ๋ฉ์ปค๋์ฆ์ด ํ์ํ๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ด ํ๋ ์์ํฌ์์ ๋ณ๊ฒฝ๋ ๊ฐ๋ฅ์ฑ์ ๋งค์ฐ ๋ฎ ์ต๋๋ค. ๋ฐ๋ผ์ ์ค๋ฒํค๋๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ ์๋ฏธ๊ฐ ์์ต๋๋ค. ํ์ํ ๊ฒฝ์ฐ ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ํจํค์ง๊ฐ ์์ต๋๋ค.
์ฌ์ฉ์๋ ๋ฉ์ปค๋์ฆ์ ์ ๊ฒฝ ์ฐ์ง ์์ต๋๋ค. ์ผ๋ง๋ ํ๋ ์ง ์๋์ง. ๊ทธ๋ค์ ๋จ์ง ๊ฒฐ๊ณผ๊ฐ ํ์ํฉ๋๋ค. ์ด๊ฒ์ ๋ถ๊ฐ๋ฅํ ์ ์์ต๋๋ค. ํ์ง๋ง ์ฌ์ฉ์๊ฐ ํ์๋ก ํ๋ฉด Flutter์์ ์ ๊ณตํด์ผ ํฉ๋๋ค...
๊ตฌํ์ ์ ํ์ด ์์ผ๋ฉฐ ์ด ๊ธฐ๋ฅ์ ๊ธฐ์กด ๊ฒฉ๋ฆฌ์ ์ถ๊ฐํ๊ฑฐ๋ ์ด ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ฌ ์ API๋ฅผ ๋ง๋๋ ๋ฐ ๋ง์ ์๊ฐ์ด ๊ฑธ๋ฆด ์ ์์์ ์ดํดํฉ๋๋ค. ๋๋ ์ด๊ฒ์ด P5๋ณด๋ค ์ฐ์ ์์๊ฐ ๋์์ผํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
๋ํ ๊ทํ์ ์๊ฒฌ์ ๋ชจ๋ ์ฝ๊ณ ๊ทํ๊ฐ ๋ง๋ ํจํค์ง๋ฅผ ํ๋ณดํ๋ ๊ฒ์ฒ๋ผ ๋๋๋๋ค.
์๋์, ๋ด๊ฐ ๋ง๋ ๊ฒ์ ์๋์ง๋ง ๋ช ์ฃผ ์ ์ ์์ ๊ถ์ ์๋ฝํ์ต๋๋ค. ๋๋ ๊ทธ๊ฒ์ด ์ด ์ค๋ ๋์์ ๋น๋ฐ๋ก ์ ์ง๋์๋ค๊ณ ์๊ฐํ์ง ์์ต๋๋ค. ๊ทธ ์ธ์๋ ์ํ๋ ๊ฒ์ ์ ๊ณตํ ์ ์๋ ๋ ๊ฐ์ ํจํค์ง(๋จ์ผ ๊ฒ์๋ฌผ์์ ์ค์ ๋ก ํ ๋ฒ๋ง)๋ฅผ ์ธ๊ธํ์ผ๋ฉฐ ์ง๊ธ๊น์ง ์ํํ ๋ฐ์ด๋ ์์ ์ ์์กดํ๋ ๊ฒ ์ธ์ ๋ ๋ฒ์งธ ํจํค์ง์ ์๋ฌด ๊ด๋ จ์ด ์์ต๋๋ค.
๋น์ ์ด ๊ทธ๊ฒ์ ์ฝ๋๋ค๋ฉด, ๋ด๊ฐ ์ด๊ฒ์ ์ฒ์์ ์ง์ ์ฌ์ฉํ ์ ์ผํ ์ด์ ๋ ๋น์ ์ด ์์ฒญํ ๊ฒ๊ณผ ๋๊ฐ์ ๊ธฐ๋ฅ์ด ํ์ํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ด ์ฑ์ 1๋ ์ด์ ๋ฌธ์ ์์ด ์ฌ์ฉํ๊ณ ์์ต๋๋ค. ๊ฒ๋ค๊ฐ, ๊ฐ๋ ๊ฐ๋ฐ์๊ฐ ๊ฒฉ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ๋ณด๋ค ๊ฒฉ๋ฆฌ์ ๋ด๋ถ ์๋์ ๋ ์ต์ํด์ง๋ฉด(๋ํ Flutter Web์์ ํด๋น ์์ ์ ์์ํ๋ค๋ ์ฌ์ค๋ ์๊ฒ ๋์์ต๋๋ค) ๋ด๊ฐ ์ด ๋ด์ฉ์ด ์ฌ์ค์ด๋ผ๊ณ ์๊ฐํ๊ฒ ๋ฉ๋๋ค. ์ด ๊ธฐ๋ฅ ์ ํฌํจ์ ๋ฐ๋ํ๋ ์ฃผ์ฅ์ด ๊ฝค ๋ง๊ธฐ ๋๋ฌธ์ ํ๋ ์์ํฌ์ ํฌํจ๋์์ต๋๋ค. ์๊ฐ์ด ๋ง์ด ๊ฑธ๋ฆฌ๊ธฐ ๋๋ฌธ์ด ์๋๋ผ ์ ํ ์๋๋๋ค. ์๊ฐ์ด ๋น๊ต์ ์ ๊ฒ ์์๋ ๊ฒ์ ๋๋ค. ๋จ์ํ ์ผ๋ถ๋ง ์ค์ ๋ก ํ์ํ๊ณ ์ฌ์ฉํ๋ ๊ฒ๋ณด๋ค ๋ชจ๋ ๊ฒฉ๋ฆฌ์ ๋ฐฑ์๋ ๋ณต์ก์ฑ์ ์ถ๊ฐํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
@deakjahn ์ด ํ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค. isolate_handler๋ฅผ ์ฌ์ฉํ๋ฉด ๋ค์ดํฐ๋ธ ์ธก์์ ์๋ฆผ์ ๋ฐ์ ๋๋ง๋ค ๋ฉ์๋๋ฅผ ํธ์ถํ๊ณ ๋คํธ ์ธก์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด๋ ๋ฐ ๋์์ด ๋ ๊น์? (์ ๋ twilio ๊ธฐ๋ณธ SDK๋ฅผ ์ฌ์ฉํ๊ณ ์์ผ๋ฉฐ ๊ธฐ๋ณธ ์ธก์์ ํธ์ ์๋ฆผ์ ๋ฐ๊ณ ์์ต๋๋ค)
์ด๊ฒ์ด ํ๋ซํผ ์ฑ๋์ ํตํด ํต์ ํ๋ ๋ฐ ์ฌ์ฉํ๋ patform ํ๋ฌ๊ทธ์ธ์ด ์๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค๋ฉด ์, ๋ ํจํค์ง ์ค ํ๋๊ฐ ๋์์ด ๋ ๊ฒ์ ๋๋ค. ์ผ๋ฐ ์ฝ๋์์ ์๋ํ๋ ๊ฒฝ์ฐ ์ด๋ฌํ ํจํค์ง๋ฅผ ์ฌ์ฉํ๋ฉด ๊ฒฉ๋ฆฌ์์๋ ์๋ํฉ๋๋ค.
@deakjahn ๋น ๋ฅธ ๋ต๋ณ ๊ฐ์ฌํฉ๋๋ค! ๋ด ๋ฌธ์ ๋ ์ผ๋ฐ ํ๋ซํผ ์ฑ๋๋ก ํ ์ ์๋ค๋ ๊ฒ์ ๋๋ค. ํ์คํ์ง ์์ง๋ง twilio sdk๋ ๋ฉ์ธ ์ค๋ ๋๊ฐ ์๋ ๋ณ๋์ ๊ฒฉ๋ฆฌ์์ ํธ์ ์๋ฆผ ์์ ์ ์ฒ๋ฆฌํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ๊ฒ์ด ๋ด ๋ฌธ์ ๋ผ๊ณ ์๊ฐํฉ๋๋ค. ๋ ํจํค์ง ์ค ํ๋๋ฅผ ์ฌ์ฉํ์ฌ ์๋ฆผ์ ๋ฐ์ ๋๋ง๋ค ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ์๋ํ๋์ง ์๊ณ ์ถ์์ต๋๋ค. ๊ฐ์ฌํฉ๋๋ค. (๊ฐ๋ฅํ์ง ์๋ค๋ฉด ๊ธฐ๋ณธ ์ฑ์ผ๋ก ์ ํํ๋ ๊ฒ์ ๊ณ ๋ คํ๊ณ ์์ต๋๋ค)
๋๋ Twilio๊ฐ ๋ฌด์์ธ์ง์กฐ์ฐจ ์์ง ๋ชปํ๊ธฐ ๋๋ฌธ์ (OK, ๋๋ ๊ทธ๊ฒ์ ๋ดค์ :-)), ๊ทธ๋์ ๋๋ ์ ๋ง๋ก ํ์ ํ ์ ์์ต๋๋ค. ํ์ง๋ง ์ด์จ๋ ๋ค์ดํฐ๋ธ ์ฝ๋๋ฅผ ์ธํฐํ์ด์คํ๋ ค๋ฉด ํ๋ซํผ ์ฑ๋ ์ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ์ด Twilio๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด ๋ง๋ ์ด๋ฏธ ์กด์ฌํ๋ ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉํ๊ฑฐ๋ ์ง์ ์์ฑํฉ๋๋ค(์ด ๊ฒฝ์ฐ ๊ฑฐ์ ๋์ผํ ํ๋ฌ๊ทธ์ธ์ ๋ง๋ค๊ณ ๊ฒ์ํ์ง ์๊ณ ๋ก์ปฌ์์ ์ฐธ์กฐ). ๋๋ ๋จ์ํ ๊ด๋ จ ํ๋ฌ๊ทธ์ธ์ ๋ณต์ฌํฉ๋๋ค. ์ฝ๋๋ฅผ ์์ ์ ์ฑ์ ์ถ๊ฐํฉ๋๋ค(์ธ๋ถ ์ข ์์ฑ์ ์๋์ง๋ง ๊ทธ ์ธ์๋ ์ค์ ๋ก ๋์ผํ ์ฝ๋๋ฅผ ๊ฐ์ต๋๋ค).
๊ทธ๋ฆฌ๊ณ ํ๋ซํผ ์ฑ๋์ด ์๋ ๊ฒฝ์ฐ ์ด์ ๋ต๋ณ์ด ์ ์ฉ๋ฉ๋๋ค. ์ผ๋ฐ Flutter ์ฑ์ ๋ฉ์ธ ์ค๋ ๋์์ ํ๋ซํผ ์ฑ๋๊ณผ ํ๋ฌ๊ทธ์ธ์ ์ด๋ฏธ ์ฌ์ฉํ ์ ์๋ค๋ฉด ๋ค์ ์ค ํ๋๋ฅผ ์ฌ์ฉํ์ฌ ๊ฒฉ๋ฆฌ์์ ๋์ผํ ๊ฒ์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ ๊ฐ์ ํจํค์ง.
๋ฐ๋ผ์ ์ด ๋ฌธ์ ๋ 2018๋
1์ 5์ผ๋ถํฐ ์กด์ฌํ๋ฉฐ ์ถ๊ฐ ๋
ธ๋ ฅ์ผ๋ก ์ฌ์ ํ ๋ถ๊ฐ๋ฅํฉ๋๋ค. ์ ๊ณต๋ ์๋ฃจ์
์ ํ๋ฅญํ์ง๋ง ๋ฐ์คํฌํ์์๋ ์์ง ์๋ํ๋ ๊ฒ์ด ์์ต๋๋ค. ๋ฐ๋ผ์ ๋ฐ์คํฌํ์์ Flutter๊ฐ ์ผ๋ง๋ ์ ์๋ํ๋์ง ์ํํด๋ณด๊ณ ๋ฏธ๋ ์ ํ์ ๋ํ ๊ฐ๋ฅ์ฑ์ด ์๋์ง ํ์ธํ๋ ค๋ ์ฌ๋์ ์ฌ๊ธฐ์์ ์์ ํ ๋งํ๊ฒ ๋ ๊ฒ์
๋๋ค.
๊ฑฐ์ ๋ชจ๋ ์ฑ์ ๊ฒฉ๋ฆฌ๊ฐ ํ์ํฉ๋๋ค. ํญ์ ์์ฒญ๋ ๊ณ์ฐ์ด ์๊ธฐ ๋๋ฌธ์ ์ค์ํ Api ์ค๊ณ ๊ฒฐํจ์ ๋ํด ์๋ฌด ์ผ๋ ์ผ์ด๋์ง ์์ ์ ์๋ค๋ ๊ฒ์ด ์ด๋ป๊ฒ ๊ฐ๋ฅํ๊ฐ์?
๋ด ํ๋ฌ๊ทธ์ธ ์์คํ ๊ฒฝ๊ณ ์ฐฝ ์ ์ด์ ๋ํ ๋ฐฉ๋ฒ์ ์ถ๊ฐํ์ต๋๋ค.
์๋ฃจ์
์ ์ฌ๊ธฐ์ ์ธ๊ธ ๋์ด ์์ต๋๋ค.
์ ๊ณต๋ ์์ ๋ ์์คํ
๊ฒฝ๊ณ ์ฐฝ ํ๋ฌ๊ทธ์ธ๊ณผ ๊ด๋ จ์ด ์์ง๋ง ๋ค๋ฅธ ํ๋ฌ๊ทธ์ธ์์๋ ์ฝ๊ฒ ๋ณต์ ํ ์ ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ๊ฒ์ ์๋์ํค๊ธฐ ์ํด ๋ค๋ฅธ ๋ฉ์ง ํ๋ฌ๊ทธ์ธ์ด ํ์ํ์ง ์์ต๋๋ค!
์ด๊ฒ์ ์ฌ์ ํ โโ๋ฌธ์ ๊ฐ ๋ ์ ์์ต๋๋ค. ํ๋ฌ๊ทธ์ธ์ผ๋ก ๋ฌด์์ด๋ ํ๋ ค๋ฉด ์ฑ ๋ฒ์์ ๋ฉ์์ง๋ฅผ ๋ณด๋ด์ผ ํ๊ธฐ ๋๋ฌธ์ ๋ฐฑ๊ทธ๋ผ์ด๋/ํฌ๊ทธ๋ผ์ด๋์์ ์คํ ์ค์ธ ๊ฒฉ๋ฆฌ์์ ํ๋ฌ๊ทธ์ธ์ ์ง์ ํธ์ถํ ์ ์๋ ๋ฐฉ๋ฒ์ด ์์์ ์๋ฏธํฉ๋๋ค. ๋ฐ๋ผ์ ์ฑ์ด ์คํ๋๊ณ ์์ง ์๋ค๋ฉด ๋ฐฑ๊ทธ๋ผ์ด๋์์ ํ๋ฌ๊ทธ์ธ์ผ๋ก ์๋ฌด ๊ฒ๋ ํ ์ ์์ต๋๋ค.
๋ฐ๋ผ์ ์๋ฅผ ๋ค์ด ์ฑ์ด ๋ซํ ๋ FCM ํ๋ฌ๊ทธ์ธ์ backgroundMessageHandler์์ ๊ณต์ ๊ธฐ๋ณธ ์ค์ ์ผ๋ก ๋ฌด์์ด๋ ํ๋ ค๋ ๊ฒฝ์ฐ MissingPluginException์ด ๋ฐ์ํฉ๋๋ค.
๋๋ ์์คํ ๊ฒฝ๊ณ ์ฐฝ์ผ๋ก ์ฑ์ ์ด์ง ์์ผ๋ ค๋ ๊ฒฝ์ฐ. ๊ฒฝ๊ณ ์ฐฝ์ด ๋ค๋ฅธ ๊ฒฉ๋ฆฌ์์ ์คํ ์ค์ ๋๋ค. ๋ฐ๋ผ์ ์ฑ ๋ฒ์ ๋ด์์ ์ฝ๋๋ฅผ ์คํํด์ผ ํฉ๋๋ค. ์ฑ์ด ํ์ฌ ๋ซํ ์๊ธฐ ๋๋ฌธ์ ๋ฌธ์ ๊ฐ ๋ฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ์ด๊ฒ์ด ํฐ ๋ฌธ์ ์ธ ๋ค๋ฅธ ๋ง์ ์๋๋ฆฌ์ค๊ฐ ์์ ๊ฒ์ ๋๋ค.
@michael-ottink ์ค๋ช ํ๋ ์๋๋ฆฌ์ค๋ ์ ํํ ๋ฌธ์ ๊ฐ ์์ด์ผ ํ๋ ์๋๋ฆฌ์ค์ ๋๋ค. ๋ฐฑ๊ทธ๋ผ์ด๋์์ ์ฝ๋๋ฅผ ์คํํ๋ ํ๋ฌ๊ทธ์ธ์ ์ผ๋ฐ์ ์ผ๋ก ์์ฒด ํ๋ฌ๊ทธ์ธ ๋ ์ง์คํธ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ์์ ํ ์๋ก์ด FlutterEngine์ ์ธ์คํด์คํํ๊ณ ๊ทธ ์์์ ์คํ๋๋ ๊ฒฉ๋ฆฌ๋ ํ๋ซํผ ์ฑ๋์ ํตํด ํด๋น ํ๋ฌ๊ทธ์ธ๊ณผ ์ง์ ํต์ ํ ์ ์์ต๋๋ค.
๋ง๋ถ์ฌ์, ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉํ๊ธฐ ์ํด ๊ฒฉ๋ฆฌ๊ฐ ํ์ํ ๊ฒฝ์ฐ ์ฌ์ด ๋ฐฉ๋ฒ์ ํด๋น ๊ฒฉ๋ฆฌ๋ฅผ FlutterEngine์ ๋ํํ๋ ๊ฒ์ ๋๋ค. ๊ทธ๋ฌ๋ฉด ํด๋น ๊ถํ์ ๋ง์ ์ฒ๋ผ ์์๋ฐ๊ฒ ๋ฉ๋๋ค. ์ด๊ฒ์ Android ๋ฐ iOS์์ flutter_isolate ํจํค์ง๊ฐ ํ๋ ์ผ์ ๋๋ค(ํด๊ฒฐ ๋ฐฉ๋ฒ๋ณด๋ค ์ ์ ํ ์์ ์ ํ๋ ๊ฒ์ด ๋ ๋ซ๋ค๋ ๋ฐ ๋์ํฉ๋๋ค. ํ์ฌ ์ฌ์ฉ ๊ฐ๋ฅํ ํด๊ฒฐ ๋ฐฉ๋ฒ์๋ ๋ณ๋ชฉ ํ์, ์ค๋ฒํค๋๊ฐ ์๊ฑฐ๋ ๊ทธ๋ ์ง ์์ผ๋ฉด ์ ์ง ๊ด๋ฆฌ๊ฐ ์ ๋๋ก ์ด๋ฃจ์ด์ง์ง ์๊ฑฐ๋ ์ง์์ด ๋ถ์กฑํ ์ ์์ต๋๋ค. ๋ชจ๋ ํ๋ซํผ.)
@ryanheise so flutter_isolate ์ ํํ ๋ง๋์? ๋ฌธ์์์ ์ด๋ป๊ฒ ๋งํ ์ ์์ต๋๋ค. FCM onBackgroundMessage์์ ์๋ํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํฉ๋๊น? ๊ทธ๋์ ๋ด onBackgroundMessageHandler์์ ์ ๊ฒฉ๋ฆฌ๋ฅผ ์์ฑํด์ผ ํฉ๋๊น? ํ์ง๋ง ๊ฑฐ๊ธฐ์์ ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉํ ์ ์์ผ๋ฏ๋ก flutter_isolate๋ฅผ ์ด๋ป๊ฒ ์ฌ์ฉํฉ๋๊น?
๋ฌธ์ ๋ firebase_messaging์ด ์ค๋ซ๋์ ์ ๋ฐ์ดํธ๋์ง ์์๊ณ ์ต์ ๋ฐฑ๊ทธ๋ผ์ด๋ ์คํ API๋ณด๋ค ํจ์ฌ ๋ค๋จ์ด์ ธ ์๋ค๋ ๊ฒ์ ๋๋ค. ๊ทธ๋ค์ด ํ๋ฌ๊ทธ์ธ์ ์ ๋ฐ์ดํธํ๋ค๋ฉด ๋ ์ด์ ์ด ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ง ์์ ๊ฒ์ ๋๋ค. ๋ค์ ๋ช ํํ ํ์๋ฉด, ๊ทํ๊ฐ ์ค๋ช ํ๋ ์๋๋ฆฌ์ค๋ ์ฌ๋ฐ๋ฅด๊ฒ ๊ตฌํ๋ ๊ฒฝ์ฐ ๋ฐฑ๊ทธ๋ผ์ด๋ ๊ฒฉ๋ฆฌ๊ฐ ์ด๋ฏธ ํ๋ฌ๊ทธ์ธ์ ์ก์ธ์คํ ์ ์์ด์ผ ํ๊ธฐ ๋๋ฌธ์ ๋ฌธ์ ๊ฐ ์์ด์ผ ํ๋ ์๋๋ฆฌ์ค์ ๋๋ค. firebase_messaging ํ๋ฌ๊ทธ์ธ์ ์ต์ API์ ๋ฐ๋ผ ๊ตฌํ๋์ง ์์์ผ๋ฏ๋ก ์๋ํ์ง ์์ต๋๋ค. ํด๋น ํ๋ก์ ํธ์ ํจ๊ป ๋ฒ๊ทธ ๋ณด๊ณ ์๋ฅผ ์ ์ถํ ์ ์์ต๋๋ค.
๋๋ ์ด๊ฒ์ ๋ํ ๋์์ด ์ ์คํ ํ์ํฉ๋๋ค. ๋ด๊ฐ ํ ์์๋ ๋ฐฉ๋ฒ์ด ์์ต๋๊น? ๋๋ ๋ด์ผ ๋์ ์ฒซ ๋ฒ์งธ ์ง์งํ ๊ฑฐ๋๊ฐ ์๊ณ ๋๋ ๊ทธ๊ฒ์ ์ดํดํ ์ ์์ต๋๋ค.
ํ๋ฌ๊ทธ์ธ์ด ๋ก๋๋๊ณ ์๋์ง ํ์ธํ๊ธฐ ์ํด ๋ชจ๋ ์์ ์ ์ํํฉ๋๋ค. ๋ฐฑ๊ทธ๋ผ์ด๋ ๋ฉ์์ง๋ฅผ ํ์ฑํํ๋ ๋ฐฉ๋ฒ์ ๋ํ README์ ์ง์นจ์ ๋ฐ๋๋์ง ๋ชจ๋ฅด๊ฒ ์ง๋ง ํ๋ฌ๊ทธ์ธ์ ๋ฐฑ๊ทธ๋ผ์ด๋ FlutterNativeView ์ด๊ธฐํ์ ์ฐ๊ฒฐํ๋ ์ฌ์ฉ์ ์ง์ Application ํด๋์ค๋ฅผ ๋ง๋ค์ด์ผ ํฉ๋๋ค. ๊ทธ๋ ๊ฒ ํ์ง ์์ผ๋ฉด ์ฌ์ฉํ ์ ์๋ ํ๋ฌ๊ทธ์ธ์ด ์์ต๋๋ค. ๊ทธ๋๋ ์๋ํ์ง ์์ผ๋ฉด ํ๋ก์ ํธ๋ฅผ ์ด์ v1 ์คํ์ผ ํ๋ฌ๊ทธ์ธ ์ํคํ ์ฒ๋ก ๋ค์ด๊ทธ๋ ์ด๋ํ ์ ์์ต๋๋ค(v2๊ฐ ํ์ํ ๋ค๋ฅธ ํ๋ฌ๊ทธ์ธ์ด ์ค๋จ๋ ์ํ์ด ์์).
๋ด Application.k๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์ค์ ํฉ๋๋ค.
import `in`.jvapps.system_alert_window.SystemAlertWindowPlugin
import io.flutter.app.FlutterApplication
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService
import android.os.Build
import android.app.NotificationManager
import android.app.NotificationChannel
public class Application: FlutterApplication(), PluginRegistrantCallback {
override fun onCreate() {
super.onCreate()
FlutterFirebaseMessagingService.setPluginRegistrant(this)
createNotificationChannels()
SystemAlertWindowPlugin.setPluginRegistrant(this)
}
override fun registerWith(registry: PluginRegistry) {
FirebaseCloudMessagingPluginRegistrant.registerWith(registry)
SystemAlertWindowPlugin.registerWith(registry.registrarFor("in.jvapps.system_alert_window"))
}
fun createNotificationChannels() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val name = "groupChannel"
val descriptionText = "This is the group channel"
val importance = NotificationManager.IMPORTANCE_HIGH
val mChannel = NotificationChannel("59054", name, importance)
mChannel.description = descriptionText
val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(mChannel)
}
}
}
์ด ๋ฌธ์ ์ ๊ด๋ จ์ด ์์ผ๋ฏ๋ก firebase_messaging ๋ฌธ์ ํ์ด์ง์ ๊ฒ์ํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ข์ต๋๋ค.
'SchedulerBinding'์ ๋ํ ์๋ก์ด 'spawnIsolate' ๋ฉ์๋๊ฐ ์๋ PR์ ๋ง๋ค ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ฉด ์ด ๊ฒฉ๋ฆฌ์์ ํ๋ซํผ ๋ฉ์๋๋ฅผ ํธ์ถํ ์ ์์ต๋๋ค.
์ด๊ฒ์ ํ๋ซํผ ๋ฉ์๋๋ฅผ ํธ์ถํ๊ณ ์๋ต์ ๋ฐ์์ผ ํ๋ ๊ฒฝ์ฐ์๋ง ๋์์ด ๋ฉ๋๋ค.
import 'dart:async';
import 'dart:isolate';
import 'package:flutter/scheduler.dart';
import 'package:flutter/widgets.dart';
import 'package:path_provider/path_provider.dart';
Future<void> _test(SendPort sendPort) async {
final dir = await getTemporaryDirectory();
sendPort.send(dir);
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final Completer<Object> completer = Completer<Object>();
final RawReceivePort receivePort = RawReceivePort(completer.complete);
final Isolate isolate = await ServicesBinding.instance.spawnIsolate(
_test,
receivePort.sendPort,
);
print(await completer.future);
receivePort.close();
isolate.kill();
}
ํต๋๋ฌด
Performing hot restart...
Syncing files to device Pixel 4...
Restarted application in 722ms.
I/flutter (11705): Directory: '/data/user/0/com.example.bug/cache'
'SchedulerBinding'์ ๋ํ ์๋ก์ด 'spawnIsolate' ๋ฉ์๋๊ฐ ์๋ PR์ ๋ง๋ค ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ฉด ์ด ๊ฒฉ๋ฆฌ์์ ํ๋ซํผ ๋ฉ์๋๋ฅผ ํธ์ถํ ์ ์์ต๋๋ค.
์ด๊ฒ์ ํ๋ซํผ ๋ฉ์๋๋ฅผ ํธ์ถํ๊ณ ์๋ต์ ๋ฐ์์ผ ํ๋ ๊ฒฝ์ฐ์๋ง ๋์์ด ๋ฉ๋๋ค.
SchedulerBinding.instance.spawnIsolate
์ด๊ฒ์ ํ ์คํธํ ๊ธฐํ๊ฐ ์์ต๋๊น? ๋ด ์๊ตฌ ์ฌํญ์ ๋ง๋ ๊ฒฝ์ฐ ๋ฑ ..
@๋์ผ๋ฆญ
์ด ํ์ผ์ ๊ต์ฒดํ์ญ์์ค(๋ฒ์ 1.17.5์ ๊ฒฝ์ฐ ์ค์ ).๋ฐ์ธ๋ฉ.๋คํธ
```dart// Copyright 2014 The Flutter Authors. ํ๊ถ ์์ .
// ์ด ์์ค ์ฝ๋์ ์ฌ์ฉ์ BSD ์คํ์ผ ๋ผ์ด์ ์ค์ ์ ์ฉ์ ๋ฐ์ต๋๋ค.
// LICENSE ํ์ผ์์ ์ฐพ์์ต๋๋ค.
๊ฐ์ ธ์ค๊ธฐ ' ๋คํธ:๋น๋๊ธฐ ';
๊ฐ์ ธ์ค๊ธฐ ' ๋คํธ:๋ถ๋ฆฌ ';
๊ฐ์ ธ์ค๊ธฐ ' ๋คํธ:typed_data ';
' dart:ui '๋ฅผ ui๋ก ๊ฐ์ ธ์ต๋๋ค.
๊ฐ์ ธ์ค๊ธฐ ' ํจํค์ง:flutter/foundation.dart ';
import 'asset_bundle.dart';
import 'binary_messenger.dart';
'system_channels.dart' ๊ฐ์ ธ์ค๊ธฐ;
/// ํ๋ซํผ ๋ฉ์์ง๋ฅผ ์์ ํ๊ณ [defaultBinaryMessenger]๋ก ๋ณด๋
๋๋ค.
///
/// [ServicesBinding]์ ๋ํ ๋
ธ์ถํ๋ [LicenseEntryCollector]๋ฅผ ๋ฑ๋กํฉ๋๋ค.
/// ์์ฐ์ ๋ฃจํธ์ ์ ์ฅ๋ LICENSE
ํ์ผ์์ ์ฐพ์ ๋ผ์ด์ ์ค
/// ๋ฒ๋ค๋ก ์ ๊ณต๋๊ณ ext.flutter.evict
์๋น์ค ํ์ฅ์ ๊ตฌํํฉ๋๋ค(์ฐธ์กฐ
/// [ํด๊ฑฐ]).
BindingBase์ ๋ฏน์ค์ธ ServicesBinding {
@์ฐ์ธํ๋ค
๋ฌดํจ initInstances() {
super.initInstances();
_instance = ์ด๊ฒ;
_defaultBinaryMessenger = createBinaryMessenger();
window.onPlatformMessage = defaultBinaryMessenger.handlePlatformMessage;
์ด๊ธฐํ ๋ผ์ด์ ์ค();
SystemChannels.system.setMessageHandler(handleSystemMessage);
}
/// ์์ฑ๋ ๊ฒฝ์ฐ ํ์ฌ [ServicesBinding]์
๋๋ค.
์ ์ ServicesBinding get ์ธ์คํด์ค => _instance;
์ ์ ์๋น์ค ๋ฐ์ธ๋ฉ _instance;
/// [BinaryMessenger]์ ๊ธฐ๋ณธ ์ธ์คํด์ค์
๋๋ค.
///
/// ์ ํ๋ฆฌ์ผ์ด์
์์ ํ๋ซํผ์ผ๋ก ๋ฉ์์ง๋ฅผ ๋ณด๋ด๋ ๋ฐ ์ฌ์ฉ๋๋ฉฐ,
/// ๊ฐ ์ฑ๋์ ๋ฑ๋ก๋ ํธ๋ค๋ฌ๋ฅผ ์ถ์ ํ๋ฏ๋ก
/// ๋ค์ด์ค๋ ๋ฉ์์ง๋ฅผ ๋ฑ๋ก๋ ํธ๋ค๋ฌ์ ์ ๋ฌํ ์ ์์ต๋๋ค.
BinaryMessenger get defaultBinaryMessenger => _defaultBinaryMessenger;
BinaryMessenger _defaultBinaryMessenger;
/// ์ ์ก์ ์ฌ์ฉํ ์ ์๋ ๊ธฐ๋ณธ [BinaryMessenger] ์ธ์คํด์ค๋ฅผ ๋ง๋ญ๋๋ค.
/// ํ๋ซํผ ๋ฉ์์ง.
@๋ณดํธ
BinaryMessenger createBinaryMessenger() {
๋ฐํ const _DefaultBinaryMessenger._();
}
/// [SystemChannels.system]์์ ์์ ๋ ๋ฉ์์ง์ ๋ํด ํธ์ถ๋ ํธ๋ค๋ฌ
/// ๋ฉ์์ง ์ฑ๋.
///
/// ๋ค๋ฅธ ๋ฐ์ธ๋ฉ์ ๋ค์ด์ค๋ ์์คํ
๋ฉ์์ง์ ์๋ตํ๊ธฐ ์ํด ์ด๊ฒ์ ์ฌ์ ์ํ ์ ์์ต๋๋ค.
@๋ณดํธ
@mustCallSuper
๋ฏธ๋
/// [LicenseRegistry]์ ๊ด๋ จ ๋ผ์ด์ ์ค๋ฅผ ์ถ๊ฐํฉ๋๋ค.
///
/// ๊ธฐ๋ณธ์ ์ผ๋ก [ServicesBinding]์ [initLicenses] ๊ตฌํ์ ๋ค์์ ์ถ๊ฐํฉ๋๋ค.
/// ์ปดํ์ผํ๋ ๋์ flutter
๋๊ตฌ์์ ์์งํ ๋ชจ๋ ๋ผ์ด์ ์ค.
@๋ณดํธ
@mustCallSuper
๋ฌดํจ initLicenses() {
LicenseRegistry.addLicense(_addLicenses);
}
๊ฐ์ธ
// ์ฌ๊ธฐ์์ ํ์ด๋จธ๋ฅผ ์ฌ์ฉํฉ๋๋ค(์ค์ผ์ค๋ฌ ๋ฐ์ธ๋ฉ์ scheduleTask ๋์ ).
// ์๋น์ค ๊ณ์ธต์ ์ค์ผ์ค๋ฌ ๋ฐ์ธ๋ฉ(์ค์ผ์ค๋ฌ
// ๋ฐ์ธ๋ฉ์ ์๋น์ค ๊ณ์ธต์ ์ฌ์ฉํ์ฌ ์๋ช
์ฃผ๊ธฐ ์ด๋ฒคํธ๋ฅผ ๊ด๋ฆฌํฉ๋๋ค. ํ์ด๋จธ
// ์ด๋ ์ด์จ๋ scheduleTask๊ฐ ๋ด๋ถ์ ์ผ๋ก ์ฌ์ฉํ๋ ๊ฒ์
๋๋ค. ์ ์ผํ ์ฐจ์ด์ ์
// ์ด๊ฒ๋ค์ ์๋์ ์ผ๋ก ์ฐ์ ์์๊ฐ ์ง์ ๋๋ ๋์ ๋ค์์๋ง ์คํ๋ฉ๋๋ค.
// ์คํ ์ค์ผ ์ ์๋ ๋ค๋ฅธ ์์
. ์ฌ๊ธฐ์์ _๋ฌด์ธ๊ฐ_๋ฅผ ์ฌ์ฉํ์ฌ ์ค๋จ
// isolates๋ฅผ ๋ณต์ฌํ๋ ๋ฐ ์๊ฐ์ด ๊ฑธ๋ฆฌ๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ ๋ ๋ถ๋ถ์ผ๋ก ๋๋๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
// ํ์ฌ ๋ฐ์ดํฐ์ด๊ณ ๋์ผํ ์ด๋ฒคํธ ๋ฃจํ์์ ๋ฐ์ดํฐ๋ฅผ ์์ ํ๋ ๊ฒฝ์ฐ
// ๋ค์ ๊ฒฉ๋ฆฌ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ผ ๋ ๋ฐ๋ณต, ์ฐ๋ฆฌ๋ ํ์คํ
// ํ๋ ์์ ๋์น๊ฒ ๋ฉ๋๋ค. ๋ ๋ค๋ฅธ ์๋ฃจ์
์ ๋ชจ๋ ์์
์
// ํ๋์ ๊ฒฉ๋ฆฌ์์ ๋ฐ์ํ๊ณ ๊ฒฐ๊ตญ ๊ฑฐ๊ธฐ์ ๊ฐ ์ ์์ง๋ง ๋จผ์
// ๊ฒฉ๋ฆฌ ํต์ ์ ๋ ์ ๋ ดํ๊ฒ ๋ง๋ค ์ ์๋์ง ํ์ธํฉ๋๋ค.
// ์ฐธ์กฐ: https://github.com/dart-lang/sdk/issues/31959
// https://github.com/dart-lang/sdk/issues/31960
// TODO(ianh): ์ด๋ฌํ ๋ฒ๊ทธ๊ฐ ์์ ๋๋ฉด ์ด ๋ณต์ก์ฑ์ ์ ๊ฑฐํฉ๋๋ค.
์ต์ข
์์ฑ์
Timer.run(() ๋น๋๊ธฐ {
rawLicenses.complete(rootBundle.loadString('LICENSE', ์บ์: false));
});
rawLicenses.future๋ฅผ ๊ธฐ๋ค๋ฆฝ๋๋ค.
์ต์ข
์์ฑ์> parsedLicenses = ์์ฑ์
>();
Timer.run(() ๋น๋๊ธฐ {
parsedLicenses.complete(compute(_parseLicenses, rawLicenses.future ๋๊ธฐ, debugLabel: 'parseLicenses'));
});
parsedLicenses.future๋ฅผ ๊ธฐ๋ค๋ฆฝ๋๋ค.
yield* ์คํธ๋ฆผ
}
// ์ด๊ฒ์ ์์ _addLicenses์ ์ํด ์์ฑ๋ ๋ค๋ฅธ ๊ฒฉ๋ฆฌ์์ ์คํ๋ฉ๋๋ค.
์ ์ ๋ชฉ๋ก
์ต์ข
๋ฌธ์์ด _licenseSeparator = '\n' + ('-' * 80) + '\n';
์ต์ข
๋ชฉ๋ก
์ต์ข
๋ชฉ๋ก
for (๋ผ์ด์ผ์ค์ ์ต์ข
๋ฌธ์์ด ๋ผ์ด์ ์ค) {
์ต์ข
์ ์ ๋ถํ = license.indexOf('\n\n');
if (๋ถํ >= 0) {
result.add(LicenseEntryWithLineBreaks(
license.substring(0, split).split('\n'),
license.substring(๋ถํ + 2),
));
} ๋ ๋ค๋ฅธ {
result.add(LicenseEntryWithLineBreaks(const
}
}
๋ฐํ ๊ฒฐ๊ณผ;
}
@์ฐ์ธํ๋ค
๋ฌดํจ initServiceExtensions() {
super.initServiceExtensions();
assert(() {
registerStringServiceExtension(
// ext.flutter.evict value=foo.png will cause foo.png to be evicted from
// the rootBundle cache and cause the entire image cache to be cleared.
// This is used by hot reload mode to clear out the cache of resources
// that have changed.
name: 'evict',
getter: () async => '',
setter: (String value) async {
evict(value);
},
);
return true;
}());
}
/// ext.flutter.evict
์๋น์ค ํ์ฅ์ ๋ํ ์๋ต์ผ๋ก ํธ์ถ๋ฉ๋๋ค.
///
/// ์ด๊ฒ์ ํซ ๋ฆฌ๋ก๋ ๋์ flutter
๋๊ตฌ์์ ์ฌ์ฉํ๋ฏ๋ก ๋ชจ๋ ์ด๋ฏธ์ง๊ฐ
/// ๋์คํฌ์์ ๋ณ๊ฒฝ๋ ์ฌํญ์ ์บ์์์ ์ง์์ง๋๋ค.
@๋ณดํธ
@mustCallSuper
๋ฌดํจ ์ถ์ถ(๋ฌธ์์ด ์์ฐ) {
rootBundle.evict(์์ฐ);
}
๋ฏธ๋
๋ฏธ๋๋๋
T ๋ฉ์์ง, {
๋ถ์ธ ์ผ์ ์ค์ง = ๊ฑฐ์ง,
๋ถ์ธ ์ค๋ฅ๊ฐ ์น๋ช
์ ์ด๊ณ ,
์ผ๋ํฌํธ ์จ์์ํธ,
SendPort ์ค๋ฅ,
๋ฌธ์์ด ๋๋ฒ๊ทธ ์ด๋ฆ,
}) {
์ฃผ์ฅํ๋ค(
_isMainIsolate,
'์ฌ๋ฌ ์์ค์ ๋ถ๋ฆฌ๋ฅผ ๋ง๋ค ์ ์์',
);
final RawReceivePort messageReceiver = RawReceivePort(
(Object receivedMessage) async {
if (receivedMessage is SendPort) {
receivedMessage.send(
_IsolateStarter<T>(
ui.PluginUtilities.getCallbackHandle(entryPoint),
message,
),
);
} else if (receivedMessage is _Message) {
final ByteData result = await defaultBinaryMessenger.send(
receivedMessage.channel,
receivedMessage.message,
);
receivedMessage.sendPort.send(result);
}
},
);
RawReceivePort onExitReceiver;
onExitReceiver = RawReceivePort(
(Object message) {
onExit?.send(message);
onExitReceiver.close();
messageReceiver.close();
},
);
return Isolate.spawn(
_startIsolate,
messageReceiver.sendPort,
paused: paused,
errorsAreFatal: true,
onExit: onExitReceiver.sendPort,
onError: onError,
debugName: debugName,
);
}
}
๋ฏธ๋
_sendPortToMainIsolate = sendPort;
_IsolateBinding();
์ต์ข
์์ฑ์<_IsolateStarter
์์ฑ์<_IsolateStarter
์ต์ข
RawReceivePort ์์ ํฌํธ = RawReceivePort(
(๊ฐ์ฒด ๊ฒฉ๋ฆฌ ์์) {
assert(isolateStarter๋ _IsolateStarter์
๋๋ค.
completer.complete(isolateStarter๋ฅผ _IsolateStarter๋ก
},
);
sendPort.send(receivePort.sendPort);
์ต์ข
_IsolateStarter
์์ ํฌํธ.๋ซ๊ธฐ();
์ต์ข
๊ธฐ๋ฅ ํจ์ =
UI.PluginUtilities.getCallbackFromHandle(isolateStarter.callbackHandle);
ํจ์(isolateStarter.message)๋ฅผ ๊ธฐ๋ค๋ฆฝ๋๋ค.
}
SendPort _sendPortToMainIsolate;
bool get _isMainIsolate => _sendPortToMainIsolate == null;
ํด๋์ค _IsolateStarter
_IsolateStarter(this.callbackHandle, this.message);
์ต์ข
ui.CallbackHandle callbackHandle;
์ต์ข
T ๋ฉ์์ง;
}
ํด๋์ค _๋ฉ์์ง {
_๋ฉ์ธ์ง(
this.์ฑ๋,
์ด ๋ฉ์์ง,
this.sendPort,
);
์ต์ข
๋ฌธ์์ด ์ฑ๋;
์ต์ข
ByteData ๋ฉ์์ง;
์ต์ข
SendPort sendPort;
}
ํด๋์ค _IsolateBinding์ ServicesBinding {}์ผ๋ก BindingBase๋ฅผ ํ์ฅํฉ๋๋ค.
/// [BinaryMessenger]์ ๊ธฐ๋ณธ ๊ตฌํ.
///
/// ์ด ๋ฉ์ ์ ๋ ์ฑ ์ธก์์ ํ๋ซํผ ์ธก์ผ๋ก ๋ฉ์์ง๋ฅผ ๋ณด๋ด๊ณ
/// ํ๋ซํผ ์ธก์์ ๋ค์ด์ค๋ ๋ฉ์์ง๋ฅผ ์ ์ ํ
/// ํธ๋ค๋ฌ.
ํด๋์ค _DefaultBinaryMessenger๋ BinaryMessenger๋ฅผ ํ์ฅํฉ๋๋ค. {
const _DefaultBinaryMessenger._();
// ํ๋ซํผ ํ๋ฌ๊ทธ์ธ์์ ๋ค์ด์ค๋ ๋ฉ์์ง ์ฒ๋ฆฌ๊ธฐ.
// ์ด๊ฒ์ ์ด ํด๋์ค๊ฐ const ์์ฑ์๋ฅผ ๊ฐ์ง ์ ์๋๋ก ์ ์ ์
๋๋ค.
์ ์ ์ต์ข
์ง๋
// ๋๊ฐ๋ ๋ฉ์์ง๋ฅผ ๊ฐ๋ก์ฑ์ ์๋ตํ๋ ๋ชจ์ ํธ๋ค๋ฌ.
// ์ด๊ฒ์ ์ด ํด๋์ค๊ฐ const ์์ฑ์๋ฅผ ๊ฐ์ง ์ ์๋๋ก ์ ์ ์
๋๋ค.
์ ์ ์ต์ข
์ง๋
๋ฏธ๋
์ต์ข
์์ฑ์
if (_isMainIsolate) {
// ui.window is accessed directly instead of using ServicesBinding.instance.window
// because this method might be invoked before any binding is initialized.
// This issue was reported in #27541. It is not ideal to statically access
// ui.window because the Window may be dependency injected elsewhere with
// a different instance. However, static access at this location seems to be
// the least bad option.
ui.window.sendPlatformMessage(channel, message, (ByteData reply) {
try {
completer.complete(reply);
} catch (exception, stack) {
FlutterError.reportError(FlutterErrorDetails(
exception: exception,
stack: stack,
library: 'services library',
context:
ErrorDescription('during a platform message response callback'),
));
}
});
} else {
RawReceivePort receivePort;
receivePort = RawReceivePort(
(Object message) async {
assert(message is ByteData);
completer.complete(message as ByteData);
receivePort.close();
},
);
_sendPortToMainIsolate.send(
_Message(channel, message, receivePort.sendPort),
);
}
return completer.future;
}
@์ฐ์ธํ๋ค
๋ฏธ๋
์คํธ๋ง ์ฑ๋,
๋ฐ์ดํธ๋ฐ์ดํฐ ๋ฐ์ดํฐ,
ui.PlatformMessageResponseCallback ์ฝ๋ฐฑ,
) ๋น๋๊ธฐ {
ByteData ์๋ต;
๋
ธ๋ ฅํ๋ค {
์ต์ข
MessageHandler ํธ๋ค๋ฌ = _handlers[์ฑ๋];
if (ํธ๋ค๋ฌ != null) {
์๋ต = ํธ๋ค๋ฌ(๋ฐ์ดํฐ)๋ฅผ ๊ธฐ๋ค๋ฆฝ๋๋ค.
} ๋ ๋ค๋ฅธ {
ui.channelBuffers.push(์ฑ๋, ๋ฐ์ดํฐ, ์ฝ๋ฐฑ);
์ฝ๋ฐฑ = null;
}
} catch(์์ธ, ์คํ) {
FlutterError.reportError(FlutterErrorDetails(
์์ธ: ์์ธ,
์คํ: ์คํ,
๋ผ์ด๋ธ๋ฌ๋ฆฌ: '์๋น์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ',
์ปจํ
์คํธ: ErrorDescription('ํ๋ซํผ ๋ฉ์์ง ์ฝ๋ฐฑ ์ค'),
));
} ๋ง์ง๋ง์ผ๋ก {
if (์ฝ๋ฐฑ != null) {
์ฝ๋ฐฑ(์๋ต);
}
}
}
@์ฐ์ธํ๋ค
๋ฏธ๋
์ต์ข
MessageHandler ํธ๋ค๋ฌ = _mockHandlers[์ฑ๋];
if (ํธ๋ค๋ฌ != null)
๋ฆฌํด ํธ๋ค๋ฌ(๋ฉ์์ง);
return _sendPlatformMessage(์ฑ๋, ๋ฉ์์ง);
}
@์ฐ์ธํ๋ค
๋ฌดํจ setMessageHandler(๋ฌธ์์ด ์ฑ๋, MessageHandler ํธ๋ค๋ฌ) {
if (ํธ๋ค๋ฌ == null)
_handlers.remove(์ฑ๋);
๋ ๋ค๋ฅธ
_handlers[์ฑ๋] = ํธ๋ค๋ฌ;
ui.channelBuffers.drain(์ฑ๋, (ByteData ๋ฐ์ดํฐ, ui.PlatformMessageResponseCallback ์ฝ๋ฐฑ) ๋น๋๊ธฐ {
handlePlatformMessage(์ฑ๋, ๋ฐ์ดํฐ, ์ฝ๋ฐฑ)๋ฅผ ๊ธฐ๋ค๋ฆฝ๋๋ค.
});
}
@์ฐ์ธํ๋ค
๋ฌดํจ setMockMessageHandler(๋ฌธ์์ด ์ฑ๋, MessageHandler ํธ๋ค๋ฌ) {
if (ํธ๋ค๋ฌ == null)
_mockHandlers.remove(์ฑ๋);
๋ ๋ค๋ฅธ
_mockHandlers[์ฑ๋] = ํธ๋ค๋ฌ;
}
}
```
๋๋ flutter 1.21์ ๊ฐ์ง๊ณ ์์ผ๋ฏ๋ก ๋ชจ๋ ์ฝ๋๋ฅผ ์
๋ฐ์ดํธํ์ฌ ์ปดํ์ผํ๋ ค๊ณ ํ์ต๋๋ค.
์ด์ _IsolateBinding์ด BindingBase ๋ฉ์๋์ ๊ตฌํ์ ๋ง์ด ๋๋ฝํ๊ธฐ ๋๋ฌธ์ ํ๋์ ๋ฌธ์ ๊ฐ ๋จ์์ต๋๋ค...
๋๋ ์ข์ํ๋ค
Error: The non-abstract class '_IsolateBinding' is missing implementations for these members:
- BindingBase with ServicesBinding.SchedulerBinding.addPersistentFrameCallback
์ฝ 30ํ.
๋ง์ง๋ง์ ์ฝ์์ด ์ธ์ํฉ๋๋ค.
/C:/flutter/packages/flutter/lib/src/services/binding.dart:341:7: Error: 'BindingBase' doesn't implement 'SchedulerBinding' so it can't be used with 'ServicesBinding'.
- 'BindingBase' is from 'package:flutter/src/foundation/binding.dart' ('/C:/flutter/packages/flutter/lib/src/foundation/binding.dart').
- 'SchedulerBinding' is from 'package:flutter/src/scheduler/binding.dart' ('/C:/flutter/packages/flutter/lib/src/scheduler/binding.dart').
- 'ServicesBinding' is from 'package:flutter/src/services/binding.dart' ('/C:/flutter/packages/flutter/lib/src/services/binding.dart').
class _IsolateBinding extends BindingBase with ServicesBinding {}
_startIsolate
์ _IsolateBinding()
ํธ์ถ์ด ๋ฌด์์ ํ๋์ง 100% ํ์ ํ ์ ์์ง๋ง ์ผ๋ฐ์ ์ธ ServicesBinding.defaultBinaryMessenger was accessed before the binding was initialized.
์ค๋ฅ๊ฐ ๋ฐ์ํ์ง ์์ต๋๋ค.
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ค๊ณ ํ์ง๋ง ์์ง ๋ฏน์ค์ธ์ ๋ํ ์ง์์ด ๊ทธ๋ฆฌ ์ข์ง ์์ ๊ฒ ๊ฐ์ต๋๋ค.
๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์์ด๋์ด๊ฐ ์์ต๋๊น?
์ ํ์ผ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค(์ง๊ธ๊น์ง).
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// <strong i="24">@dart</strong> = 2.8
import 'dart:async';
import 'dart:isolate';
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/foundation.dart';
import 'package:flutter/scheduler.dart';
import 'asset_bundle.dart';
import 'binary_messenger.dart';
import 'restoration.dart';
import 'system_channels.dart';
/// Listens for platform messages and directs them to the [defaultBinaryMessenger].
///
/// The [ServicesBinding] also registers a [LicenseEntryCollector] that exposes
/// the licenses found in the `LICENSE` file stored at the root of the asset
/// bundle, and implements the `ext.flutter.evict` service extension (see
/// [evict]).
mixin ServicesBinding on BindingBase, SchedulerBinding {
<strong i="25">@override</strong>
void initInstances() {
super.initInstances();
_instance = this;
_defaultBinaryMessenger = createBinaryMessenger();
_restorationManager = createRestorationManager();
window.onPlatformMessage = defaultBinaryMessenger.handlePlatformMessage;
initLicenses();
SystemChannels.system.setMessageHandler(handleSystemMessage);
SystemChannels.lifecycle.setMessageHandler(_handleLifecycleMessage);
readInitialLifecycleStateFromNativeWindow();
}
/// The current [ServicesBinding], if one has been created.
static ServicesBinding get instance => _instance;
static ServicesBinding _instance;
/// The default instance of [BinaryMessenger].
///
/// This is used to send messages from the application to the platform, and
/// keeps track of which handlers have been registered on each channel so
/// it may dispatch incoming messages to the registered handler.
BinaryMessenger get defaultBinaryMessenger => _defaultBinaryMessenger;
BinaryMessenger _defaultBinaryMessenger;
/// Creates a default [BinaryMessenger] instance that can be used for sending
/// platform messages.
<strong i="26">@protected</strong>
BinaryMessenger createBinaryMessenger() {
return const _DefaultBinaryMessenger._();
}
/// Called when the operating system notifies the application of a memory
/// pressure situation.
///
/// This method exposes the `memoryPressure` notification from
/// [SystemChannels.system].
<strong i="27">@protected</strong>
<strong i="28">@mustCallSuper</strong>
void handleMemoryPressure() { }
/// Handler called for messages received on the [SystemChannels.system]
/// message channel.
///
/// Other bindings may override this to respond to incoming system messages.
<strong i="29">@protected</strong>
<strong i="30">@mustCallSuper</strong>
Future<void> handleSystemMessage(Object systemMessage) async {
final Map<String, dynamic> message = systemMessage as Map<String, dynamic>;
final String type = message['type'] as String;
switch (type) {
case 'memoryPressure':
handleMemoryPressure();
break;
}
return;
}
/// Adds relevant licenses to the [LicenseRegistry].
///
/// By default, the [ServicesBinding]'s implementation of [initLicenses] adds
/// all the licenses collected by the `flutter` tool during compilation.
<strong i="31">@protected</strong>
<strong i="32">@mustCallSuper</strong>
void initLicenses() {
LicenseRegistry.addLicense(_addLicenses);
}
Stream<LicenseEntry> _addLicenses() async* {
// We use timers here (rather than scheduleTask from the scheduler binding)
// because the services layer can't use the scheduler binding (the scheduler
// binding uses the services layer to manage its lifecycle events). Timers
// are what scheduleTask uses under the hood anyway. The only difference is
// that these will just run next, instead of being prioritized relative to
// the other tasks that might be running. Using _something_ here to break
// this into two parts is important because isolates take a while to copy
// data at the moment, and if we receive the data in the same event loop
// iteration as we send the data to the next isolate, we are definitely
// going to miss frames. Another solution would be to have the work all
// happen in one isolate, and we may go there eventually, but first we are
// going to see if isolate communication can be made cheaper.
// See: https://github.com/dart-lang/sdk/issues/31959
// https://github.com/dart-lang/sdk/issues/31960
// TODO(ianh): Remove this complexity once these bugs are fixed.
final Completer<String> rawLicenses = Completer<String>();
scheduleTask(() async {
rawLicenses.complete(await rootBundle.loadString('NOTICES', cache: false));
}, Priority.animation);
await rawLicenses.future;
final Completer<List<LicenseEntry>> parsedLicenses = Completer<List<LicenseEntry>>();
scheduleTask(() async {
parsedLicenses.complete(compute(_parseLicenses, await rawLicenses.future, debugLabel: 'parseLicenses'));
}, Priority.animation);
await parsedLicenses.future;
yield* Stream<LicenseEntry>.fromIterable(await parsedLicenses.future);
}
// This is run in another isolate created by _addLicenses above.
static List<LicenseEntry> _parseLicenses(String rawLicenses) {
final String _licenseSeparator = '\n' + ('-' * 80) + '\n';
final List<LicenseEntry> result = <LicenseEntry>[];
final List<String> licenses = rawLicenses.split(_licenseSeparator);
for (final String license in licenses) {
final int split = license.indexOf('\n\n');
if (split >= 0) {
result.add(LicenseEntryWithLineBreaks(
license.substring(0, split).split('\n'),
license.substring(split + 2),
));
} else {
result.add(LicenseEntryWithLineBreaks(const <String>[], license));
}
}
return result;
}
<strong i="33">@override</strong>
void initServiceExtensions() {
super.initServiceExtensions();
assert(() {
registerStringServiceExtension(
// ext.flutter.evict value=foo.png will cause foo.png to be evicted from
// the rootBundle cache and cause the entire image cache to be cleared.
// This is used by hot reload mode to clear out the cache of resources
// that have changed.
name: 'evict',
getter: () async => '',
setter: (String value) async {
evict(value);
},
);
return true;
}());
}
/// Called in response to the `ext.flutter.evict` service extension.
///
/// This is used by the `flutter` tool during hot reload so that any images
/// that have changed on disk get cleared from caches.
<strong i="34">@protected</strong>
<strong i="35">@mustCallSuper</strong>
void evict(String asset) {
rootBundle.evict(asset);
}
Future<Isolate> spawnIsolate<T>(
FutureOr<void> entryPoint(T message),
T message, {
bool paused = false,
bool errorsAreFatal,
SendPort onExit,
SendPort onError,
String debugName,
}) {
assert(
_isMainIsolate,
'Can\'t make multiple levels of isolates',
);
final RawReceivePort messageReceiver = RawReceivePort(
(Object receivedMessage) async {
if (receivedMessage is SendPort) {
receivedMessage.send(
_IsolateStarter<T>(
ui.PluginUtilities.getCallbackHandle(entryPoint),
message,
),
);
} else if (receivedMessage is _Message) {
final ByteData result = await defaultBinaryMessenger.send(
receivedMessage.channel,
receivedMessage.message,
);
receivedMessage.sendPort.send(result);
}
},
);
RawReceivePort onExitReceiver;
onExitReceiver = RawReceivePort(
(Object message) {
onExit?.send(message);
onExitReceiver.close();
messageReceiver.close();
},
);
return Isolate.spawn(
_startIsolate,
messageReceiver.sendPort,
paused: paused,
errorsAreFatal: true,
onExit: onExitReceiver.sendPort,
onError: onError,
debugName: debugName,
);
}
// App life cycle
/// Initializes the [lifecycleState] with the [Window.initialLifecycleState]
/// from the window.
///
/// Once the [lifecycleState] is populated through any means (including this
/// method), this method will do nothing. This is because the
/// [Window.initialLifecycleState] may already be stale and it no longer makes
/// sense to use the initial state at dart vm startup as the current state
/// anymore.
///
/// The latest state should be obtained by subscribing to
/// [WidgetsBindingObserver.didChangeAppLifecycleState].
<strong i="36">@protected</strong>
void readInitialLifecycleStateFromNativeWindow() {
if (lifecycleState != null) {
return;
}
final AppLifecycleState state = _parseAppLifecycleMessage(window.initialLifecycleState);
if (state != null) {
handleAppLifecycleStateChanged(state);
}
}
Future<String> _handleLifecycleMessage(String message) async {
handleAppLifecycleStateChanged(_parseAppLifecycleMessage(message));
return null;
}
static AppLifecycleState _parseAppLifecycleMessage(String message) {
switch (message) {
case 'AppLifecycleState.paused':
return AppLifecycleState.paused;
case 'AppLifecycleState.resumed':
return AppLifecycleState.resumed;
case 'AppLifecycleState.inactive':
return AppLifecycleState.inactive;
case 'AppLifecycleState.detached':
return AppLifecycleState.detached;
}
return null;
}
/// The [RestorationManager] synchronizes the restoration data between
/// engine and framework.
///
/// See the docs for [RestorationManager] for a discussion of restoration
/// state and how it is organized in Flutter.
///
/// To use a different [RestorationManager] subclasses can override
/// [createRestorationManager], which is called to create the instance
/// returned by this getter.
RestorationManager get restorationManager => _restorationManager;
RestorationManager _restorationManager;
/// Creates the [RestorationManager] instance available via
/// [restorationManager].
///
/// Can be overriden in subclasses to create a different [RestorationManager].
<strong i="37">@protected</strong>
RestorationManager createRestorationManager() {
return RestorationManager();
}
}
Future<void> _startIsolate<T>(SendPort sendPort) async {
_sendPortToMainIsolate = sendPort;
_IsolateBinding();
final Completer<_IsolateStarter<T>> completer =
Completer<_IsolateStarter<T>>();
final RawReceivePort receivePort = RawReceivePort(
(Object isolateStarter) {
assert(isolateStarter is _IsolateStarter<T>);
completer.complete(isolateStarter as _IsolateStarter<T>);
},
);
sendPort.send(receivePort.sendPort);
final _IsolateStarter<T> isolateStarter = await completer.future;
receivePort.close();
final Function function =
ui.PluginUtilities.getCallbackFromHandle(isolateStarter.callbackHandle);
await function(isolateStarter.message);
}
SendPort _sendPortToMainIsolate;
bool get _isMainIsolate => _sendPortToMainIsolate == null;
class _IsolateStarter<T> {
_IsolateStarter(this.callbackHandle, this.message);
final ui.CallbackHandle callbackHandle;
final T message;
}
class _Message {
_Message(
this.channel,
this.message,
this.sendPort,
);
final String channel;
final ByteData message;
final SendPort sendPort;
}
//TODO not working
class _IsolateBinding extends BindingBase with ServicesBinding {}
/// The default implementation of [BinaryMessenger].
///
/// This messenger sends messages from the app-side to the platform-side and
/// dispatches incoming messages from the platform-side to the appropriate
/// handler.
class _DefaultBinaryMessenger extends BinaryMessenger {
const _DefaultBinaryMessenger._();
// Handlers for incoming messages from platform plugins.
// This is static so that this class can have a const constructor.
static final Map<String, MessageHandler> _handlers =
<String, MessageHandler>{};
// Mock handlers that intercept and respond to outgoing messages.
// This is static so that this class can have a const constructor.
static final Map<String, MessageHandler> _mockHandlers =
<String, MessageHandler>{};
Future<ByteData> _sendPlatformMessage(String channel, ByteData message) {
final Completer<ByteData> completer = Completer<ByteData>();
if (_isMainIsolate) {
// ui.window is accessed directly instead of using ServicesBinding.instance.window
// because this method might be invoked before any binding is initialized.
// This issue was reported in #27541. It is not ideal to statically access
// ui.window because the Window may be dependency injected elsewhere with
// a different instance. However, static access at this location seems to be
// the least bad option.
ui.window.sendPlatformMessage(channel, message, (ByteData reply) {
try {
completer.complete(reply);
} catch (exception, stack) {
FlutterError.reportError(FlutterErrorDetails(
exception: exception,
stack: stack,
library: 'services library',
context:
ErrorDescription('during a platform message response callback'),
));
}
});
} else {
RawReceivePort receivePort;
receivePort = RawReceivePort(
(Object message) async {
assert(message is ByteData);
completer.complete(message as ByteData);
receivePort.close();
},
);
_sendPortToMainIsolate.send(
_Message(channel, message, receivePort.sendPort),
);
}
return completer.future;
}
<strong i="38">@override</strong>
Future<void> handlePlatformMessage(
String channel,
ByteData data,
ui.PlatformMessageResponseCallback callback,
) async {
ByteData response;
try {
final MessageHandler handler = _handlers[channel];
if (handler != null) {
response = await handler(data);
} else {
ui.channelBuffers.push(channel, data, callback);
callback = null;
}
} catch (exception, stack) {
FlutterError.reportError(FlutterErrorDetails(
exception: exception,
stack: stack,
library: 'services library',
context: ErrorDescription('during a platform message callback'),
));
} finally {
if (callback != null) {
callback(response);
}
}
}
<strong i="39">@override</strong>
Future<ByteData> send(String channel, ByteData message) {
final MessageHandler handler = _mockHandlers[channel];
if (handler != null)
return handler(message);
return _sendPlatformMessage(channel, message);
}
<strong i="40">@override</strong>
void setMessageHandler(String channel, MessageHandler handler) {
if (handler == null)
_handlers.remove(channel);
else
_handlers[channel] = handler;
ui.channelBuffers.drain(channel, (ByteData data, ui.PlatformMessageResponseCallback callback) async {
await handlePlatformMessage(channel, data, callback);
});
}
<strong i="41">@override</strong>
void setMockMessageHandler(String channel, MessageHandler handler) {
if (handler == null)
_mockHandlers.remove(channel);
else
_mockHandlers[channel] = handler;
}
<strong i="42">@override</strong>
bool checkMessageHandler(String channel, MessageHandler handler) => _handlers[channel] == handler;
<strong i="43">@override</strong>
bool checkMockMessageHandler(String channel, MessageHandler handler) => _mockHandlers[channel] == handler;
}
@๋์ผ๋ฆญ
ํ์ฌ๋ก์๋ flutter๋ฅผ ์
๋ฐ์ดํธํ ์ ์์ต๋๋ค.
์ flutter ํ์์ ๊ตฌํํ ๋ค๋ฅธ flutter ๋๊ตฌ(์: devtools)๊ฐ ์ด ์ฐจ๋จ๊ธฐ๋ฅผ ์น์ง ์์๋์ง ๊ถ๊ธํฉ๋๋ค.
๊ทธ๋ค์ ๊ทธ๋ค์ ์ํด ์ฐจ๋จ๋์์ ๋๋ง ๋ฒ๊ทธ๋ฅผ ์์ ํ๋ ๊ฒ์ฒ๋ผ ๋ณด์
๋๋ค.
์ด๊ฒ์ ์ฌ๊ฐํ ์ ๊ธฐ๋ฅ์ด ์๋๋ผ ํ๋ ์์ํฌ ์ฐจ๋จ๊ธฐ์
๋๋ค.
๋ฐ๋ผ์ https://github.com/flutter/flutter/issues/18761#issuecomment -639248761์ ๋ฐ๋ฅด๋ฉด P3์ฌ์ผ ํฉ๋๋ค.
์ flutter ํ์์ ๊ตฌํํ ๋ค๋ฅธ flutter ๋๊ตฌ(์: devtools)๊ฐ ์ด ์ฐจ๋จ๊ธฐ๋ฅผ ์น์ง ์์๋์ง ๊ถ๊ธํฉ๋๋ค.
๊ทธ๋ค์ ๊ทธ๋ค์ ์ํด ์ฐจ๋จ๋์์ ๋๋ง ๋ฒ๊ทธ๋ฅผ ์์ ํ๋ ๊ฒ์ฒ๋ผ ๋ณด์ ๋๋ค.
์์งํ ๋งํด์ ์ด ๋ฌธ์ ๊ฐ ์ค์ ์ฑ์ ๋ฏธ์น๋ ์ํฅ์ด ๊ณผ๋ํ๊ฐ๋์๋ค๊ณ ์๊ฐํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ๋ฌธ์ ๊ฐ ๋ ์ฌ์์ง๊ธฐ ๋๋ฌธ์ ์ง์ผ๋ณด๊ณ ์๋ ์ค์ด์ง๋ง "ํด๊ฒฐ ๋ฐฉ๋ฒ"์ด ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ํ๋ก๋์ ์ ๋ง์ ์ฑ๊ณผ ํ๋ฌ๊ทธ์ธ์ ๋ฐฑ๊ทธ๋ผ์ด๋ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
+1 ์ค ์ผ๋ถ๊ฐ ๋ฌธ์ ๊ฐ ๋ฌด์์ธ์ง ์ ์ดํดํ์ง ๋ชปํ๋์ง ํ์คํ์ง ์์ต๋๋ค. (์: https://github.com/flutter/flutter/issues/13937#issuecomment-635683123 ). Imo ๋ฐฑ๊ทธ๋ผ์ด๋ ๊ฒฉ๋ฆฌ ๋ฐ ํค๋๋ฆฌ์ค ๋ฐํ์(๋ฐ ๊ด๋ฆฌ ๋ฐฉ๋ฒ)์ ๋ํ ๊ณต์ ๋ฌธ์๋ ์ฌ์ ํ ์ฝ๊ฐ ๋ถ์กฑํ๊ณ Firebase ๋ฉ์์ง ํญ๋ชฉ์ ์ ๋ชฝ์ด์ง๋ง ํ๋ ์์ํฌ, ์์ง๊ณผ ๊ด๋ จ์ด ์์ต๋๋ค ๐คทโโ๏ธ
๊ทธ๋ฅ ํ๋ฌํฐ ํ ์์ข ๊ทธ๋งํ๊ณ , ๋๋ผ์ด ์ง์ ์ด ์๊ณ , ์ด๊ฑด ๋์ดํฌ ์ ์๋ ์ผ์ด ์๋๋๋ค... ๊ทธ๋ฆฌ๊ณ PR์ด ์๋ค๋ฉด ํ๋ฌํฐ ํ์ด ๊ณ ๋ คํ ์ ์๋๋ก ์ ์ถํ๋ ๊ฒ์ด ์ด๋จ๊น์ ๐ค
๊ฒฉ๋ฆฌ์ ๋ํด ์ด ๋์์ ๊ตฌํํ๋ ๋ฐ ๋ฌธ์ ๊ฐ ์์ต๋๋ค.
์์:
๋ฉ์ธ ์์ด์๋ ์ดํธ์ ์์ง์ด ์์ต๋๋ค.
๊ฒฉ๋ฆฌ์ ํ์ํ ๊ฒ์ด ์์ผ๋ฉด ์์ง์ ์์ฒญํฉ๋๋ค.
์์ง์ ํ์ํ ๊ฒ์ด ์์ผ๋ฉด ๊ฒฉ๋ฆฌ๋ฅผ ์์ฒญํฉ๋๋ค.
์ด์ ์ฐ๋ฆฌ์ ์ํฉ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
2๊ฐ์ ๊ฒฉ๋ฆฌ ์ฅ์น์ ์์ง์ด ์์ต๋๋ค.
๊ฒฉ๋ฆฌ์ ํ์ํ ๊ฒ์ด ์์ผ๋ฉด ์์ง์ ์์ฒญํฉ๋๋ค.
์์ง์ ๋ฌด์ธ๊ฐ๊ฐ ํ์ํ ๊ฒฝ์ฐ ์ด๋ป๊ฒ ํด์ผ ํฉ๋๊น?
๋ ๋ค ๋ฌผ์ด? ๊ทธ๋ฌ๋ฉด ๋๊ตฌ์ ๋๋ต์ ์ทจํด์ผ ํ ๊น์?
์๋๋ฉด ํ๋์ ๋ถ๋ฆฌ๋ฌผ๋ง ์์ฒญํ์๊ฒ ์ต๋๊น? ๊ทธ๋ผ ์ด๋ ์ชฝ?
@hpoul ์ฌ๊ธฐ์ ์๋ ๋ง์ ์ฌ๋๋ค์ด Android/ios ํ๋ก๊ทธ๋๋ฐ์ ์ด๋ณด์์ด๊ณ ์ฑ ๊ฐ๋ฐ์ ์ํ ์ฒซ ๋ฒ์งธ ํ๋ ์์ํฌ๋ฅผ ์ ํํ๊ธฐ ๋๋ฌธ์ ๋์ํด์ผ ํฉ๋๋ค.
๋ฐ๋ผ์ ๋๊ตฐ๊ฐ๊ฐ ์ด๊ฒ์ ๊นจ๋ซ๊ณ ํ๋ ์์ํฌ์ ์ํด ์ฐจ๋จ๋๊ณ ๊ฐ์ ๋ก ๋ณต์กํ "ํด๊ฒฐ ๋ฐฉ๋ฒ"์ ์ํํด์ผ ํ๋ ์ด๋ฌํ ์ข ๋ฅ์ ๋ฌธ์ ์ ๋ํ ์๋ฅผ ํตํด ๊ณต์ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์์ ํ๊ฑฐ๋ ์ ์ํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ์ฌ๊ธฐ๋ stackoverflow ๋๋ ๋ค๋ฅธ ๋ธ๋ก๊ทธ์ ์ฃผ์์ ์ ์ค๋ช ๋ ํด๊ฒฐ ๋ฐฉ๋ฒ์ด ์๊ธฐ ๋๋ฌธ์ ์ด๋์๋ถํฐ ์์ํด์ผ ํ ๊น์? ์ด๊ฒ์ ์ฌ๋ฐ๋ฅด๊ฒ ๊ตฌํํ๊ฑฐ๋ ๊ตฌํํ์ง ์์์ ์ ์๋ ์ผ๋ถ ํจํค์ง๋ฅผ ๊ฐ๋ฆฌํค๋ ํญ๋ชฉ๋ง ์์ต๋๋ค.
Android์ ios ๋ชจ๋ ์์ ์๋น์ค, ๋ฐฑ๊ทธ๋ผ์ด๋ ์์ ๋๊ธฐ์ด ๋ฑ์ผ๋ก ์์ ํ ๊ฒฝํ์ด ๋ง๊ณ ์ด ๋ฌธ์ ๋ฅผ ์ฝ๊ฒ ํด๊ฒฐํ ์ ์๋ ์ฌ๋๋ค์ flutter์ ๋์ ์ธ๊ตฌ ํต๊ณ๊ฐ ์๋๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋ค๋ฅธ ๋ชจ๋ ๋ฌธ์ ์๋ ์๋ชป๋ +1์ด ์๋ค๊ณ ํ์ ํฉ๋๋ค. ์ด๋ ๋ฌธ์ ์ฐ์ ์์์ ์์๋ฅผ ํฌ๊ฒ ๋ณ๊ฒฝํ์ง ์์ผ๋ฉฐ ์ด ๋ฌธ์ ๋ ์ฌ์ ํ ๋งจ ์์ ์์ต๋๋ค.
์๋ ํ์ธ์ @phanirithvij
flutter_isolate๋ ์์ ๋งํฌ๋์์ผ๋ฉฐ 2019๋ 2์๋ถํฐ ์ฌ์ฉ๋์์ต๋๋ค. ๋ํ ๋ณต์กํ์ง ์์ต๋๋ค. ๊ฐ๋จํด ๋ณด์ด๋ README๋ฅผ ๋ณต์ฌํ๊ฒ ์ต๋๋ค.
FlutterIsolate๋ฅผ ์ฌ์ฉํ๋ฉด ํ๋ฌํฐ ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉํ ์ ์๋ ํ๋ฌํฐ์์ ๊ฒฉ๋ฆฌ๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. ํ๋ซํผ ์ฑ๋์ด ๊ฒฉ๋ฆฌ ๋ด์์ ์๋ํ ์ ์๋๋ก ํ์ํ ํ๋ซํผ๋ณ ๋นํธ(Android์ FlutterBackgroundView ๋ฐ iOS์ FlutterEngine)๋ฅผ ์์ฑํฉ๋๋ค.
| | ์๋๋ก์ด๋ | iOS | ์ค๋ช |
| :-------------------- | :----------------: | :--------------------------------: | :-------------------------------- |
| FlutterIsolate.spawn(entryPoint, ๋ฉ์์ง) | :white_check_mark: | :white_check_mark: | ์๋ก์ด FlutterIsolate ์์ฑ |
| flutterIsolate.pause() | :white_check_mark: | :white_check_mark: | ์คํ ์ค์ธ ๊ฒฉ๋ฆฌ๋ฅผ ์ผ์ ์ค์ง |
| flutterIsolate.resume() | :white_check_mark: | :white_check_mark: | ์ผ์ ์ค์ง isoalte ์ฌ๊ฐ |
| flutterIsolate.kill() | :white_check_mark: | :white_check_mark: | ๊ฒฉ๋ฆฌ๋ฅผ ์ฃฝ์ธ๋ค |
์ด ๋ฉ์๋๋ "์๋" Isolate
ํด๋์ค์ ๋ฉ์๋์ ์ด๋ฆ์ด ๊ฐ๊ธฐ ๋๋ฌธ์ ๊ฐ๋จํฉ๋๋ค. ๋ฐ๋ผ์ ๊ณต์ ๋ฌธ์์์ ๊ฒฉ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์ด๋ฏธ ์๊ณ ์๋ค๋ฉด ์ฌ์ฉ๋ฒ์ ์ดํดํ๋ ๊ฒ์ด ์ด๋ ต์ง ์์ ๊ฒ์
๋๋ค. ์ด๊ฒ์ ์ ์ด๋ ์์ ๋์ด๋ ๋ฐฉ๋ฒ์ ๋ํ ๋๋กญ ์ธ ๋์ฒด์
๋๋ค.
(์ฐธ๊ณ : ์ ์ญ์ ์ด์ ์๊ฒฌ์์ ์ด๋ฏธ ์ธ๊ธํ ์ด์ ๋ก ์ด ๋ฌธ์ ๋ฅผ ๊ณต์์ ์ผ๋ก ์์ ํ๊ณ ์ถ์ต๋๋ค. ๊ทธ ์ค ์ผ๋ถ๋ ์ฌ๋ฌ๋ถ๊ณผ ๊ณต์ ํ์ง๋ง ์ด ํด๊ฒฐ ๋ฐฉ๋ฒ์ "๋ณต์กํจ"์ด๋ผ๊ณ ๋ถ๋ฅด์ง๋ ์์ต๋๋ค.)
@nikitadol ์ ์๊ฒฌ์ ๋ํ ์๋ต์ผ๋ก flutter_isolate๋ ๋์ผํ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ง ์๋๋ก ๊ฐ ๊ฒฉ๋ฆฌ์ ๋ํด ๋ณ๋์ ์์ง์ ์์ฑํฉ๋๋ค. ๋ฌผ๋ก , ๋ถ๋ฆฌ๋ง๋ค ์๋ก์ด ์์ง์ ์์ฑํด์ผ ํ๋ ๊ฒ์ ์ด์์ ์ด์ง ์์ต๋๋ค. ์ด๊ฒ์ด Flutter ํ์ด ๋ ๋์ ์์ ์ ์ํํ ์ ์๋ค๊ณ ํ์ ํ๋ ์ด์ ์ค ํ๋์ ๋๋ค. ๋ง์ฐฌ๊ฐ์ง๋ก ๊ธฐ๋ณธ ๊ฒฉ๋ฆฌ๋ฅผ ํตํด ๋ชจ๋ ํ๋ฌ๊ทธ์ธ ๋ฉ์๋ ํธ์ถ์ ํ์ดํํ๋ ๋์ฒด ์๋ฃจ์ ์ ์ ์ด์ ๊ฒฉ๋ฆฌ์ ๋ชฉํ์ ๋ฐ๋๋๋ ๋ณ๋ชฉ ํ์์ ์์ฑํ๋ฏ๋ก Flutter ํ๋ ์ด ์์ ์ ๋ ์ ์ํํ ์ ์์ ๊ฒ์ด๋ผ๊ณ ํ์ ํฉ๋๋ค.
Flutter ํ์ด ๋จผ์ ํด๊ฒฐํด์ผ ํ ๋ ๋์ ์ฐ์ ์์ ๋ฌธ์ ๊ฐ ์์ ์ ์๋ค๊ณ ๋งํ ์ฌ๋๋ค์ ์๊ฒฌ์ ๋์ํ์ง๋ง, ํ๋ฌ๊ทธ์ธ ์ํคํ ์ฒ์์ ์ด์ ์ ๋ณธ ๊ฒ์ ๊ธฐ๋ฐ์ผ๋ก ํ๋ฉด ์ด ๋ฌธ์ ๋ฅผ ์์ ํ๋ ค๋ฉด ์ฃผ์ ์ํคํ ์ฒ ๋ณ๊ฒฝ ๋ฐ ๊ธฐํ ๋ช ๊ฐ์ง ๋ฏธํด๊ฒฐ ๋ฌธ์ ๊ฐ ํ์ํ ์๋ ์์ต๋๋ค. ๋ํ ์ฃผ์ ์ํคํ ์ฒ ๋ณ๊ฒฝ์ด ํ์ํ๋ฉฐ ์ด๋ฌํ ๋ชจ๋ ์๊ตฌ ์ฌํญ์ ํ๊ฐํ๋ ๋ฐ๋ ์ด ํน์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ๊น์ง ์๊ฐ์ด ๊ฑธ๋ฆด ์ ์์ต๋๋ค.
@ryanheise
flutter_isolate๋ ๊ฐ ๊ฒฉ๋ฆฌ์ ๋ํด ๋ณ๋์ ์์ง์ ๋ง๋ญ๋๋ค.
๊ทธ๋์ ์ ๋ Flutter ํ๋ ๊ทธ ์ผ์ ๋ ์ ํ ์ ์๋ค๊ณ ํ์ ํฉ๋๋ค.
Flutter ํ์ด ์ด๊ฒ์ ํ ์ ์๋ค๊ณ ๋งํ์ง๋ง ์ด๋ป๊ฒ?
์์์ ์ง๋ฌธํ ๋ด์ฉ์ ์ ํจํฉ๋๋ค.
์๋ฃจ์
์ด ์ ์์ง์ ๋ง๋๋ ๊ฒ์ด๋ผ๋ฉด ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
(์ฐธ๊ณ ๋ก flutter_isolate๋ ๋ด ํ๋ฌ๊ทธ์ธ์ด ์๋์ง๋ง ์ด ๊ธฐ๋ฅ๋ ํ์ํ๊ธฐ ๋๋ฌธ์ ํ๋ก์ ํธ์ ๊ธฐ์ฌํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค.)
"๋ ๋์ ์์ "์ด ์๋ฏธํ๋ ๋ฐ๋ ํ๋ฌ๊ทธ์ธ๊ณผ ํต์ ํ๊ธฐ ์ํด FlutterEngine์ ๋ชจ๋ ๊ธฐ๊ณ๋ฅผ ๊ฐ๋ํ ํ์๋ ์์ง๋ง ํ์ฌ ํ์ํ ์ธํ๋ผ๊ฐ ๋ชจ๋ ์์ง์ ์ฐ๊ฒฐ๋์ด ์์ผ๋ฏ๋ก ํ์ฌ flutter_isolate๋ ํ๋ฌ๊ทธ์ธ์ ์ก์ธ์คํ๊ธฐ ์ํด ์ ์ฒด ์์ง์ ๊ฐ๋ํด์ผ ํฉ๋๋ค.
(์ฐธ๊ณ ๋ก flutter_isolate๋ ๋ด ํ๋ฌ๊ทธ์ธ์ด ์๋์ง๋ง ์ด ๊ธฐ๋ฅ๋ ํ์ํ๊ธฐ ๋๋ฌธ์ ํ๋ก์ ํธ์ ๊ธฐ์ฌํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค.)
์ฃ์กํฉ๋๋ค. ์ด๊ฒ์ด ํฌํฌ์ธ ์ค ๋ชฐ๋์ต๋๋ค.
flutter_isolate๋ ํ๋ฌ๊ทธ์ธ์ ์ก์ธ์คํ๊ธฐ ์ํด ์ ์ฒด ์์ง์ ๊ฐ๋ํด์ผ ํฉ๋๋ค.
'is_background_view = true'๋ก ์ง์ ํ๋ฉด ์์ง์ด ๋ ๋๋ง์ ์์ํ์ง ์์ต๋๋ค. ์ฆ, ์์ง์ด ์์ ํ ์์๋์ง ์์ต๋๋ค.
ํค๋๋ฆฌ์ค ์คํ์ ์ํ ์ ํํ API๋ iOS, Android v1 ๋ฐ Android v2์์ ๋ค๋ฅด์ง๋ง ๋ณธ์ง์ ์ผ๋ก ์ด๊ฒ์ด flutter_isolate๊ฐ ์ด๋ฏธ ํ๋ ์ผ์ ๋๋ค. ์ผ๋ฐ ๊ฒฉ๋ฆฌ์ FlutterEngine ์ฌ์ด์๋ ์ฌ์ ํ ์ค๋ฒํค๋์ ์ฐจ์ด๊ฐ ์์ผ๋ฏ๋ก ์ค๋ฒํค๋๋ฅผ ๋ ๋ฎ์ถ๋ ๊ฒ์ Flutter ํ์ด ํ ์ ์๋ ์ ์ผํ ๊ฒ์ ๋๋ค. ์์ ์๊ฐ์ ์ค๋ฒํค๋์ผ ๋ฟ๋ง ์๋๋ผ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ์ ์ค๋ฒํค๋์ด๊ธฐ๋ ํฉ๋๋ค.
๊ทธ๋์ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ์๋ํ๋๋ก ์ ์์ง ์์ฑ์ ์ต์ ํํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
๊ทธ๋ ๋ค๋ฉด ์ด๊ฒ์ ์๋ง๋ ์ด ๋ฌธ์ ์ ์ ์ฉ๋์ง ์์ ๊ฒ์ ๋๋ค
๋๋ ๊ทธ๊ฒ์ ์ ์ํ๋ ๊ฒ์ด ์๋๋ผ, ๋จ์ง flutter_isolate ํด๊ฒฐ ๋ฐฉ๋ฒ์ด ํผํ ์ ์๋ ์ค๋ฒํค๋ ๋๋ฌธ์ ์ด ์ ํ์ด ์์์ ์ง์ ํ๋ ๊ฒ์ ๋๋ค. Flutter ํ์ด ํด๊ฒฐ ๋ฐฉ๋ฒ์ ๋ ํจ์จ์ ์ผ๋ก ๋ง๋ค์ด์ผ ํ๋ค๊ณ ์ ์ํ๋ ๊ฒ์ ์๋๋๋ค. ์ด์์ ์ผ๋ก๋ FlutterEngine์ ์ธ์คํด์คํํ ํ์๊ฐ ์๋๋ก ํ๋ฌ๊ทธ์ธ์ด ๋ก๋๋๋ ๋ฐฉ์์ ์ํคํ ์ฒ ๋ณ๊ฒฝ์ด ์์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
์์ง์ด 1์ด๊ณ ๊ฒฉ๋ฆฌ๊ฐ 1๋ณด๋ค ํฌ๋ฉด ์ด ์ง๋ฌธ์ผ๋ก ๋์๊ฐ๋๋ค.
https://github.com/flutter/flutter/issues/13937#issuecomment -667314232
์ด ์๋ก์ด ๊ฒฝ๋ ์ํคํ ์ฒ์ ๋ํ ์๋ฃจ์ ์ ์ค์ ๋ก ์๊ฐํด๋ด๋ ค๊ณ ํ๋ ๊ฒ์ ์๋์ง๋ง ์ ์๊ฒ ๋ฌป๋๋ค๋ฉด ๊ฒฝ๋ ์๋ฃจ์ ์ ๋ ๊ฐ์ง ๋ณํ์ ์๊ฐํ ์ ์์ต๋๋ค.
๋น์ ์ด ๋์๊ฒ ๋ฌป๋๋ค๋ฉด
์, ๋ฌป์ต๋๋ค
์ฌ๋ฐ๋ฅธ ๊ฒฉ๋ฆฌ์ ๋ฉ์์ง๋ฅผ ๋ณด๋ผ ์ ์์ต๋๋ค.
'์ฌ๋ฐ๋ฅธ ๋ถ๋ฆฌ'๊ฐ ์๋์ ์ธ ๊ฐ๋ ์ด๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ด ๋์ ํด๊ฒฐ์ฑ ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
๋์ผํ FlutterEngine ๋ด์์ ๋ถ๋ฆฌํ์ง๋ง ๊ฐ๊ฐ์ ๋ํด ์ ํ๋ฌ๊ทธ์ธ ๋ ์ง์คํธ๋ฆฌ ๋ฑ์ ์์ฑํฉ๋๋ค.
์ด๊ฒ์ ์ข์ ์ต์ ์ด ๋ ์ ์์ง๋ง ์์ง์ด ํญ์ ์์ฒด์ ์ผ๋ก ํ๋ฌ๊ทธ์ธ์ ๋ฑ๋กํ๋ ๊ฒฝ์ฐ์๋ง ๊ฐ๋ฅํฉ๋๋ค.
๊ทธ๋ฌ๋ ์ด๊ฒ์ GeneratedPluginRegistrant์ ๋ชจ๋ ํ๋ฌ๊ทธ์ธ์ด ์๋ ๊ฒฝ์ฐ์๋ง ๋ฐ์ํฉ๋๋ค.
https://github.com/flutter/engine/blob/f7d241fd8a889fadf8ab3f9d57918be3d986b4be/shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java#L330 -L344
์ถ๊ฐ ์ฝ๋ฐฑ์ ๋ง๋๋ ๊ฒ์ ๋ช ๋ฐฑํ ๋์์ด ์๋๋๋ค.
'์ฌ๋ฐ๋ฅธ ๋ถ๋ฆฌ'๊ฐ ์๋์ ์ธ ๊ฐ๋ ์ด๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ด ๋์ ํด๊ฒฐ์ฑ ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
๋์ ํด๊ฒฐ์ฑ ์ด ๋ ์ ์์ง๋ง ๊ทธ๋ฐ ์ด์ ๋ก ๋์์ง๋ ์์ต๋๋ค. "์ฌ๋ฐ๋ฅธ ๋ถ๋ฆฌ"๋ ์๋ฒ ์์ผ์ด ๋ช ํํ ๋ฐฉ์์ผ๋ก ํด๋ผ์ด์ธํธ ์ฐ๊ฒฐ์ ์ฒ๋ฆฌํ๋ ๊ฒ๊ณผ ๊ฐ์ ๋ฐฉ์์ผ๋ก ๋ชจํธํ์ง ์์ต๋๋ค.
์ด๊ฒ์ ์ข์ ์ต์ ์ด ๋ ์ ์์ง๋ง ์์ง์ด ํญ์ ์์ฒด์ ์ผ๋ก ํ๋ฌ๊ทธ์ธ์ ๋ฑ๋กํ๋ ๊ฒฝ์ฐ์๋ง ๊ฐ๋ฅํฉ๋๋ค.
ํญ์ ๋ฐ์ํ๋๋ก ํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ํ์ฌ ๋ฉ์ปค๋์ฆ์ด ์ฝ๊ฐ ๋ถ์์ ํฉ๋๋ค.
๋์ ํด๊ฒฐ์ฑ ์ด ๋ ์ ์์ง๋ง ๊ทธ๋ฐ ์ด์ ๋ก ๋์์ง๋ ์์ต๋๋ค. "์ฌ๋ฐ๋ฅธ ๋ถ๋ฆฌ"๋ ์๋ฒ ์์ผ์ด ๋ช ํํ ๋ฐฉ์์ผ๋ก ํด๋ผ์ด์ธํธ ์ฐ๊ฒฐ์ ์ฒ๋ฆฌํ๋ ๊ฒ๊ณผ ๊ฐ์ ๋ฐฉ์์ผ๋ก ๋ชจํธํ์ง ์์ต๋๋ค.
๊ทธ๋ฐ ๋ค์ ๊ฐ ํ๋ฌ๊ทธ์ธ์ ์๋ก ๋ค๋ฅธ ๊ฒฉ๋ฆฌ์์ ์ก์ธ์คํ ์ ์๋ค๋ ์ ์ ๊ณ ๋ คํด์ผ ํฉ๋๋ค.
๋ค.
์ด ํ ๋ก ์ ์ 2์ผํธ๋ฅผ ์ถ๊ฐํ๊ฒ ์ต๋๋ค... ์ฝ 2๋ ๋์ Flutter์ ์์ ์ ์ผ๋ก ์ผํ๋ฉด์ ์ ๊ฐ ๋ฐฐ์ด ๊ฐ์ฅ ์ค์ํ ๊ฒ์ Flutter๊ฐ UI ํดํท ์ด๋ผ๋ ๊ฒ์ ๋๋ค. ์ฌ๋๋ค์ด ์ด๊ฒ์ ์์ง ์์๋ค๋ฉด ์ด ์ฑ๋ช ์์๋ ๋๋ผ์ด ๊ฒ์ด ์์์ ๊ฒ์ ๋๋ค. ์ฌ์ง์ด Flutter์ ๋ฉ์ธ ์น์ฌ์ดํธ์๋ ๊ทธ๋ ๊ฒ ๋์ ์์ต๋๋ค.
Flutter๋ UI ํดํท์ด๋ฉฐ ์ํ๋ ๊ฒ์ UI์ ๋๋ค. ๊ฐ๋น์ผ ๋ฐ์ดํฐ ์ฒ๋ฆฌ์ ์์กดํ๊ฑฐ๋ ๋ณต์กํ ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ๊ณ ๋ง์ ์์ ๋ฐ์ดํฐ๋ฅผ ์๋นํ๋ CPU๋ฅผ ๋ง์ด ์ฌ์ฉํ๋ ์์ฉ ํ๋ก๊ทธ๋จ์ ๋ง๋ค๋ ค๋ ๊ฒฝ์ฐ ์ด ์ฉ๋๋ก UI ๋๊ตฌ ํคํธ๋ฅผ ์ฌ์ฉํ๋ฉด ์ ๋ฉ๋๋ค. ๋น์ฆ๋์ค ๋ก์ง์ UI์ ํผ์ฉ๋์ด์๋ ์๋ฉ๋๋ค.
๋ฌผ๋ก Dart๋ฅผ ์ฌ์ฉํ๋ฉด UI ์ด์์ ์์ ์ ์ํํ ์ ์์ง๋ง ์ด ํดํท์ ์ฃผ์ ๋ชฉ์ ์ ์์ง ๋ง์.
์ ๋ ํค๋๋ฆฌ์ค Flutter๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ํฌํจํ์ฌ ์ฌ๋ฌ ๊ฐ์ง ์ ๊ทผ ๋ฐฉ์์ ์๋ํ์ง๋ง ์์ ํ ์ฌ์์ผ๋ก ํ๋ช ๋์์ต๋๋ค. ์๋ํ์ง ์์์๊ฐ ์๋๋ผ ๋ค๋ฅธ ๊ฐ๋ฐ์์๊ฒ ์๋ ๋ฐฉ์์ ์ค๋ช ํ๋ ๋ฐ ๋ฌธ์ ๊ฐ ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ์ถ๊ฐ๋๋ ์ ์ง ๊ด๋ฆฌ ๋ถ๋ด์ ๊ทธ๋งํ ๊ฐ์น๊ฐ ์์ต๋๋ค. ๊ทธ๋ฌํ ์๋ฃจ์ ์ ํ ์คํธํ๋ ๊ฒ์ ๋งํ ๊ฒ๋ ์์ต๋๋ค. ๋ง์ง๋ง์ผ๋ก ์๋ํ์ ๋ Flutter Driver๋ ์ ํ ์ฒ๋ฆฌํ์ง ๋ชปํ์ต๋๋ค.
์ ํ๋ฆฌ์ผ์ด์ ์ ์ฒ๋ฆฌ ๋ฅ๋ ฅ์ธ IMHO๊ฐ ์ ๋ง๋ก ํ์ํ ๊ฒฝ์ฐ ์ธ ๊ฐ์ง ์ต์ ์ด ์์ต๋๋ค.
์์ ๋ชจ๋ ๊ฒ์๋ ๋จ์ ์ด ์์ง๋ง ์ค์ ๋ก ์ค๊ณ๋์ง ์์ ์์ ์ ์ํํ๊ธฐ ์ํด ๋ผ์ด๋ธ๋ฌ๋ฆฌ/ํ๋ ์์ํฌ๋ฅผ ํ์ฅํ๋ ๊ฒ๋ ์ด์์ ์ด์ง ์์ต๋๋ค.
isolate_handler ๊ฐ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์ง ์์์ต๋๊น?
@hasonguo ๋ฐฑ๊ทธ๋ผ์ด๋์์ flutter_isolate
๋ฅผ ์ฌ์ฉํฉ๋๋ค. ํต์ ์ฉ ์์ฉ๊ตฌ๋ฅผ ์ถ๊ฐํ์ฌ ๋ถ๋ฆฌ(์ค์ ๋ก ๋ชจ๋ ๋ถ๋ฆฌ)๋ฅผ ๋ ์ฝ๊ฒ ์ฒ๋ฆฌํ ์ ์๋๋ก ์ถ๊ฐ ๋ ์ด์ด๋ฅผ ์ถ๊ฐํ๋ฏ๋ก ๋งค๋ฒ ์๋์ผ๋ก ์ค์ ํ ํ์๊ฐ ์์ต๋๋ค. ์๊ฐ. ์ด์ ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ์ง๋ง Flutter ์์ฒด์ ๋ณ๊ฒฝ์ผ๋ก ์ธํด ๋ถ๊ฐ๋ฅํด์ก์ผ๋ฉฐ ๋์ flutter_isolate
์ ์์กดํ๋๋ก ๋ณ๊ฒฝ๋์์ต๋๋ค.
์ฐ๋ฆฌ๋ ์์ ๊ทธ๋ฆฌ๋ฉฐ ๊ฐ๊ณ ์์ต๋๋ค. ์, ์ค์ ๋ก ๋ ํ๋ฌ๊ทธ์ธ ๋ชจ๋ ์๋ฃจ์
์ด ์์ต๋๋ค. Ryan์ด ์ง์ ํ๋ฏ์ด ์ฑ๋ ํต์ ์ ๊ฐ๋ฅํ๊ฒ ํ๋ ๋ฐ ์๋ฐ๋๋ ์ค๋ฒํค๋๊ฐ ์์ต๋๋ค. ๋๋ถ๋ถ์ ๊ฒฝ์ฐ(๋๋ถ๋ถ์) ์ง์์ด ํ์ํ์ง ์๊ธฐ ๋๋ฌธ์ Flutter ํ์ด ์๋ Isolate
์ ์๋์ผ๋ก ์ถ๊ฐํ๋ ๊ฒ์ ํผํ๊ฒ ๋ง๋ ๊ฒ์ ๋ฐ๋ก ์ด ์ค๋ฒํค๋์
๋๋ค.
๊ทธ๋ฌ๋ ์ป์ ์ ์๋ ๊ฒ๋งํผ ๊นจ๋ํ ์๋ฃจ์
์ ์๋๋๋ค. Flutter ํ์ด ๊ธฐ๋ณธ Isolate
์์ผ๋ฉด ๋ฐ๋ก ์๋์ผ๋ก ์ค๋ฒํค๋ ์์ด ์ฑ๋ ์ปค๋ฎค๋์ผ์ด์
์ ์ ๊ณตํ ์ ์๋ค๋ฉด ์ ์ฒด ํ ๋ก ์ด ๋ฌด์๋ฏธํด์ง ๊ฒ์
๋๋ค. ๊ทธ๋ฌ๋ ๊ทธ ๋ฐ๋๋ ๋ง์ฐฌ๊ฐ์ง์
๋๋ค. ๊ทธ๋ค์ ์ค์ ๋ก ๋ณํ๋ฅผ ์ํ ๋ณํ๋ฅผ ์ถ๊ตฌํ์ง ์์ต๋๋ค. ํจํค์ง๋ ํ๋ฌ๊ทธ์ธ์ ์คํ ๊ฐ๋ฅํ ์๋ฃจ์
์ด ์๋ค๋ฉด ์ ์๊ฐ์ ๋ค์ฌ ์ฝ์ด์ ๋ฌด๊ฒ๋ฅผ ๋ํ ๊น์?
๋์ผํ FlutterEngine ๋ด์์ ๋ถ๋ฆฌํ์ง๋ง ๊ฐ๊ฐ์ ๋ํด ์ ํ๋ฌ๊ทธ์ธ ๋ ์ง์คํธ๋ฆฌ ๋ฑ์ ์์ฑํฉ๋๋ค.
์ด๊ฒ์ ์ข์ ์ต์ ์ด ๋ ์ ์์ง๋ง ์์ง์ด ํญ์ ์์ฒด์ ์ผ๋ก ํ๋ฌ๊ทธ์ธ์ ๋ฑ๋กํ๋ ๊ฒฝ์ฐ์๋ง ๊ฐ๋ฅํฉ๋๋ค.
๊ทธ๋ฌ๋ ์ด๊ฒ์ GeneratedPluginRegistrant์ ๋ชจ๋ ํ๋ฌ๊ทธ์ธ์ด ์๋ ๊ฒฝ์ฐ์๋ง ๋ฐ์ํฉ๋๋ค.
https://github.com/flutter/engine/blob/f7d241fd8a889fadf8ab3f9d57918be3d986b4be/shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java#L330 -L344์ถ๊ฐ ์ฝ๋ฐฑ์ ๋ง๋๋ ๊ฒ์ ๋ช ๋ฐฑํ ๋์์ด ์๋๋๋ค.
์ด ๋ ๋ฒ์งธ ์์ด๋์ด์ ๋ํ ๋ ๋ค๋ฅธ ๊ฐ์ ์ฌํญ์ ํ๋ฌ๊ทธ์ธ์ ์ ๊ฒฉ๋ฆฌ์์ ๋๋ฆฌ๊ฒ ๋ก๋ํ๋๋ก ํ๋ ๊ฒ์
๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ํ๋ก์ ํธ๊ฐ ๋ง์ ํ๋ฌ๊ทธ์ธ์ ์์กดํ๋ ๊ฒฝ์ฐ GeneratedPluginRegistrant
๋ ์๋นํ ํฌ๋ฉฐ ํ๋ฌ๊ทธ์ธ์ ์ด๊ธฐํ ๋ฃจํด์ด ์ผ๋ง๋ ํจ์จ์ ์ธ์ง์ ๋ฐ๋ผ ์ค๋ฒํค๋๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ์ด๊ฒ์ ์ ํํ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ๋ ๋ค๋ฅธ ์ด์ผ๊ธฐ์
๋๋ค. ํ๋ซํผ ์ฑ๋์ ํ๋ฌ๊ทธ์ธ์ด ์์ ํ์ง ์์ผ๋ฏ๋ก ํ์ฌ ์ฑ๋์ ํตํด ๋ฉ์์ง๋ฅผ ๋ณด๋ด๋ ๊ฒ์ ํ๋ฌ๊ทธ์ธ์ ํ๋ซํผ ์ธก์ด ์ธ์คํด์คํ๋๋๋ก ํธ๋ฆฌ๊ฑฐํ๋ ๋ฐ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ ๋ ๋ฉ์๋ ์ฑ๋ ์ค ํ๋๋ ํ๋ฌ๊ทธ์ธ๊ณผ ์ฐ๊ฒฐ๋์ด์ผ ํ๊ฑฐ๋ ํ๋ฌ๊ทธ์ธ์ Dart ์ธก์ด ์ฒซ ๋ฒ์งธ ๋ฉ์๋ ์ฑ๋์ด ์์ฑ๋๊ธฐ ์ ์ ์ง์ฐ ์์ฒด๋ฅผ ์ด๊ธฐํํ๊ธฐ ์ํด ํธ์ถํ ์ ์๋ ์ถ๊ฐ ๋ฉ์ปค๋์ฆ์ด ํ์ํ๊ณ ํด๋น ๋ฉ์ปค๋์ฆ์ด ์ธ์คํด์คํ๋ฅผ ํธ๋ฆฌ๊ฑฐํ ์ ์์ต๋๋ค. ๊ฒฉ๋ฆฌ ๋ด์์ ํด๋น ํ๋ฌ๊ทธ์ธ์ ํ๋ซํผ ์ธก.
@TahaTesser
๊ทํ์ ์์์ ์ค๋ฅ๋ ์ด ๋ฌธ์ ์ ๊ด๋ จ์ด ์์ต๋๋ค.
E/flutter ( 7814): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: Invalid argument(s): Isolate.spawn expects to be passed a static or top-level function
์๋
ํ์ธ์ @nikitadol
๊ฐ์ฌํฉ๋๋ค. ์
๋ฐ์ดํธ๋ ์์์๋ ์์ธ๊ฐ ๋ฐ์ํ์ง ์์ต๋๋ค. ๋ง๋์? (์ด์ ์๋ ์ฌ์ฉํ ํ์๊ฐ ์์์ต๋๋ค)
์๋ฒฝํ๊ฒ ์ฌํ ๊ฐ๋ฅํ ์ต์ ์ฝ๋ ์ํ์ ์ ๊ณตํ ์ ์์ต๋๊น?
๊ฐ์ฌํฉ๋๋ค
@TahaTesser์ฝ๋ ์ํ
import 'package:battery/battery.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
Future<void> main() async {
await printBatteryLevel();
await compute(printBatteryLevel, null);
}
Future<void> printBatteryLevel([dynamic message]) async {
WidgetsFlutterBinding.ensureInitialized();
print(await Battery().batteryLevel);
}
๋ก๊ทธ
Launching lib/main.dart on Pixel 4 in debug mode...
Running Gradle task 'assembleDebug'...
โ Built build/app/outputs/flutter-apk/app-debug.apk.
Installing build/app/outputs/flutter-apk/app.apk...
Waiting for Pixel 4 to report its views...
Debug service listening on ws://127.0.0.1:50709/-SPs_6AmL2Q=/ws
Syncing files to device Pixel 4...
I/flutter ( 8708): 39
E/flutter ( 8708): [ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: Exception: UI actions are only available on root isolate.
E/flutter ( 8708): #0 Window._nativeSetNeedsReportTimings (dart:ui/window.dart:1003:86)
E/flutter ( 8708): #1 Window.onReportTimings= (dart:ui/window.dart:996:29)
E/flutter ( 8708): #2 SchedulerBinding.addTimingsCallback (package:flutter/src/scheduler/binding.dart:272:14)
E/flutter ( 8708): #3 SchedulerBinding.initInstances (package:flutter/src/scheduler/binding.dart:209:7)
E/flutter ( 8708): #4 ServicesBinding.initInstances (package:flutter/src/services/binding.dart:27:11)
E/flutter ( 8708): #5 PaintingBinding.initInstances (package:flutter/src/painting/binding.dart:23:11)
E/flutter ( 8708): #6 SemanticsBinding.initInstances (package:flutter/src/semantics/binding.dart:24:11)
E/flutter ( 8708): #7 RendererBinding.initInstances (package:flutter/src/rendering/binding.dart:32:11)
E/flutter ( 8708): #8 WidgetsBinding.initInstances (package:flutter/src/widgets/binding.dart:257:11)
E/flutter ( 8708): #9 new BindingBase (package:flutter/src/foundation/binding.dart:59:5)
E/flutter ( 8708): #10 new _WidgetsFlutterBinding&BindingBase&GestureBinding (package:flutter/src/widgets/binding.dart)
E/flutter ( 8708): #11 new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding (package:flutter/src/widgets/binding.dart)
E/flutter ( 8708): #12 new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding&ServicesBinding (package:flutter/src/widgets/binding.dart)
E/flutter ( 8708): #13 new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding&ServicesBinding&PaintingBinding (package:flutter/src/widgets/binding.dart)
E/flutter ( 8708): #14 new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding&ServicesBinding&PaintingBinding&SemanticsBinding (package:flutter/src/widgets/binding.dart)
E/flutter ( 8708): #15 new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding&ServicesBinding&PaintingBinding&SemanticsBinding&RendererBinding (package:flutter/src/widgets/binding.dart)
E/flutter ( 8708): #16 new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding&ServicesBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding (package:flutter/src/widgets/binding.dart)
E/flutter ( 8708): #17 new WidgetsFlutterBinding (package:flutter/src/widgets/binding.dart)
E/flutter ( 8708): #18 WidgetsFlutterBinding.ensureInitialized (package:flutter/src/widgets/binding.dart:1229:7)
E/flutter ( 8708): #19 printBatteryLevel (package:bug/main.dart:11:25)
E/flutter ( 8708): #20 _IsolateConfiguration.apply (package:flutter/src/foundation/_isolates_io.dart:83:34)
E/flutter ( 8708): #21 _spawn.<anonymous closure> (package:flutter/src/foundation/_isolates_io.dart:90:65)
E/flutter ( 8708): #22 Timeline.timeSync (dart:developer/timeline.dart:163:22)
E/flutter ( 8708): #23 _spawn (package:flutter/src/foundation/_isolates_io.dart:87:35)
E/flutter ( 8708): #24 _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:304:17)
E/flutter ( 8708): #25 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)
E/flutter ( 8708):
ํ๋ฌํฐ ๋ฅํฐ -v
[โ] Flutter (Channel stable, 1.20.4, on Mac OS X 10.15.6 19G2021, locale en-BY)
โข Flutter version 1.20.4 at /Users/nikitadold/development/flutter
โข Framework revision fba99f6cf9 (2 weeks ago), 2020-09-14 15:32:52 -0700
โข Engine revision d1bc06f032
โข Dart version 2.9.2
[โ] Android toolchain - develop for Android devices (Android SDK version 30.0.0)
โข Android SDK at /Users/nikitadold/Library/Android/sdk
โข Platform android-30, build-tools 30.0.0
โข Java binary at: /Users/nikitadold/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/193.6626763/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
โข Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)
โข All Android licenses accepted.
[โ] Xcode - develop for iOS and macOS (Xcode 12.0.1)
โข Xcode at /Applications/Xcode.app/Contents/Developer
โข Xcode 12.0.1, Build version 12A7300
โข CocoaPods version 1.9.3
[!] Android Studio (version 4.0)
โข Android Studio at /Users/nikitadold/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/193.6626763/Android Studio.app/Contents
โ Flutter plugin not installed; this adds Flutter specific functionality.
โ Dart plugin not installed; this adds Dart specific functionality.
โข Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)
[โ] IntelliJ IDEA Ultimate Edition (version 2020.2.2)
โข IntelliJ at /Users/nikitadold/Applications/JetBrains Toolbox/IntelliJ IDEA Ultimate.app
โข Flutter plugin installed
โข Dart plugin version 202.7319.5
@TahaTesser
์ด ๋๊ธ์ ๋ด์ฃผ์ธ์
ํ๋ซํผ ๋ฉ์์ง๋ ๊ธฐ๋ณธ ๊ฒฉ๋ฆฌ์์๋ง ์ง์๋ฉ๋๋ค. [...]
์ด ๋์์ _์์_ ์ด๋ฉฐ ๋ ์ด๋ธ severe: new feature
์ ์์ต๋๋ค.
์ด ๋ฌธ์ ๋ _ ๋ฒ๊ทธ _๊ฐ ์๋๋ผ _๊ธฐ๋ฅ ์์ฒญ_ ๋๋ _ ์ ์ _์ผ๋ก ๊ฐ์ฃผ ๋์ด์ผ ํฉ๋๋ค.
@iapicca
๊ทํ์ ์์์ ์ค๋ฅ๋ ์ด ๋ฌธ์ ์ ๊ด๋ จ์ด ์์ต๋๋ค.
E/flutter (23174): [ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: Invalid argument(s): Illegal argument in isolate message : (object is a closure - Function '<anonymous closure>':.)
@iapicca
๊ทํ์ ์์์ ์ค๋ฅ๋ ์ด ๋ฌธ์ ์ ๊ด๋ จ์ด ์์ต๋๋ค.
E/flutter (23174): [ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: Invalid argument(s): Illegal argument in isolate message : (object is a closure - Function '<anonymous closure>':.)
๋น์ ์ด ์ณ์ต๋๋ค ๋ด ๊ฒ์ ์ข์ ์๊ฐ ์๋๋ฏ๋ก ๋ฌด์ํ์ญ์์ค
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
๋ค์ํ ์ฌ์ฉ ์ฌ๋ก๊ฐ ์์ต๋๋ค. ์:
์ผ๋ฐ์ ์ผ๋ก ์ด๋ค ๊ณต๊ฐ ๋ฉ์๋๋ฅผ ์ ์ธํ๋ ์ข ์์ฑ์ ์ฌ์ฉํ์ฌ ๊ฒฐ๊ตญ์๋ ํ๋ซํผ๋ณ ์ฝ๋๋ฅผ ์ฌ์ฉํ์ฌ ์์ ์ ์ํํ ์ง ์ฌ๋ถ๋ฅผ ์ ์ ์๋ ๊ฒฝ์ฐ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค(์: flutterfire์ ๋ํด ์๊ฐํ๊ณ ์์ต๋๋ค). ๊ทธ๊ฒ๋ค์ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ก ์ฐ์ฌ์ง ๊ฒ ๋์ ์ ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ๋ณํ ์ ์๋ ๊ตฌํ ์ธ๋ถ ์ฌํญ์ด์ด์ผ ํฉ๋๋ค.
๋ฐ์ดํฐ๊ฐ ์ด๋ฏธ ๋ฉ์๋ ์ฑ๋์ ์ ๋ฌ๋๋ ๋ฐฉ์์ผ๋ก ์ธ์ฝ๋ฉ๋์ด ์๊ธฐ ๋๋ฌธ์ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ํ์ฌ๋ก์๋ ๊ด์ฐฎ๊ณ ๊ตฌํํ๊ธฐ๊ฐ ์๋์ ์ผ๋ก ์ด๋ ต์ง ์์ ๊ฒ ๊ฐ์ต๋๋ค. ์ด๋ฌํ ์ด์ ๋ก ๊ฒฉ๋ฆฌ ํฌํธ๋ฅผ ํตํด์๋ ์ฝ๊ฒ ์ ๋ฌ๋์ง๋ง ์ฑ๋ฅ์ ์ฐจ์ ์ฑ ์ด ๋ ๊ฒ์ ๋๋ค. .
๊ทธ๋ฌ๋ ๊ตฌํํ๋ ๋์ ์ฝ๊ฐ ๋งํ์ต๋๋ค. ๊ธฐ๋ณธ ๊ฒฉ๋ฆฌ์์ ๋ณด์กฐ ๋ฉ์๋์์ ์ ์ ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ์ฌ์ด ๋ฐฉ๋ฒ์ ์๋ฅผ ์ ๊ณตํ ์ ์์ต๋๊น?
๊ฐ์ฌ ํด์