パッケージ、リポジトリ、アプリカテゴリを検索

dart_native のカバー
パッケージ詳細v0.7.11

dart_native

Dartを使用してネイティブコードを書く。このパッケージは、ネイティブコードと低パフォーマンスのチャネルから解放します。

AndroidiOSmacOS
30日間ダウンロード
138
いいね数
23
Pub ポイント
125

パッケージをインストール

flutter pub add dart_native

パッケージ概要

公開情報に基づく選定ガイドです。参考としてご利用ください。

Dart_Native は、開発者が Dart で直接ネイティブなモバイルおよびデスクトップアプリケーションを記述できるようにし、プラットフォーム固有のコードやパフォーマンス負荷の高い相互運用チャネルの必要性を排除します。Dart の強力な型付けと現代的な構文を活用することで、Android、iOS、macOS でのネイティブ API へのシームレスなアクセスが可能になります。このパッケージは、高レベルの Dart 開発と低レベルのシステム機能の間のギャップを埋め、複数のプラットフォームにわたる統一されたワークフローを提供します。単一のコードベースを維持しつつ、ネイティブなパフォーマンスとデバイス機能へのアクセスを実現したいチームにとって理想的です。

用途

  • クロスプラットフォームアプリ開発
  • Dart からのネイティブ API アクセス
  • プラットフォーム固有のコードの削除
  • 高パフォーマンスなモバイルアプリ
  • 複数のプラットフォーム向けの統合コードベース

主な機能

  • Dartでのネイティブコードの直接記述
  • Android、iOS、macOS のサポート
  • 低パフォーマンスなチャネルに頼らない
  • ネイティブAPIとのシームレスな統合
  • 複数のプラットフォーム用の単一コードベース

適している対象

  • モバイル/デスクトップアプリ用にDartを使用する開発者
  • ネイティブ言語の複雑さを回避するチーム
  • ネイティブパフォーマンスを必要とするプロジェクト
  • クロスプラットフォームアプリケーション開発
  • ボイラープレートや相互運用のオーバーヘッドを減らしたい人

注意事項

  • 成熟したネイティブツールと比較してエコシステムが限定的
  • 初期段階での導入には、より深いデバッグが必要になる場合があります
  • ネイティブプラットフォームのコンセプトを理解する必要があります
  • まだすべてのニッチなネイティブ機能をサポートしていない可能性があります
  • ネイティブ統合パターンに馴染みのない開発者の学習曲線

元の README

関連するソースリポジトリの README 原文のスナップショットです。最新の内容はリポジトリをご覧ください。

DartNative

DartNative operates as a bridge to communicate between Dart and native APIs.

Replaces the low-performing Flutter channel with faster and more concise code.

pub package Build Status Dart CI

Features

Dynamic synchronous & asynchronous channeling

DartNative calls any native API dynamically. It supports both synchronous and asynchronous channeling.

Direct call between multi-language interfaces

Serialization of parameters and return values like Flutter Channel is no longer required. DartNative provides direct calls and automatic object marshalling between language interfaces.

Dart finalizer

Dart finalizer is only supported above Flutter 3(Dart 2.17), but with DartNative it is available in Dart Flutter 2.2.0(Dart 2.13.0) and up.

Autogenerate succinct bridging code

DartNative supports automatic type conversion so its bridging code is shorter & simpler than the Flutter channel.

The design and vision of this package:

Requirements

DartNative Version Flutter Requirements 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 Flutter 1.12.13 (Dart 2.7) 1.x

Supported Platforms

iOS & macOS & Android

Usage

Basic usage: Interface binding

Add dart_native to dependencies and build_runner to dev_dependencies. Then you can write code. Here are some examples:

Dart calls Native

Dart code:

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]);
}

Corresponding Objective-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);
}

@end

Corresponding 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;
    }
}

NOTE: If your so path is custom, you need pass specific path.

DartNativePlugin.loadSoWithCustomPath("xxx/libdart_native.so");

And before using DartNative in dart, first invoke dartNativeInitCustomSoPath(). It will get path from channel.

Native calls Dart

