A Flutter application that demonstrates how to integrate Go code with Flutter using Foreign Function Interface (FFI).
demo.mp4
This project showcases how to leverage Go's powerful features within a Flutter application through FFI (Foreign Function Interface). As a practical example, the app allows users to enter a GitHub username and fetch their profile avatar using a Go function that makes HTTP requests.
-
Flutter UI: The app provides a simple interface where users can enter a GitHub username and click a button to fetch the avatar.
-
Go Backend: A Go function (
GetGithubAvatar) handles the HTTP request to GitHub's API to retrieve the user's avatar image. -
FFI Bridge: Flutter communicates with the Go code through FFI, allowing seamless integration between the two languages.
- Uses Dart FFI to call the compiled Go function
- Handles the UI and user interactions
- Processes and displays the returned image data
- Makes HTTP requests to GitHub's API
- Processes the response and extracts the avatar image
- Returns the image data back to Flutter
- Flutter SDK
- Go compiler
- FFI package for Flutter
- Android NDK or Xcode for compilation
First, create the necessary jniLibs directories if they don't exist:
mkdir -p android/app/src/main/jniLibs/arm64-v8a
mkdir -p android/app/src/main/jniLibs/armeabi-v7a
mkdir -p android/app/src/main/jniLibs/x86
mkdir -p android/app/src/main/jniLibs/x86_64Then build for each architecture:
# For arm64
GOOS=android GOARCH=arm64 CGO_ENABLED=1 CC=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin/aarch64-linux-android21-clang go build -buildmode=c-shared -o android/app/src/main/jniLibs/arm64-v8a/github_avatar.so go_files/github_avatar.go
# For arm
GOOS=android GOARCH=arm CGO_ENABLED=1 CC=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin/armv7a-linux-androideabi21-clang go build -buildmode=c-shared -o android/app/src/main/jniLibs/armeabi-v7a/github_avatar.so go_files/github_avatar.go
# For x86
GOOS=android GOARCH=386 CGO_ENABLED=1 CC=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin/i686-linux-android21-clang go build -buildmode=c-shared -o android/app/src/main/jniLibs/x86/github_avatar.so go_files/github_avatar.go
# For x86_64
GOOS=android GOARCH=amd64 CGO_ENABLED=1 CC=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin/x86_64-linux-android21-clang go build -buildmode=c-shared -o android/app/src/main/jniLibs/x86_64/github_avatar.so go_files/github_avatar.goNote: The path to your NDK might be different. Adjust accordingly.
go build -buildmode=c-archive -o ios/Runner/github_avatar.a go_files/github_avatar.goAfter generating the .a file, you'll need to add it to your Xcode project:
- Open the iOS project in Xcode
- Drag the
github_avatar.aandgithub_avatar.hfiles into your project - Add the library to "Link Binary With Libraries" in your target's Build Phases
go build -buildmode=c-shared -o github_avatar.so go_files/github_avatar.go- Ensure the Go shared library is in the correct location
- Run the Flutter app:
flutter run
lib/github_avatar.dart: Contains the Dart FFI bindings to call the Go functionlib/main.dart: The main Flutter applicationgo_files/github_avatar.go: The Go code that fetches GitHub avatars
// Import the GitHub avatar library
import 'github_avatar.dart';
// Fetch an avatar
final avatarBytes = GithubAvatar.getAvatar('username');
// Display it
if (avatarBytes.isNotEmpty) {
Image.memory(avatarBytes)
}FFI provides several advantages over Method Channel:
- Direct Memory Access: No serialization/deserialization overhead
- Reduced Context Switching: Calls happen within the same thread context
- Lower Latency: Significantly faster for large data transfers like images
- No Message Passing: Avoids the overhead of passing messages between isolates
This project is open source and available under the MIT License.