プロジェクトの背景
少し前に、社内でAndroid SDKの開発を担当し、関連するドッキングドキュメントを作成しました。開発が完了したら、いくつかのパートナーとドッキングします。
ただし、一部の企業のプロジェクトはFlutterで記述されており、SDKに対応するFlutterプラグインを記述して、相手に提供する必要があります。はためく?ありえない!
ははは、でも大胆不敵なプログラマーとして、それを認めることはできますか?もちろんできません(弾丸を噛む)
最終週には、対応するFlutterプラグインが開発され、配信されます。以下は、Android SDKFlutterプラグインを開発するための私の学習の要約です。
総括する
最初はすべてが難しいですが、フラッター環境がすでに成熟している場合は、まったく慌てる必要はありません。
最初のステップは、フラッターがAndroidネイティブコードを呼び出す方法を理解することです
ブログをお勧めします。自分で検索できる優れたブログがたくさんあります:https://developer.aliyun.com/article/697792
参照用に使用できる、より適切に記述されていると思うオープンソースのフラッタープラグインもあります:https://github.com/OpenFlutter/Pangolin
設置環境
WindowsオペレーティングシステムにFlutter開発環境をインストールして構成します
プラグインプロジェクトを作成する
環境がセットアップされたら、Androidスタジオ->ファイル->新規->新しいフラッタープロジェクト->フラッタープラグインの選択を開きます
作成が成功したら、プロジェクトを開いてこのディレクトリ構造を確認します。Androidプラグインの作成についてもっと心配しています。
プラグインを書く
プロジェクト自体によって生成されたプラグインデモであるandroidディレクトリにあるFlutterPluginファイルを開きます。このウィンドウでは、コンパイルには影響しませんが、多くのネイティブAndroidコードが人気があることを見つけるのは難しくありません。
しかし、それは不快に見えます。右上隅にある[Android Studioで編集用に開く]を選択し、別のウィンドウで開くことを選択すると、問題ありません。
自動生成されたプラグインコードを見てみましょう。FlutterPlugin、MethodCallHandlerを実装するKotlin構文を次に示します。
/** FlutterPlugin */
public class FlutterPlugin: FlutterPlugin, MethodCallHandler {
...
private lateinit var channel : MethodChannel
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
channel = MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "flutter_plugin")
channel.setMethodCallHandler(this);
}
...
companion object {
@JvmStatic
fun registerWith(registrar: Registrar) {
val channel = MethodChannel(registrar.messenger(), "flutter_plugin")
channel.setMethodCallHandler(FlutterPlugin())
}
}
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
if (call.method == "getPlatformVersion") {
result.success("Android ${android.os.Build.VERSION.RELEASE}")
} else {
result.notImplemented()
}
}
override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
channel.setMethodCallHandler(null)
}
}
その中で、MethodCallHandlerインターフェイスはonMethodCall(MethodCall call, MethodChannel.Result result)
メッセージの受信に使用されます。
ここで受信したメッセージはFlutterプロジェクトからのものであり、呼び出しはメッセージの内容であり、call.method
呼び出されたメソッドの名前を表すString型の2つのメンバー変数があります。
オブジェクトタイプcall.arguments
は、呼び出し元のメソッドによって渡される入力パラメーターを表します。
コーディングを開始し、androidディレクトリのbuild.gradleに独自のAndroidプロジェクトのSDK依存関係を追加します。
implementation 'com.jayxu.android:***Sdk:1.0.1'
自動生成されたプラグインコードに基づいてプロジェクトを開発します。プラグインでは、ネイティブアクティビティ間のジャンプのために現在のアクティビティオブジェクトも取得する必要があります。
そこで、ActivityAwareも実装しました。具体的な用途については、コード(Kotlinの記述)を参照してください。
/** PedesxpluginPlugin */
public class PedesxpluginPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
...
private lateinit var channel: MethodChannel
private lateinit var applicationContext: Context
private lateinit var activity: Activity
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
onAttachedToEngine(flutterPluginBinding.applicationContext, flutterPluginBinding.binaryMessenger)
}
fun onAttachedToEngine(applicationContext: Context, messenger: BinaryMessenger) {
this.applicationContext = applicationContext
channel = MethodChannel(messenger, "pedesxplugin")
channel.setMethodCallHandler(this)
}
fun onAttachedToEngine(applicationContext: Context, messenger: BinaryMessenger, activity: Activity) {
this.applicationContext = applicationContext
channel = MethodChannel(messenger, "pedesxplugin")
channel.setMethodCallHandler(this)
this.activity = activity
}
...
companion object {
@JvmStatic
fun registerWith(registrar: Registrar) {
val instance = PedesxpluginPlugin()
instance.onAttachedToEngine(registrar.context(), registrar.messenger(), registrar.activity())
}
}
/**
* 最主要的回调方法
*/
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
if (call.method == "getPlatformVersion") {
result.success("Android ${android.os.Build.VERSION.RELEASE}")
} else if (call.method == "registerPedesx") {
val appId: String? = call.argument("appId")
val shelf_id: String? = call.argument("shelf_id")
val csj_appId: String? = call.argument("csj_appId")
val csj_video_id: String? = call.argument("csj_video_id")
//初始化SDK
PedesxUtil.init(applicationContext, appId, shelf_id, csj_appId, csj_video_id)
} else if (call.method == "registerPedesxUser") {
val uid: String? = call.argument("uid")
val oaid: String? = call.argument("oaid")
//初始化SDK的User信息
PedesxUtil.initUser(applicationContext, uid, oaid)
} else if (call.method == "startPedesxVideoActivity") {
//跳转我们自己SDK的界面1
ActivityUtils.startActivity(activity, Demo1Activity::class.java)
} else if (call.method == "startPedesxWelfareActivity") {
//跳转我们自己SDK的界面2
ActivityUtils.startActivity(activity, Demo2Activity::class.java)
} else {
result.notImplemented()
}
}
override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
channel.setMethodCallHandler(null)
}
override fun onDetachedFromActivity() {
}
override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
}
override fun onAttachedToActivity(binding: ActivityPluginBinding) {
this.activity = binding.activity
}
override fun onDetachedFromActivityForConfigChanges() {
}
}
この時点で、Androidプラグインの部分はすべて書かれていますが、それは非常に簡単ですか?
プラグインの使用方法
プラグインは作成されていますが、Flutterプロジェクトはプラグインをどのように使用しますか?作業は続行されます
flutterプラグインプロジェクトに戻り、libディレクトリに新しいdartファイルを作成します。以下はコード例です。すべてを記述したわけではありません。基本的な記述は似ています。このファイルは、主にAndroidプラグイン部分のコードをサンプルプロジェクトにカプセル化します。使用する。
...
MethodChannel _channel = MethodChannel('pedesxplugin')
..setMethodCallHandler(_methodHandler);
StreamController<BasePedesxResponse> _pedesxResponseEventHandlerController =
new StreamController.broadcast();
Stream<BasePedesxResponse> get pedesxResponseEventHandler =>
_pedesxResponseEventHandlerController.stream;
Future _methodHandler(MethodCall methodCall) {
var response =
BasePedesxResponse.create(methodCall.method, methodCall.arguments);
_pedesxResponseEventHandlerController.add(response);
return Future.value();
}
Future<bool> initPedesxSdk({
@required String appId, //SDK APPId
@required String shelf_id, //注释1
@required String csj_appId, //注释2
@required String csj_video_id, //注释3
}) async {
return await _channel.invokeMethod("registerPedesx", {
"appId": appId,
"shelf_id": shelf_id,
"csj_appId": csj_appId,
"csj_video_id": csj_video_id,
});
}
Future<bool> initPedesxSdkUser({
@required String uid,
@required String oaid,
}) async {
return await _channel
.invokeMethod("registerPedesxUser", {"uid": uid, "oaid": oaid});
}
Future<bool> startPedesxVideoActivity() async {
return await _channel.invokeMethod("startPedesxVideoActivity");
}
Future<bool> startPedesxWelfareActivity() async {
return await _channel.invokeMethod("startPedesxWelfareActivity");
}
...
ここでは、Androidプラグインのコードの一部と、フラッターがプラグインを呼び出すコードの一部を比較します。それは明らかですか?
android 插件代码:
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
...
if (call.method == "registerPedesx") {
val appId: String? = call.argument("appId")
val shelf_id: String? = call.argument("shelf_id")
val csj_appId: String? = call.argument("csj_appId")
val csj_video_id: String? = call.argument("csj_video_id")
//初始化SDK
PedesxUtil.init(applicationContext, appId, shelf_id, csj_appId, csj_video_id)
}
...
}
-----------------------这是一条分界线---------------------------
flutter代码:
Future<bool> initPedesxSdk({
@required String appId, //SDK APPId
@required String shelf_id, //货架ID
@required String csj_appId, //穿山甲APPID
@required String csj_video_id, //穿山甲激励视频ID
}) async {
return await _channel.invokeMethod("registerPedesx", {
"appId": appId,
"shelf_id": shelf_id,
"csj_appId": csj_appId,
"csj_video_id": csj_video_id,
});
}
最後のサンプルプロジェクトは、プラグインのダーツコードの一部を呼び出します。
_initPedesxSdk() async{
/**
* 初始化SDK
* appID:此为注释
* shelf_id:此为注释
* csjAppId:此为注释
* codeId:此为注释
*/
await Pedesxplugin.initPedesxSdk(
appId: "***",
shelf_id: "***********",
csj_appId: "*****",
csj_video_id: "*******",
);
}
コードの一部にはプロジェクトのプライバシーが含まれているため、すべてを投稿することはできません。子供用の靴について質問がある場合は、プロジェクトhttps://github.com/OpenFlutter/Pangolinを確認することを強くお勧めします。