Dartnative действует как мост для общения между DART и местными API.
Заменяет низкопроизводительный канал Flutter на более быстрый и более краткий код.
Dartnative вызывает любой родной API динамически . Он поддерживает как синхронное, так и асинхронное канал.
Сериализация параметров и возвращаемых значений, таких как канал Flutter, больше не требуется. Dartnative обеспечивает прямые вызовы и автоматическое объект, маршалирование между языковыми интерфейсами.
DART Finalizer поддерживается только над Flutter 3 (DART 2.17), но с Dartnative он доступен в Dart Flutter 2.2.0 (Dart 2.13.0) и вверх.
Dartnative поддерживает автоматическое преобразование типа, поэтому его мостовой код короче и проще, чем канал Flutter.
Дизайн и видение этого пакета:

| Дартнавная версия | Требования к трепету | Кодовая версия |
|---|---|---|
| 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 | Флаттер 1.12.13 (Dart 2.7) | 1.x |
iOS & MacOS & Android
Добавьте dart_native к зависимостям и build_runner в dev_dependencies. Тогда вы можете написать код. Вот несколько примеров:
Код DART:
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]);
}Соответствующий код Objective-C:
@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);
}
@endСоответствующий код Java:
// 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 ;
}
}ПРИМЕЧАНИЕ. Если ваш путь такого пути, вам нужно пройти конкретный путь.
DartNativePlugin . loadSoWithCustomPath ( "xxx/libdart_native.so" ); И прежде чем использовать Dartnative в DART, сначала вызовет dartNativeInitCustomSoPath() . Он получит путь от канала.
Код DART:
interface . setMethodCallHandler ( 'totalCost' ,
( double unitCost, int count, List list) async {
return { 'totalCost: ${ unitCost * count }' : list};
});Соответствующий код Objective-C:
[ self invokeMethod: @" totalCost "
arguments: @[@ 0.123456789 , @ 10 , @[ @" testArray " ]]
result: ^( id _Nullable result, NSError * _Nullable error) {
NSLog ( @" %@ " , result);
}];
Соответствующий код Java:
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.
});| Дрэк | Объектив-c | Быстрый | Ява |
|---|---|---|---|
| нулевой | ноль | ноль | нулевой |
| буль | Буль | Буль | буль |
| инт | NSINTEGER | Инт | инт |
| двойной | двойной | Двойной | двойной |
| Нить | NSString | Нить | Нить |
| Список | Nsarray | Множество | Список, ArrayList |
| Карта | Nsdictionary | Словарь | Карта, Hashmap |
| Набор | NSSet | Набор | SET, Hashset |
| Функция | Блокировать | Закрытие | Обещать |
| Указатель | пустота * | Uncefemutablerawpointer | - |
| NativeByte | NSDATA | Данные | DirectByteBuffer |
| NativeObject | Nsobject | Nsobject | Объект |
Шаг 1: Добавьте dart_native к зависимостям и build_runner в dev_dependencies.
Шаг 2: Сгенерируйте код обертки DART с помощью @dartnative/codegen или напишите код DART вручную.
Шаг 3: Сгенерируйте код для автоматического преобразования типа с использованием dart_native_gen с следующими шагами (3.1-3.3):
3.1 Аннотируйте класс Dart Wrapper с @native .
@native
class RuntimeSon extends RuntimeStub {
RuntimeSon ([ Class isa]) : super ( Class ( 'RuntimeSon' ));
RuntimeSon . fromPointer ( Pointer < Void > ptr) : super . fromPointer (ptr);
} 3.2 Аннотируйте свою собственную запись (например, main() ) с @nativeRoot .
@nativeRoot
void main () {
runApp ( App ());
}3.3 беги
flutter packages pub run build_runner build --delete-conflicting-outputs Чтобы сгенерировать файлы в ваш исходный каталог.
Примечание: сначала мы рекомендуем работать clean :
flutter packages pub run build_runner clean Шаг 4: Вызовите функцию автогенерирования в <generated-name>.dn.dart в 3.3. Имя функции определяется name в pubspec.yaml .
@nativeRoot
void main () {
// Function name is generated by name in pubspec.yaml.
runDartNativeExample ();
runApp ( App ());
}Шаг 5: Тогда вы можете написать код. Вот несколько примеров:
5.1 iOS:
Код DART (сгенерирован):
// 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);
Соответствующий код Objective-C:
typedef int (^BarBlock)( NSObject *a);
@interface RuntimeStub
- ( CGRect ) fooCGRect : ( CGRect ) rect ;
- ( void ) fooBlock : (BarBlock) block ;
@endБольше примеров iOS См.: Ios_unit_test.dart
5.2 Android:
Код DART (сгенерирован):
// new Java object.
RuntimeStub stub = RuntimeStub ();
// get java list.
List list = stub. getList ([ 1 , 2 , 3 , 4 ]);
// support interface.
stub. setDelegateListener ( DelegateStub ());
Соответствующий код Java:
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 );
}
}Больше примеров Android См.: Android_unit_test.dart
ПРИМЕЧАНИЕ. Если вы используете DART_NAIVE на MacOS, вы должны использовать use_frameworks! в вашем подполковнике.
Q: Не удалось найти символ поиска (DLSYM (rtld_default, initdartapidl): символ не найден) на архиве macOS.
A: Выберите одно решение:
use_frameworks! в Podfile.Dartnative доступен по лицензии BSD 3-CRAUSE. Смотрите файл лицензии для получения дополнительной информации.