Dartnative arbeitet als Brücke, um zwischen Dart und nativen APIs zu kommunizieren.
Ersetzt den leistungsschwachen Flutterkanal durch einen schnelleren und prägnanteren Code.
Dartnative ruft jede native API dynamisch auf. Es unterstützt sowohl synchrones als auch asynchrones Kanaling.
Die Serialisierung von Parametern und Rückgabeträgen wie Flutterkanal ist nicht mehr erforderlich. Dartnativ liefert direkte Anrufe und automatisches Objekt -Marsching zwischen Sprachschnittstellen.
Dart Finalizer wird nur über Flutter 3 (Dart 2.17) unterstützt, aber mit Dartnativ ist es in Dart Flutter 2.2.0 (Dart 2.13.0) und auf.
Dartnative unterstützt die automatische Konvertierung des Typs, sodass sein Überbrückungscode kürzer und einfacher ist als der Flutterkanal.
Das Design und die Vision dieses Pakets:

| Dartnative Version | Flattern Anforderungen | Codegen -Version |
|---|---|---|
| 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 | Flattern 1.12.13 (Dart 2.7) | 1.x |
iOS & macos & Android
Fügen Sie dart_native zu Abhängigkeiten hinzu und build_runner zu Dev_Dependencies. Dann können Sie Code schreiben. Hier sind einige Beispiele:
Dartcode:
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]);
}Entsprechender objektiver C-Code:
@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);
}
@endEntsprechender Java -Code:
// 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 ;
}
}Hinweis: Wenn Ihr SO -Pfad individuell ist, müssen Sie einen bestimmten Pfad bestehen.
DartNativePlugin . loadSoWithCustomPath ( "xxx/libdart_native.so" ); Und bevor Sie Dartnativ in Dart verwenden, rufen Sie zunächst dartNativeInitCustomSoPath() auf. Es wird Pfad vom Kanal bekommen.
Dartcode:
interface . setMethodCallHandler ( 'totalCost' ,
( double unitCost, int count, List list) async {
return { 'totalCost: ${ unitCost * count }' : list};
});Entsprechender objektiver C-Code:
[ self invokeMethod: @" totalCost "
arguments: @[@ 0.123456789 , @ 10 , @[ @" testArray " ]]
result: ^( id _Nullable result, NSError * _Nullable error) {
NSLog ( @" %@ " , result);
}];
Entsprechender Java -Code:
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.
});| Pfeil | Ziel-C | Schnell | Java |
|---|---|---|---|
| NULL | Null | Null | NULL |
| bool | Bool | Bool | bool |
| int | NSINTEER | Int | int |
| doppelt | doppelt | Doppelt | doppelt |
| Saite | Nsstring | Saite | Saite |
| Liste | Nsarray | Array | Liste, ArrayList |
| Karte | NSDictionary | Wörterbuch | Karte, Hashmap |
| Satz | NSSET | Satz | Set, Hashset |
| Funktion | Block | Schließung | Versprechen |
| Zeiger | Leere * | Unafemutablerawpointer | - - |
| NativeByte | Nsdata | Daten | DirectByTebuffer |
| NativeObject | NSOBJECT | NSOBJECT | Objekt |
Schritt 1: Fügen Sie dart_native zu Abhängigkeiten und build_runner zu Dev_Dependencies hinzu.
Schritt 2: Generieren Sie den Dart -Wrapper -Code mit @dartnative/codeGen oder schreiben Sie den Dart -Code manuell.
Schritt 3: Generieren Sie Code für den automatischen Typumwandlung mit DART_NATIVE_GEN mit den folgenden Schritten (3.1-3.3):
3.1 Annotieren Sie eine Dart -Wrapper -Klasse mit @native .
@native
class RuntimeSon extends RuntimeStub {
RuntimeSon ([ Class isa]) : super ( Class ( 'RuntimeSon' ));
RuntimeSon . fromPointer ( Pointer < Void > ptr) : super . fromPointer (ptr);
} 3.2 Mit @nativeroot Ihren eigenen Eintrag (wie main() ) mit @nativeRoot .
@nativeRoot
void main () {
runApp ( App ());
}3.3 Lauf
flutter packages pub run build_runner build --delete-conflicting-outputs So generieren Sie Dateien in Ihr Quellverzeichnis.
Hinweis: Wir empfehlen, zuerst clean zu laufen:
flutter packages pub run build_runner clean Schritt 4: Rufen Sie die autogenerierte Funktion in <generated-name>.dn.dart in 3.3 auf. Der Funktionsname wird in pubspec.yaml mit name bestimmt.
@nativeRoot
void main () {
// Function name is generated by name in pubspec.yaml.
runDartNativeExample ();
runApp ( App ());
}Schritt 5: Dann können Sie Code schreiben. Hier sind einige Beispiele:
5.1 iOS:
Dartcode (generiert):
// 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);
Entsprechender objektiver C-Code:
typedef int (^BarBlock)( NSObject *a);
@interface RuntimeStub
- ( CGRect ) fooCGRect : ( CGRect ) rect ;
- ( void ) fooBlock : (BarBlock) block ;
@endWeitere iOS -Beispiele siehe: ios_unit_test.dart
5.2 Android:
Dartcode (generiert):
// new Java object.
RuntimeStub stub = RuntimeStub ();
// get java list.
List list = stub. getList ([ 1 , 2 , 3 , 4 ]);
// support interface.
stub. setDelegateListener ( DelegateStub ());
Entsprechender Java -Code:
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 );
}
}Weitere Android -Beispiele siehe: Android_unit_test.dart
Hinweis: Wenn Sie DART_NATIVE auf MacOS verwenden, müssen Sie use_frameworks! in Ihrer Podfile.
F: Suchsymbol (dlsym (rtld_default, initdartapidl): Symbol nicht gefunden) auf dem MacOS -Archiv.
A: Wählen Sie eine Lösung aus:
use_frameworks! in Podfile.Dartnativ ist gemäß der BSD 3-Clause-Lizenz verfügbar. Weitere Informationen finden Sie in der Lizenzdatei.