Repository navigation
Conversation
- Add Native interop landing page with decision tree and layers guide - Add Pigeon guide covering platform channels and native bindings modes - Add FFIgen guide covering Apple frameworks, C-ABI, and developer flow - Add dart:ffi guide for native memory allocation and concurrency - Move bind-native-code into platform-integration/interop/ - Add JNIgen guide for Java/Kotlin and Android bindings - Update platform-channels to focus on manual message passing - Update sidenav default.yml with new Native interop section - Update firebase.json with 301 redirect for bind-native-code TAG=agy CONV=a76ca369-bcbf-4f8a-822b-b2d6bdd86f54
- Restore exact text, structure, and headings from the Google Doc - Remove extraneous code examples from developer flow sections TAG=agy CONV=a76ca369-bcbf-4f8a-822b-b2d6bdd86f54
|
Staged preview of the updated docs.flutter.dev site (updated for commit 650cbb7): https://flutter-docs-prod--docs-pr13995-native-interop-eap-n5ovjnbf.web.app |
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a comprehensive "Native interop" documentation section, adding new guides for dart:ffi, FFIgen, JNIgen, and Pigeon, along with an overview page to help developers choose the right interop solution. It also updates existing platform integration docs, sidebar navigation, and redirects to point to these new pages. A review comment points out an incorrect API reference in the JNIgen guide, suggesting the use of PlatformDispatcher.instance.scheduleOnPlatformThread instead of runOnPlatformThread.
sfshaza2
left a comment
There was a problem hiding this comment.
I have some quibbles but, overall, a great addition to the site! I like the decision graph and would be hesitant to clobber it. I also like the table comparing the approaches.
sfshaza2
left a comment
There was a problem hiding this comment.
lgtm, once my feedback is incorporated. I'll go ahead and approve, but I'd like approval from a SME. thx! Overall, this looks great!
tarrinneal
left a comment
There was a problem hiding this comment.
Just a couple little clarifications
There was a problem hiding this comment.
Code Review
This pull request restructures the documentation by introducing a new 'Native interop' section, adding dedicated guides for dart:ffi, FFIgen, JNIgen, and Pigeon, and updating existing files to link to these new paths. Feedback on these changes includes a suggestion to flatten the sidebar navigation under 'Native interop' to make dart:ffi and 'Bind to native code' more discoverable, as well as a correction in the FFIgen guide to use .cast<T>() instead of .as() for casting Objective-C objects to avoid compilation errors.
mariamhas
left a comment
There was a problem hiding this comment.
Left some comments that need to be addressed before this is published
| regenerate the bindings. | ||
| ::: | ||
|
|
||
| ## Examples |
There was a problem hiding this comment.
we should confirm with @liamappelbe if there is a published package on pub.dev that use jnigen that would be a good example to add here
| and regenerate the bindings. | ||
| ::: | ||
|
|
||
| ## Example |
There was a problem hiding this comment.
similar comment to jnigen doc, we definitely have packages on pub.dev that use ffigen in production. @liamappelbe or @jwill should be able to help choose the best one to include here as a good example as a reference
|
I recall there being a concept called "direct native interop" (or something similar)—what happened to it? Why hasn't there been any news about it lately? Edit |
goderbauer
left a comment
There was a problem hiding this comment.
There's still outdated verbiage in one places on the website, e.g.
https://docs.flutter.dev/platform-integration/android/call-jetpack-apis says:
In the coming months, the Dart team hopes to make this process easier with direct support for calling native APIs using the FFI approach...
Can we update that as well as part of this update?
|
|
||
| When you use FFIgen or JNIgen to generate Dart bindings, | ||
| the generated code doesn't automatically convert Dart objects | ||
| like `String` or `List` into native formats. |
There was a problem hiding this comment.
dart:ffi doesn't directly relate to converting strings and lists into native ObjC or Java formats (there are utils in package:ffi to convert Dart strings to C strings, but that's a bit different), so this sentence is a bit misleading. Might be better to remove this sentence (or the whole paragraph)?
| Dart memory is automatically garbage collected while native C memory is | ||
| manually managed, so use `dart:ffi` to bridge this gap. | ||
|
|
||
| The two most common scenarios when `dart:ffi` is needed are |
There was a problem hiding this comment.
Hmmm. All the memory allocation and string conversion utils are in package:ffi, not dart:ffi. This whole section sounds like it's talking about package:ffi.
|
|
||
| - **`dart:ffi`:** Built into the core Dart SDK. | ||
| It provides native representation types and lookup signatures. | ||
| - **`package:ffi`:** A required dependency for working with `dart:ffi`. |
There was a problem hiding this comment.
Not quite true that it's a required dependency. dart:ffi is required for doing FFI interop. package:ffi contains utils that are helpful in common C interop usecases.
|
|
||
| FFI calls are synchronous and run on the thread on which they're called. | ||
| If you invoke a heavy or blocking C function on your Flutter app's | ||
| main UI thread, your app freezes or drops frames. |
There was a problem hiding this comment.
How about: "your app may freeze or drop frames".
| FFIgen wrappers enforce Dart static types, | ||
| but the underlying Objective-C object might have a different runtime subclass, | ||
| so Dart's `is` and `as` keywords won't work as expected. | ||
| Use `.isA()` and `.as()` instead. |
There was a problem hiding this comment.
|
|
||
| UI-related Objective-C calls must run on the iOS main platform thread. | ||
| Also, some types of callbacks can crash your app | ||
| if they're executed on the wrong thread. |
There was a problem hiding this comment.
| JNI wrappers are Dart extension types that compile down to `JObject` | ||
| at runtime, so Dart's native `is` and `as` keywords don't check the Java | ||
| runtime type. | ||
| Use `x.isA(Foo.type)` and `x.as(Foo.type)` instead. |
There was a problem hiding this comment.
| There is a hard limit of 50,000 active references. | ||
| Call `.release()` or use `.using()` blocks to prevent memory leaks. | ||
| Use `WeakReference` to break reference cycles between Dart and Java GCs | ||
| when implementing interfaces. |
There was a problem hiding this comment.
| use [`runOnPlatformThread`][run-on-platform-thread] from `dart:ui`. | ||
| - Dart callbacks from Java run on the isolate that created them. | ||
| This can lead to deadlocks if a blocked Java thread waits for a blocked | ||
| Dart thread. |
There was a problem hiding this comment.
| Tracking down JNI memory allocation bugs like `DoubleReleaseError` | ||
| and `UseAfterReleaseError` can be difficult. | ||
| Set `Jni.captureStackTraceOnRelease = true` to log stack traces | ||
| and help trace leaks. |
There was a problem hiding this comment.
Description of what this PR is changing or adding, and why:
Adds the new top-level Native interop documentation section (
/interop) for the upcoming Flutter 3.50 / Native Interop GA release:/interop): Decision tree (Mermaid flowchart and step-by-step walkthrough), packaging options, tool comparison matrix, and 3-layer interop architecture./interop/pigeon): Covers Pigeon with native interop (direct FFI on iOS/macOS and JNI on Android) and Pigeon with platform channels, developer workflow, examples, and constraints./interop/ffigen): Covers generating C, Objective-C, and Swift bindings withtool/ffigen.dart, developer workflow, examples, and platform/runtime considerations./interop/jnigen): Covers generating Java and Kotlin bindings on Android withtool/jnigen.dart, developer workflow, examples, and threading/reference lifecycle considerations.dart:ffi(/interop/dart-ffi): Covers native memory allocation, data conversion (package:ffi), and isolate concurrency (Isolate.run)./interop/bind-native-code): Moved from/platform-integration/bind-native-codewith a 301 redirect infirebase.json./platform-integration/platform-channels): Updated to link to the new Native interop overview and dedicated Pigeon guide.sites/docs/src/data/sidenav/default.yml): Adds the top-level Native interop section above Platform integration.Issues fixed by this PR (if any):
PRs or commits this PR depends on (if any):
N/A (Draft for early review and staging preview before Flutter 3.50 release)
Presubmit checklist
of 80 characters or fewer.