Dartnative ดำเนินการเป็นสะพานเชื่อมระหว่าง DART และ API พื้นเมือง
แทนที่ช่อง Flutter ที่มีประสิทธิภาพต่ำด้วยรหัสที่เร็วขึ้นและกระชับยิ่งขึ้น
Dartnative เรียก API ดั้งเดิม แบบไดนามิก รองรับทั้งช่องสัญญาณแบบซิงโครนัสและแบบอะซิงโครนัส
การทำให้เป็นอนุกรมของพารามิเตอร์และค่าส่งคืนเช่นช่อง Flutter ไม่จำเป็นอีกต่อไป Dartnative ให้การโทรโดยตรงและวัตถุอัตโนมัติ marshalling ระหว่างอินเทอร์เฟซภาษา
DART Finalizer ได้รับการสนับสนุนเฉพาะด้านบน Flutter 3 (DART 2.17) แต่ด้วย Dartnative มันมีให้บริการใน Dart Flutter 2.2.0 (DART 2.13.0) ขึ้นไป
Dartnative รองรับการแปลงประเภทอัตโนมัติเพื่อให้รหัสการเชื่อมต่อสั้นกว่า & ง่ายกว่าช่อง Flutter
การออกแบบและวิสัยทัศน์ของแพ็คเกจนี้:

| เวอร์ชัน Dartnative | ข้อกำหนดการกระพือปีก | เวอร์ชัน 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
เพิ่ม dart_native ไปยังการพึ่งพาและ build_runner ไปยัง dev_dependencies จากนั้นคุณสามารถเขียนรหัส นี่คือตัวอย่างบางส่วน:
รหัสโผ:
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 ที่สอดคล้องกัน:
@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 ;
}
}หมายเหตุ: หากเส้นทาง SO ของคุณกำหนดเองคุณต้องผ่านเส้นทางที่เฉพาะเจาะจง
DartNativePlugin . loadSoWithCustomPath ( "xxx/libdart_native.so" ); และก่อนที่จะใช้ Dartnative ใน DART ก่อนอื่นเรียก dartNativeInitCustomSoPath() มันจะได้รับเส้นทางจากช่อง
รหัสโผ:
interface . setMethodCallHandler ( 'totalCost' ,
( double unitCost, int count, List list) async {
return { 'totalCost: ${ unitCost * count }' : list};
});รหัสวัตถุประสงค์ -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 | ฉับพลัน | ชวา |
|---|---|---|---|
| โมฆะ | ไม่มี | ไม่มี | โมฆะ |
| บูล | บูล | บูล | บูล |
| int | nsinteger | int | int |
| สองเท่า | สองเท่า | สองเท่า | สองเท่า |
| สาย | NSSTRING | สาย | สาย |
| รายการ | nsarray | อาร์เรย์ | รายการ ArrayList |
| แผนที่ | การทำผิดปกติ | พจนานุกรม | แผนที่ hashmap |
| ชุด | nsset | ชุด | Set, hashset |
| การทำงาน | ปิดกั้น | การปิด | สัญญา |
| ตัวชี้ | เป็นโมฆะ * | unsafemutablerawpointer | - |
| Nativebyte | NSDATA | ข้อมูล | DirectByTebuffer |
| NativeObject | nsobject | nsobject | วัตถุ |
ขั้นตอนที่ 1: เพิ่ม dart_native ไปยังการพึ่งพาและ build_runner ให้กับ dev_dependencies
ขั้นตอนที่ 2: สร้างรหัส Wrapper Dart ด้วย @dartnative/codegen หรือเขียนรหัส DART ด้วยตนเอง
ขั้นตอนที่ 3: สร้างรหัสสำหรับการแปลงประเภทอัตโนมัติโดยใช้ dart_native_gen ด้วยขั้นตอนต่อไปนี้ (3.1-3.3):
3.1 คำอธิบายประกอบคลาส Wrapper Dart กับ @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 Run
flutter packages pub run build_runner build --delete-conflicting-outputs เพื่อสร้างไฟล์ลงในไดเรกทอรีต้นฉบับของคุณ
หมายเหตุ: เราแนะนำให้ใช้การ clean ก่อน:
flutter packages pub run build_runner clean ขั้นตอนที่ 4: การเรียกฟังก์ชั่นการทำงานแบบ autogenerated ใน <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:
รหัสโผ (สร้าง):
// 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 ที่สอดคล้องกัน:
typedef int (^BarBlock)( NSObject *a);
@interface RuntimeStub
- ( CGRect ) fooCGRect : ( CGRect ) rect ;
- ( void ) fooBlock : (BarBlock) block ;
@endตัวอย่าง iOS เพิ่มเติมดู: iOS_UNIT_TEST.DART
5.2 Android:
รหัสโผ (สร้าง):
// 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_native บน macOS คุณต้องใช้ use_frameworks! ใน Podfile ของคุณ
ถาม: ไม่สามารถค้นหาสัญลักษณ์ (DLSYM (RTLD_Default, InitDartapIdl): ไม่พบสัญลักษณ์) บน MACOS Archive
ตอบ: เลือกหนึ่งวิธี:
use_frameworks! ใน podfileDartnative สามารถใช้ได้ภายใต้ใบอนุญาต BSD 3-cluse ดูไฟล์ใบอนุญาตสำหรับข้อมูลเพิ่มเติม