일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 클래스
- python
- Yocto
- 웹크롤러
- textstyle
- 플러터
- Flutter
- pushnamed
- List
- set
- Class
- DART
- import
- 콜렉션
- animation
- 함수
- 다트
- ML
- function
- 코틀린
- kotlin
- variable
- Collection
- package
- 파이썬
- Android
- map
- 크롤러
- text
- crawler
- Today
- Total
조용한 담장
Flutter : Platform-specific code 본문
Flitter Platform-specific code
Flutter Docs 따라가기
Flutter Docs 의 Writing custom platform-specific code 을 따라가 보며 Android/iOS 의 Java, Kotlin, Objective-C, Swift 와 Flutter 가 어떻게 연동되는지 알아보자.
Platform-specific code 를 사용할 수 있다는 것은 이미 존재하는 많은 코드들을 재사용 할 수도 있고, 좀 더 성능에 유리하게 개발 할 수도 있을 것이다.
또 Package 로 만들어서 flutter 내에서 재사용 하는 것도 가능하다.
플랫폼에 상관없이 코드 구조가 비슷해서 Android 와 Java 만 따라가 보겠다.
Flutter 는 Android 는 Java, iOS 는 Objective-C 를 기본으로 사용하므로 Kotlin, Swift 를 사용하려면 아래와 같이 프로젝트를 생성한다.
$ flutter create -i swift -a kotlin batterylevel
Platform channels
코드 구조가 비슷한 이유는 Flutter 와 Platform 이 messeging 방식으로 연동되기 때문이다.
Flutter가 Platform API 에 직접 접근하는 것이 아니라 MethodChannel 이라는 것을 통해 platform API 를 실행하도록 메세지를 보내고 결과를 메세지로 받는 방식이다.
Messages and responses are passed asynchronously, to ensure the user interface remains responsive.
Flutter app (client)
platform 과 통신하기 위한 channel 을 생성한다. 인자로 넘겨주는 이름이 다른 channel 과 구분을 지어주는 이름이니 되니 유일한 문자값을 쓴다.
The client and host sides of a channel are connected through a channel name passed in the channel constructor. All channel names used in a single app must be unique.
static const platform = const MethodChannel('samples.flutter.dev/battery');
생성된 method channel 의 method 통하여 결과값(배터리 레벨)을 얻어야 한다. 이때 method 도 문자열로 정의하여 사용된다. 아래 예제에는 platform 에 'getBatteryLevel' 문자열로 정의된 method가 있다.
invokeMethod() Invokes a method on this channel with the specified arguments.
// Get battery level.
String _batteryLevel = 'Unknown battery level.';
Future<void> _getBatteryLevel() async {
String batteryLevel;
try {
final int result = await platform.invokeMethod('getBatteryLevel');
batteryLevel = 'Battery level at $result % .';
} on PlatformException catch (e) {
batteryLevel = "Failed to get battery level: '${e.message}'.";
}
setState(() {
_batteryLevel = batteryLevel;
});
}
Flutter app 의 나머지 코드에서는 결과값 _batteryLevel 을 화면에 그리는 동작만 하면 된다.
Platform host
Android 에서 동작될 method 를 Java 로 구현한다. 파일은 android/app/src/main/java/com/example/batterylevel/MainActivity.java
이다.
MethodChannel 의 이름이 Flutter app 의 MethodChannel 과 동일한것을 확인하자.
public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "samples.flutter.dev/battery";
method channel 의 이름이 'getBatteryLevel' 인 method 의 handler 를 구현하면 된다.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
new MethodCallHandler() {
@Override
public void onMethodCall(MethodCall call, Result result) {
// Note: this method is invoked on the main thread.
if (call.method.equals("getBatteryLevel")) {
int batteryLevel = getBatteryLevel();
if (batteryLevel != -1) {
result.success(batteryLevel);
} else {
result.error("UNAVAILABLE", "Battery level not available.", null);
}
} else {
result.notImplemented();
}
}
}
);
}
'getBatteryLevel' 의 handler 에서 실제로 배터리 레벨값을 읽어오는 getBatteryLevel() 를 작성해주면 된다.
private int getBatteryLevel() {
int batteryLevel = -1;
if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
BatteryManager batteryManager = (BatteryManager) getSystemService(BATTERY_SERVICE);
batteryLevel = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
} else {
Intent intent = new ContextWrapper(getApplicationContext()).
registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
batteryLevel = (intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100) /
intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
}
return batteryLevel;
}
리턴값 batteryLevel 이 method 의 결과값으로 Flutter App 에 전달되어 UI 에 그려질 것이다.
more
battery package
Flutter Docs 의 예제코드를 보았지만 실제 거의 유사한 코드가 battery 값을 가져오는 package 로 구현되어 있다. 코드를 살펴보면 좋은 참고가 될 것이다.
section on threading
[You must invoke a channel method on the platform’s main thread. See the section on threading for more information.]
quick_actions
If desired, method calls can also be sent in the reverse direction, with the platform acting as client to methods implemented in Dart. A concrete example of this is the quick_actions plugin.
Platform channel data types support and codecs
The standard platform channels use a standard message codec that supports efficient binary serialization of simple JSON-like values, such as booleans, numbers, Strings, byte buffers, and List and Maps of these (see StandardMessageCodec) for details).
Reference
https://flutter.dev/docs/development/platform-integration/platform-channels
'Flutter' 카테고리의 다른 글
ListView (0) | 2019.08.08 |
---|---|
url_launcher (0) | 2019.08.07 |
Drawer (0) | 2019.08.02 |
AnimatedSwitcher (0) | 2019.07.31 |
BottomNavigationBar, BottomAppBar (0) | 2019.07.29 |