Dartnative opera como uma ponte para se comunicar entre as APIs de DART e Native.
Substitui o canal Flutter de baixo desempenho por um código mais rápido e conciso.
Dartnative chama qualquer API nativa dinamicamente . Ele suporta canalização síncrona e assíncrona.
A serialização de parâmetros e valores de retorno como canal fleta não é mais necessária. O Dartnative fornece chamadas diretas e marechaling de objetos automáticos entre interfaces de idioma.
O Finalizador do DART é suportado apenas acima do Flutter 3 (DART 2.17), mas com o Dartnative está disponível no Dart Flutter 2.2.0 (DART 2.13.0) e acima.
O Dartnative suporta a conversão do tipo automático, para que seu código de ponte seja mais curto e mais simples que o canal Flutter.
O design e a visão deste pacote:

| Versão DARTNATIVA | Requisitos de vibração | Versão CodeGen |
|---|---|---|
| 0.4.x - 0,7.x. | Flutter 2.2.0 (DART 2.13.0) | 2.x |
| 0.3.x | Flutter 1.20.0 (DART 2.9.1) | 1.2.x |
| 0.2.x | Flutter 1.12.13 (Dart 2.7) | 1.x |
iOS & MacOS e Android
Adicione dart_native às dependências e build_runner às dev_dependências. Então você pode escrever código. Aqui estão alguns exemplos:
Código de dardo:
final interface = Interface ( "MyFirstInterface" );
// Example for string type.
String helloWorld () {
return interface . invokeMethodSync ( 'hello' , args : [ 'world' ]);
}
// Example for num type.
Future < int > sum ( int a, int b) {
return interface . invokeMethod ( 'sum' , args : [a, b]);
}Código Objetivo-C correspondente:
@implementation DNInterfaceDemo
// Register interface name.
InterfaceEntry (MyFirstInterface)
// Register method "hello".
InterfaceMethod(hello, myHello:( NSString *)str) {
return [ NSString stringWithFormat: @" hello %@ ! " , str];
}
// Register method "sum".
InterfaceMethod (sum, addA:( int32_t )a withB:( int32_t )b) {
return @(a + b);
}
@endCódigo Java correspondente:
// load libdart_native.so
DartNativePlugin . loadSo ();
@ InterfaceEntry ( name = "MyFirstInterface" )
public class InterfaceDemo extends DartNativeInterface {
@ InterfaceMethod ( name = "hello" )
public String hello ( String str ) {
return "hello " + str ;
}
@ InterfaceMethod ( name = "sum" )
public int sum ( int a , int b ) {
return a + b ;
}
}Nota: Se o seu caminho SO for personalizado, você precisará passar um caminho específico.
DartNativePlugin . loadSoWithCustomPath ( "xxx/libdart_native.so" ); E antes de usar o Dartnative no DART, primeiro invoco dartNativeInitCustomSoPath() . Será o caminho do canal.
Código de dardo:
interface . setMethodCallHandler ( 'totalCost' ,
( double unitCost, int count, List list) async {
return { 'totalCost: ${ unitCost * count }' : list};
});Código Objetivo-C correspondente:
[ self invokeMethod: @" totalCost "
arguments: @[@ 0.123456789 , @ 10 , @[ @" testArray " ]]
result: ^( id _Nullable result, NSError * _Nullable error) {
NSLog ( @" %@ " , result);
}];
Código Java correspondente:
invokeMethod ( "totalCost" , new Object []{ 0.123456789 , 10 , Arrays . asList ( "hello" , "world" )},
new DartNativeResult () {
@ Override
public void onResult ( @ Nullable Object result ) {
Map retMap = ( Map ) result ;
// do something
}
@ Override
public void error ( @ Nullable String errorMessage ) {
// do something
}
}
); final foo = Bar (); // A custom instance.
unitTest. addFinalizer (() { // register a finalizer callback.
print ( 'The instance of ' foo ' has been destroyed!' ); // When `foo` is destroyed by GC, this line of code will be executed.
});| Dardo | Objective-C | Swift | Java |
|---|---|---|---|
| nulo | nil | nil | nulo |
| bool | Bool | Bool | bool |
| int | Nsinteger | Int | int |
| dobro | dobro | Dobro | dobro |
| Corda | NSString | Corda | Corda |
| Lista | Nsarray | Variedade | Lista, Arraylist |
| Mapa | Nsdictionary | Dicionário | Mapa, hashmap |
| Definir | Nsset | Definir | Set, hashset |
| Função | Bloquear | Encerramento | Promessa |
| Ponteiro | vazio * | InsafemutableRawPointer | - |
| Nativo | Nsdata | Dados | DirectByteBuffer |
| Nativo -objeto | NSObject | NSObject | Objeto |
Etapa 1: Adicione dart_native às dependências e build_runner às dev_dependências.
Etapa 2: gerar código de wrapper com @dartnative/codegen ou gravar código de dardo manualmente.
Etapa 3: Gere código para conversão de tipo automático usando Dart_native_Gen com as etapas a seguir (3.1-3.3):
3.1 Anote uma classe de wrapper Dart com @native .
@native
class RuntimeSon extends RuntimeStub {
RuntimeSon ([ Class isa]) : super ( Class ( 'RuntimeSon' ));
RuntimeSon . fromPointer ( Pointer < Void > ptr) : super . fromPointer (ptr);
} 3.2 Anote sua própria entrada (como main() ) com @nativeRoot .
@nativeRoot
void main () {
runApp ( App ());
}3.3 Run
flutter packages pub run build_runner build --delete-conflicting-outputs Para gerar arquivos no seu diretório de origem.
NOTA: Recomendamos a execução clean primeiro:
flutter packages pub run build_runner clean Etapa 4: Ligue para a função autogenerada em <generated-name>.dn.dart em 3.3. O nome da função é determinado pelo name no pubspec.yaml .
@nativeRoot
void main () {
// Function name is generated by name in pubspec.yaml.
runDartNativeExample ();
runApp ( App ());
}Etapa 5: então você pode escrever código. Aqui estão alguns exemplos:
5.1 iOS:
Código de dardo (gerado):
// new Objective-C object.
RuntimeStub stub = RuntimeStub ();
// Dart function will be converted to Objective-C block.
stub. fooBlock (( NSObject a) {
print ( 'hello block! ${ a . toString ()}' );
return 101 ;
});
// support built-in structs.
CGRect rect = stub. fooCGRect ( CGRect ( 4 , 3 , 2 , 1 ));
print (rect);
Código Objetivo-C correspondente:
typedef int (^BarBlock)( NSObject *a);
@interface RuntimeStub
- ( CGRect ) fooCGRect : ( CGRect ) rect ;
- ( void ) fooBlock : (BarBlock) block ;
@endMais exemplos do iOS, veja: ios_unit_test.dart
5.2 Android:
Código de dardo (gerado):
// new Java object.
RuntimeStub stub = RuntimeStub ();
// get java list.
List list = stub. getList ([ 1 , 2 , 3 , 4 ]);
// support interface.
stub. setDelegateListener ( DelegateStub ());
Código Java correspondente:
public class RuntimeStub {
public List < Integer > getList ( List < Integer > list ) {
List < Integer > returnList = new ArrayList <>();
returnList . add ( 1 );
returnList . add ( 2 );
return returnList ;
}
public void setDelegateListener ( SampleDelegate delegate ) {
delegate . callbackInt ( 1 );
}
}Mais exemplos do Android, consulte: Android_unit_test.dart
NOTA: Se você usar o Dart_native no macOS, você deverá usar use_frameworks! no seu poder.
P: Falha ao procurar símbolo (dlsym (rtld_default, initDartapidl): símbolo não encontrado) no arquivo macOS.
A: Selecione uma solução:
use_frameworks! No PODFILE.O Dartnative está disponível sob a licença de 3 cláusulas BSD. Consulte o arquivo de licença para obter mais informações.