"I want to use the excellent assets of C / C ++ in ** Flutter **.
There is an issue "Support integrating with C / C ++ in plugin framework" in the Flutter repository. Unfortunately it looks tough ... (as of June 16, 2018) Let's like a lot to get higher priority! !! !!
In addition, Dart => C / C ++ can be go
Run through with "** Flutter / Dart => Java / Swift => C / C ++**"![^ 1] This time, I will take Android / Java as an example. Of course Kotlin is fine too.
Just Hello World
** platform channels ** will be used.
flutter create -i swift -a java helloworld
Copy the following to main.dart
main.dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
static const platform = const MethodChannel('helloworld/hello');
String _greeting = 'Nothing';
Future<Null> _getGreeting() async {
String greeting;
try {
final String result = await platform.invokeMethod('getGreeting');
greeting = result;
} on PlatformException catch (e) {
greeting = "Failed to get greeting: '${e.message}'.";
}
setState(() {
_greeting = greeting;
});
}
@override
Widget build(BuildContext context) {
return new Material(
child: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
new RaisedButton(
child: new Text('Get Greeting'),
onPressed: _getGreeting,
),
new Text(_greeting),
],
),
),
);
}
}
There are three points.
--static const platform = const MethodChannel ('helloworld / hello');
← ** MethodChannel ** specified
--Future <Null> _getGreeting () async {}
← ** Asynchronous ** call
--ʻAwait platform.invokeMethod ('getGreeting'); `← ** Specify method name ** and call
Now that Dart => Java is good, let's write Java => C / C ++ Official document is a must read.
Open only the * android directory * of the previous project in Android Studio. Then open Tool> SDK Manager> SDK Tools and install the following.
Added cpp directory to main directory. (The name can be anything, but this time it will be cpp)
Then add native-lib.c
to the cpp directory and copy and paste the following.
native-lib.c
#include <string.h>
#include <jni.h>
jstring
Java_com_example_helloworld_MainActivity_getGreetingFromJNI( JNIEnv* env, jobject thiz ) {
return (*env)->NewStringUTF(env, "Hello World. I'm Android.");
}
The function name should be "** Java_path to reach the target java file \ _Hoge.java_method name **".
Create CMakeLists.txt
in the app directory and copy and paste the following
CMakeLists.txt
# Sets the minimum version of CMake required to build your native library.
# This ensures that a certain set of CMake features is available to
# your build.
cmake_minimum_required(VERSION 3.4.1)
# Specifies a library name, specifies whether the library is STATIC or
# SHARED, and provides relative paths to the source code. You can
# define multiple libraries by adding multiple add.library() commands,
# and CMake builds them for you. When you build your app, Gradle
# automatically packages shared libraries with your APK.
add_library( # Specifies the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/native-lib.c )
# Specifies a path to native header files.
include_directories(src/main/cpp/include/)
The last line tells you the location of the header file. I don't need to use the header file this time, but I wrote it because it should be used normally.
Copy the following.
MainActivity.java
package com.example.helloworld;
import android.os.Bundle;
import io.flutter.app.FlutterActivity;
import io.flutter.plugins.GeneratedPluginRegistrant;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "helloworld/hello";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
new MethodCallHandler() {
@Override
public void onMethodCall(MethodCall call, Result result) {
if (call.method.equals("getGreeting")) {
String greeting = getGreeting();
result.success(greeting);
} else {
result.notImplemented();
}
}
});
}
private String getGreeting() {
return getGreetingFromJNI();
}
public native String getGreetingFromJNI();
static {
System.loadLibrary("native-lib");
}
}
3 points
--private static final String CHANNEL = "helloworld / hello";
← ** Specify the same Channel name ** as before
--static {System.loadLibrary ("native-lib");}
← .so
The file is loaded.
--public native String getGreetingFromJNI ();
← ** Specify the previously defined C method **
It should look like this (The com.example.ndktest part is com.example.helloworld this time)
Select File> Invalidate Caches / Restart ... to restart
If you can get the behavior like [Demo](#Complete demo), it's OK!
It's a hassle to write both java and swift to call C / C ++. I can't wait for the github issue to be resolved ...
[^ 1]: The reason for choosing Java is that the amount of information about NDK is Java> Kotlin.
Recommended Posts