Dart code:

interface.setMethodCallHandler('totalCost',
        (double unitCost, int count, List list) async {
    return {'totalCost: ${unitCost * count}': list};
});

Corresponding Objective-C code:

[self invokeMethod:@"totalCost"
         arguments:@[@0.123456789, @10, @[@"testArray"]]
            result:^(id _Nullable result, NSError * _Nullable error) {
    NSLog(@"%@", result);
}];

Corresponding 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
                }
              }
);
Dart finalizer
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.
});
Data types support
Dart Objective-C Swift Java
null nil nil null
bool BOOL Bool bool
int NSInteger Int int
double double Double double
String NSString String String
List NSArray Array List, ArrayList
Map NSDictionary Dictionary Map, HashMap
Set NSSet Set Set, HashSet
Function Block Closure Promise
Pointer void * UnsafeMutableRawPointer -
NativeByte NSData Data DirectByteBuffer
NativeObject NSObject NSObject Object
Advanced usage: Invoke methods dynamically
  • Step 1: Add dart_native to dependencies and build_runner to dev_dependencies.

  • Step 2: Generate Dart wrapper code with @dartnative/codegen or write Dart code manually.

  • Step 3: Generate code for automatic type conversion using dart_native_gen with the following steps (3.1-3.3):

    • 3.1 Annotate a Dart wrapper class with @native.

      @native
      class RuntimeSon extends RuntimeStub {
        RuntimeSon([Class isa]) : super(Class('RuntimeSon'));
        RuntimeSon.fromPointer(Pointer<Void> ptr) : super.fromPointer(ptr);
      }
      
    • 3.2 Annotate your own entry (such asmain()) with @nativeRoot.

      @nativeRoot
      void main() {
        runApp(App());
      }
      
    • 3.3 Run

      flutter packages pub run build_runner build --delete-conflicting-outputs 
      

      to generate files into your source directory.

      Note: we recommend running clean first:

      flutter packages pub run build_runner clean
      
  • Step 4: Call autogenerated function in <generated-name>.dn.dart in 3.3. The function name is determined by name in pubspec.yaml.

    @nativeRoot
    void main() {
      // Function name is generated by name in pubspec.yaml.
      runDartNativeExample(); 
      runApp(App());
    }
    
  • Step 5: Then you can write code. Here are some examples:

    • 5.1 iOS:

      Dart code (generated):

      // 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);
      
      

      Corresponding Objective-C code:

      typedef int(^BarBlock)(NSObject *a);
      
      @interface RuntimeStub
      
      - (CGRect)fooCGRect:(CGRect)rect;
      - (void)fooBlock:(BarBlock)block;
      
      @end
      

      More iOS examples see: ios_unit_test.dart

    • 5.2 Android:

      Dart code (generated):

      // new Java object.
      RuntimeStub stub = RuntimeStub();
      
      // get java list.
      List list = stub.getList([1, 2, 3, 4]);
      
      // support interface.
      stub.setDelegateListener(DelegateStub());
      
      

      Corresponding 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);
          }
      }
      

      More android examples see: android_unit_test.dart

NOTE: If you use dart_native on macOS, you must use use_frameworks! in your Podfile.

Documentation

Further reading

FAQs

Q: Failed to lookup symbol (dlsym(RTLD_DEFAULT, InitDartApiDL): symbol not found) on macOS archive.

A: Select one solution:

  1. Use dynamic library: Add use_frameworks! in Podfile.
  2. Select Target Runner -> Build Settings -> Strip Style -> change from "All Symbols" to "Non-Global Symbols"

Contribution

  • If you need help or you'd like to ask a general question, open an issue.
  • If you found a bug, open an issue.
  • If you have a feature request, open an issue.
  • If you want to contribute, submit a pull request.

License

DartNative is available under the BSD 3-Clause License. See the LICENSE file for more info.

カテゴリー

依存関係

依存関係一覧 2 件

  • dart_native_gen^0.3.3
  • ffi>=1.1.2 <3.0.0

ソースリポジトリ

このパッケージを使用しているプロジェクト

データはまだありません。