Le dartnatif fonctionne comme un pont pour communiquer entre les API Dart et les API indigènes.
Remplace le canal de flottement peu performant avec un code plus rapide et plus concis.
Dartnative appelle dynamiquement toute API native. Il prend en charge la canalisation synchrone et asynchrone.
La sérialisation des paramètres et des valeurs de retour comme Flutter Channel n'est plus nécessaire. Dartnative fournit des appels directs et un rassemblement d'objets automatique entre les interfaces linguistiques.
Dart Finalizer n'est pris en charge qu'au-dessus de Flutter 3 (DART 2.17), mais avec le dartnatif, il est disponible dans Dart Flutter 2.2.0 (Dart 2.13.0) et UP.
Le dartnatif prend en charge la conversion de type automatique afin que son code de pontage soit plus court et plus simple que le canal de flottement.
La conception et la vision de ce package:

| Version dartnative | Exigences de flottement | Version 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 & Android
Ajoutez dart_native aux dépendances et build_runner à Dev_Dependces. Ensuite, vous pouvez écrire du code. Voici quelques exemples:
Code de fléchette:
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]);
}Code objectif-C correspondant:
@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);
}
@endCode Java correspondant:
// 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 ;
}
}Remarque: Si votre chemin SO est personnalisé, vous avez besoin de passer un chemin spécifique.
DartNativePlugin . loadSoWithCustomPath ( "xxx/libdart_native.so" ); Et avant d'utiliser le dartnatif dans Dart, invoque d'abord dartNativeInitCustomSoPath() . Il obtiendra le chemin de la chaîne.
Code de fléchette:
interface . setMethodCallHandler ( 'totalCost' ,
( double unitCost, int count, List list) async {
return { 'totalCost: ${ unitCost * count }' : list};
});Code objectif-C correspondant:
[ self invokeMethod: @" totalCost "
arguments: @[@ 0.123456789 , @ 10 , @[ @" testArray " ]]
result: ^( id _Nullable result, NSError * _Nullable error) {
NSLog ( @" %@ " , result);
}];
Code Java correspondant:
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.
});| Dard | Objectif-c | Rapide | Java |
|---|---|---|---|
| nul | néant | néant | nul |
| bool | Bool | Bool | bool |
| int | Nsinteger | Int | int |
| double | double | Double | double |
| Chaîne | Nsstring | Chaîne | Chaîne |
| Liste | Nsarray | Tableau | Liste, ArrayList |
| Carte | Nsdictionnaire | Dictionnaire | Carte, hashmap |
| Ensemble | Nsset | Ensemble | Set, hashset |
| Fonction | Bloc | Fermeture | Promesse |
| Aiguille | vide * | Dangemutablerawpointer | - |
| Natif | Nsdata | Données | Directement |
| Nativeobject | Nsobject | Nsobject | Objet |
Étape 1: Ajoutez dart_native aux dépendances et build_runner à Dev_Dependces.
Étape 2: Générez le code de wrapper Dart avec @ dartnative / codegen ou écrivez manuellement le code de fléchette.
Étape 3: Générez du code pour la conversion de type automatique à l'aide de DART_NATION_GEN avec les étapes suivantes (3.1-3.3):
3.1 Annotez une classe de wrapper de fléchette avec @native .
@native
class RuntimeSon extends RuntimeStub {
RuntimeSon ([ Class isa]) : super ( Class ( 'RuntimeSon' ));
RuntimeSon . fromPointer ( Pointer < Void > ptr) : super . fromPointer (ptr);
} 3.2 Annotez votre propre entrée (comme main() ) avec @nativeRoot .
@nativeRoot
void main () {
runApp ( App ());
}3.3 Run
flutter packages pub run build_runner build --delete-conflicting-outputs Pour générer des fichiers dans votre répertoire source.
Remarque: nous recommandons d'abord de courir clean :
flutter packages pub run build_runner clean Étape 4: Appelez la fonction autoogénérée dans <generated-name>.dn.dart en 3.3. Le nom de la fonction est déterminé par name dans pubspec.yaml .
@nativeRoot
void main () {
// Function name is generated by name in pubspec.yaml.
runDartNativeExample ();
runApp ( App ());
}Étape 5: Ensuite, vous pouvez écrire du code. Voici quelques exemples:
5.1 iOS:
Code de fléchette (généré):
// 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);
Code objectif-C correspondant:
typedef int (^BarBlock)( NSObject *a);
@interface RuntimeStub
- ( CGRect ) fooCGRect : ( CGRect ) rect ;
- ( void ) fooBlock : (BarBlock) block ;
@endPlus d'exemples iOS Voir: iOS_Unit_test.dart
5.2 Android:
Code de fléchette (généré):
// new Java object.
RuntimeStub stub = RuntimeStub ();
// get java list.
List list = stub. getList ([ 1 , 2 , 3 , 4 ]);
// support interface.
stub. setDelegateListener ( DelegateStub ());
Code Java correspondant:
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 );
}
}Plus d'exemples Android Voir: Android_Unit_test.dart
Remarque: Si vous utilisez Dart_Native sur macOS, vous devez utiliser use_frameworks! dans votre podfile.
Q: Échec du symbole de recherche (DLSym (RTLD_DEFAULT, INITDARTAPIDL): Symbole introuvable) sur l'archive macOS.
R: Sélectionnez une solution:
use_frameworks! en podfile.Le dartnatif est disponible en vertu de la licence BSD 3 clause. Voir le fichier de licence pour plus d'informations.