Dartnative opera como un puente para comunicarse entre las API de dardos y nativos.
Reemplaza el canal Flutter de bajo rendimiento con un código más rápido y más conciso.
Dartnative llama a cualquier API nativa dinámicamente . Apoya la canalización síncrona y asincrónica.
La serialización de los parámetros y los valores de retorno, como el canal Flutter, ya no se requiere. Dartnative proporciona llamadas directas y el ensarjamiento automático de objetos entre las interfaces del lenguaje.
El finalizador de Dart solo se admite por encima de Flutter 3 (Dart 2.17), pero con Dartnative está disponible en Dart Flutter 2.2.0 (Dart 2.13.0) y arriba.
Dartnative admite la conversión de tipo automático, por lo que su código de puente es más corto y simple que el canal Flutter.
El diseño y la visión de este paquete:

| Versión de dartnative | Requisitos de aleteo | Versión de Codegen |
|---|---|---|
| 0.4.x - 0.7.x | Flutter 2.2.0 (dardo 2.13.0) | 2.x |
| 0.3.x | Flutter 1.20.0 (dardo 2.9.1) | 1.2.x |
| 0.2.x | Flutter 1.12.13 (dardo 2.7) | 1.x |
iOS & MacOS & Android
Agregue dart_native a las dependencias y build_runner a dev_dependencies. Entonces puedes escribir código. Aquí hay algunos ejemplos:
Código de dardos:
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 Código CON Objetivo-C correspondiente:
@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 correspondiente:
// 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: Si su ruta SO está personalizada, necesita pasar una ruta específica.
DartNativePlugin . loadSoWithCustomPath ( "xxx/libdart_native.so" ); Y antes de usar Dartnative en Dart, primero invoca dartNativeInitCustomSoPath() . Obtendrá camino desde el canal.
Código de dardos:
interface . setMethodCallHandler ( 'totalCost' ,
( double unitCost, int count, List list) async {
return { 'totalCost: ${ unitCost * count }' : list};
});Código Código CON Objetivo-C correspondiente:
[ self invokeMethod: @" totalCost "
arguments: @[@ 0.123456789 , @ 10 , @[ @" testArray " ]]
result: ^( id _Nullable result, NSError * _Nullable error) {
NSLog ( @" %@ " , result);
}];
Código Java correspondiente:
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 | Objetivo-C | Rápido | Java |
|---|---|---|---|
| nulo | nulo | nulo | nulo |
| bool | Bool | Bool | bool |
| intencionalmente | Nsintager | Intencionalmente | intencionalmente |
| doble | doble | Doble | doble |
| Cadena | Nsstring | Cadena | Cadena |
| Lista | Nsarray | Formación | Lista, ArrayList |
| Mapa | Nsdiccionario | Diccionario | Mapa, hashmap |
| Colocar | Nsset | Colocar | Establecer, hashset |
| Función | Bloquear | Cierre | Promesa |
| Puntero | vacío * | Insegurar | - |
| Nativo | Nsdata | Datos | Directobytebuffer |
| Objeto nativo | Nsobject | Nsobject | Objeto |
Paso 1: Agregue dart_native a Dependencias y build_runner a dev_dependencies.
Paso 2: Genere el código de envoltorio de dardos con @dartnative/codegen o escriba el código de dardo manualmente.
Paso 3: Genere el código para la conversión de tipo automático usando dart_native_gen con los siguientes pasos (3.1-3.3):
3.1 Anotar una clase de envoltorio de dardos con @native .
@native
class RuntimeSon extends RuntimeStub {
RuntimeSon ([ Class isa]) : super ( Class ( 'RuntimeSon' ));
RuntimeSon . fromPointer ( Pointer < Void > ptr) : super . fromPointer (ptr);
} 3.2 Anotar su propia entrada (como main() ) con @nativeRoot .
@nativeRoot
void main () {
runApp ( App ());
}3.3 Run
flutter packages pub run build_runner build --delete-conflicting-outputs Para generar archivos en su directorio de origen.
NOTA: Recomendamos ejecutar clean primero:
flutter packages pub run build_runner clean Paso 4: Llame a la función autogenerada en <generated-name>.dn.dart en 3.3. El nombre de la función se determina por name en pubspec.yaml .
@nativeRoot
void main () {
// Function name is generated by name in pubspec.yaml.
runDartNativeExample ();
runApp ( App ());
}Paso 5: Entonces puedes escribir código. Aquí hay algunos ejemplos:
5.1 iOS:
Código de dardos (generado):
// 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 Código CON Objetivo-C correspondiente:
typedef int (^BarBlock)( NSObject *a);
@interface RuntimeStub
- ( CGRect ) fooCGRect : ( CGRect ) rect ;
- ( void ) fooBlock : (BarBlock) block ;
@endMás ejemplos de iOS ver: iOS_UNIT_TEST.DART
5.2 Android:
Código de dardos (generado):
// 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 correspondiente:
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 );
}
}Más ejemplos de Android ver: android_unit_test.dart
Nota: Si usa DART_NATIVE en MacOS, ¡debe usar use_frameworks! en tu podfile.
P: No se pudo buscar el símbolo (dlsym (rtld_default, initDartapidl): símbolo no encontrado) en el archivo macOS.
A: Seleccione una solución:
use_frameworks! en Podfile.Dartnative está disponible bajo la licencia BSD 3 cláusula. Consulte el archivo de licencia para obtener más información.