Flutter에서 자바 코드 실행 - MethodChannel 템플릿

12349 단어 dartfluttermobile
이것은 Flutter에서 기본 코드를 실행하는 것에 대한 참고 사항과 시작하기 위한 빠른 템플릿, 마지막에 소스입니다.

Flutter로 네이티브 코드를 실행하려면 정의된 플랫폼 채널을 사용하여 메시지를 보내면 됩니다. MethodChannel을 사용하여 Flutter 앱은 호스트 플랫폼(iOS/Android)에서 메시지를 보내고 받습니다.

메소드 호출은 전송되기 전에 바이너리로 인코딩되고 수신된 바이너리 결과는 Dart 값으로 디코딩됩니다. 채널을 통해 전송된 데이터는 다음 표와 같이 변환됩니다.



메시지와 응답은 비동기식으로 전달되지만 채널 메서드는 기본 스레드에서 호출해야 합니다. 이 때문에 메서드가 계산하는 데 너무 오래 걸리는 경우 메인 스레드가 버벅거릴 수 있습니다. 이는 잠시 후 백엔드의 다른 스레드에 메시지를 보내 완화할 수 있습니다.

이것의 다른 특징은 메인 격리가 메인 스레드에서 실행되는 유일한 것이므로 메서드 채널을 격리에서 사용할 수 없다는 것입니다.

방법 채널을 만드는 방법



앱 상태에서 methodchannel을 정의합니다. 이름이 일치해야 합니다.

원하는 작업을 위한 템플릿으로 사용할 수 있습니다.

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
...
class _MyHomePageState extends State<MyHomePage> {
  static const platform = const MethodChannel('com.dev.app/channel_name');


}


MainActivity.kt 또는 .java에서 '백엔드'를 생성하는 플랫폼별 코드는 메서드 채널을 생성합니다.

import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity: FlutterActivity() {
  private val CHANNEL = "com.dev.app/channel_name"
  private fun doSomethingFunction(): Int {
    return 10   
  }

    return batteryLevel
  }
  override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
    super.configureFlutterEngine(flutterEngine)
    MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
      call, result ->
      // Note: this method is invoked on the main thread.
      if (call.method == "doSomething") {
        val funValue = doSomethingFunction()

        if (funValue != -1) {
          result.success(funValue)
        } else {
          result.error("UNAVAILABLE", "Error message.", null)
        }
      } else {
        result.notImplemented()
      }
    }
  }
}


Flutter 앱에서 메서드 채널을 호출하고 상태에서 기능합니다.

String _valueReceivied= 'default value';
  Future<void> _getBatteryLevel() async {
    String tempValue;
    try {
      final int result = await platform.invokeMethod('doSomething');
      batteryLevel = 'New data $result';
    } on PlatformException catch (e) {
      batteryLevel = "Failed to get new data: '${e.message}'.";
    }

    setState(() {
      _valueReceivied = tempValue;
    });
  }


그런 다음 적합하다고 생각되는 대로 함수를 실행합니다.
invokeListMethod의 구현인 invokeMapMethodinvokeMethod를 사용할 수도 있지만 그들은 목록 또는 지도를 받을 것으로 예상합니다. More info .

플랫폼의 백엔드와 코드를 통신하고 실행하는 이러한 방식은 플러터 앱에서와 같이 백엔드에서 동일한 데이터 유형의 정의가 필요하기 때문에 유형이 안전하지 않습니다.
이를 수행하는 또 다른 방법은 Pigeon 으로 코드 생성을 사용하는 것입니다. pub.dev 페이지에서 더 많은 정보를 얻으세요. 재미있다면 이에 대한 포스팅을 해보려고 합니다.

패키지를 만들어 UI에 대한 플랫폼별 코드를 분리하고 패키지를 Flutter 에코시스템에 게시할 수도 있습니다. Developing , Publishing .

스레딩



메인 스레드와 메소드 채널이 실행되는 위치도 UI thread이므로 일부 계산이 완료되는 데 너무 오래 걸리면 UI가 이로 인해 발생할 수 있습니다.
그래서 한 가지 유의할 점은...

When your app performs intensive work in response to user interaction, this single thread model can yield poor performance unless you implement your application properly. Specifically, if everything is happening in the UI thread, performing long operations such as network access or database queries will block the whole UI. When the thread is blocked, no events can be dispatched, including drawing events. From the user's perspective, the application appears to hang. Even worse, if the UI thread is blocked for more than a few seconds (about 5 seconds currently) the user is presented with the infamous "application not responding" (ANR) dialog. The user might then decide to quit your application and uninstall it if they are unhappy.



다음을 수행하여 백그라운드 스레드에서 UI 스레드로 이동할 수 있습니다.

코틀린:

Handler(Looper.getMainLooper()).post {
  // Call the desired channel message here.
}


자바에서:

new Handler(Looper.getMainLooper()).post(new Runnable() {
  @Override
  public void run() {
    // Call the desired channel message here.
  }
});


문서가 이것이 의미하는 것이 무엇인지 확실하지 않지만 비슷한 것을 테스트하고 오류를 경험했지만 다른 스레드에서 네이티브 코드를 실행하는 방법일 수 있습니다. 따라서 여기에서 더 많은 테스트를 수행해야 합니다. 알려주는 정보가 있습니다.

이것은 dart에서 지원하지 않는 네이티브 코드 또는 라이브러리를 실행하는 데 아주 좋습니다. 제 예에서 이것은 ML 라이브러리에 대해 굉장하고 장치에서 실행되는 모델을 가져옵니다.
내가 경험한 한 가지는 ML 모델을 실행할 때 UI 스레드가 어려움을 겪기 때문에 다른 스레드에서 이러한 모델을 실행하거나 다른 스레드에서 실행될 때 플러그인을 만드는 테스트를 할 것입니다.
Flutter에서 Pytorch 모바일을 사용하는 방법에 대한 간략한 소개를 했으며, 더 포괄적인 작업을 계획하고 있습니다. 스레드가 제대로 작동하는 경우 지연 없이 작업을 더 빠르게 만들기 위한 스레드 사용에 대해 이야기하겠습니다.



출처:

Platform channels

Docs MethodChannel

좋은 웹페이지 즐겨찾기