当前位置: 首页 > 软件库 > 手机/移动开发 > >

dart_native

授权协议 Readme
开发语言 Java
所属分类 手机/移动开发
软件类型 开源软件
地区 不详
投 递 者 杜砚
操作系统 跨平台
开源组织
适用人群 未知
 软件概览

Dart_Native

Dart_Native operates as both a code generator tool and a bridge to communicate between Dart and native APIs.

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

  • Under development

This package is the blue part(DartNative Bridge):

Requirements

Dart_Native Version Requirements
0.3.0 Flutter 1.20.0 (Dart 2.9.1)
0.2.0 Flutter 1.12.13 (Dart 2.7)

Supported Platforms

iOS & Android

Usage

  1. Add dart_native to dependencies and build_runner to dev_dependencies.

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

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

Features

High-performance synchronous & asynchronous channeling

Dart_Native costs significantly less time than the Flutter channel and supports both synchronous and asynchronous channeling. A comparison of two native channeling tasks using Flutter channel and Dart_Native is shown below.

Both tasks were executed 10,000 times in the same environment using either Flutter channel or Dart_Native:

Task Total time cost (ms) (Channel/Dart_Native) Channeling time cost (ms) (Channel/Dart_Native)
Checking if an app needs to be installed 5202/4166 919/99
Logging 2480/2024 1075/432

Autogenerate succinct bridging code

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

A comparison of the task of "checking if an app needs to be installed" is shown below:

# of lines of bridging code Coding complexity
Dart_Native Dart 1 + Native 1 Autogenerated code returns BOOL directly
Channel Dart 15 + Native 30 Needs to manually define return format, convert INT to BOOL, determine channel & methodName

Automatic object marshalling between Dart and native

Examples

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

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

Documentation

Readme

  1. dart_native README.md
  2. dart_native_gen README.md

Further reading

FAQs

Q: Failed to lookup symbol (dlsym(RTLD_DEFAULT, InitDartApiDL): symbol not found) on iOS 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.

  • flutter dart 有点背景 (A bit of background) It all began in 2011: Xamarin, now a Microsoft-owned company, came up with a solution for hybrid mobile apps through its signature product, Xamarin SDK with C#.

  • Dart API 扩展 dart vm 里面其实提供了 dart 跟 cpp 之间的相互调用接口,开发者可以基于这个接口自行扩展 dart 的 api, 那么就来看看 dart vm 以及 flutter 是如何做到的。 Dart VM Dart VM中提供了以下接口: DART_EXPORT Dart_Handle Dart_SetNativeResolver(Dart_Handle libra