Flutter混合開發-通信


參考:https://www.jianshu.com/p/1a131deeee75

參考:https://www.jianshu.com/p/1770ded8f50f

 

 

一.混編

1.咸魚模式 

Flutter打包成aar嵌入到原生工程

 

2.Google模式,Flutter頁面嵌入原生

public class MyFlutterActivity extends FragmentActivity {


    FlutterFragment flutterFragment;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_flutter);
        
        initFlutterEngine();
        attachFlutterFragment();
    }


    String ENGINE_ID = "a";

    private FlutterEngine initFlutterEngine() {
        FlutterEngine flutterEngine = FlutterEngineCache.getInstance().get(ENGINE_ID);

        if (null == flutterEngine) {
            flutterEngine = new FlutterEngine(this);
            flutterEngine.getNavigationChannel().setInitialRoute("/");
            flutterEngine.getDartExecutor().executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault());
            FlutterEngineCache
                    .getInstance()
                    .put(ENGINE_ID, flutterEngine);
            messageChannelFunction(this,flutterEngine);
        }
        return flutterEngine;
    }

    private void attachFlutterFragment() {
        if (null == flutterFragment) {
            flutterFragment =
                    FlutterFragment.withCachedEngine(ENGINE_ID)
                            .shouldAttachEngineToActivity(true)
                            .build();
        }
        getSupportFragmentManager()
                .beginTransaction()
                .add(R.id.container, flutterFragment)
                .commit();
    }
}

  二.通信

1.BasicMessageChannel 方式

跨Native,Flutter發送消息可接收消息

1.1Flutter端給原生發消息

//Flutter 端

 //創建 BasicMessageChannel
  // flutter_and_native_100 為通信標識
  // StandardMessageCodec() 為參數傳遞的 編碼方式
  static const messageChannel = const BasicMessageChannel(
      'flutter_and_native_100', StandardMessageCodec());

  //發送消息
  Future<Map> sendMessage(Map arguments) async {
    Map reply = await messageChannel.send(arguments);
    //解析 原生發給 Flutter 的參數
    int code = reply["code"];
    String message = reply["message"];

    //更新 Flutter 中頁面顯示
    setState(() {
      _counter = "code:$code message:$message";
    });
    return reply;
  }

  //原生端

 private BasicMessageChannel<Object> mMessageChannel;

    private void messageChannelFunction(Context mContext, FlutterEngine flutterEngine) {
        //消息接收監聽
        //BasicMessageChannel (主要是傳遞字符串和一些半結構體的數據)
        //創建通
        mMessageChannel = new BasicMessageChannel<Object>(flutterEngine.getDartExecutor(), "flutter_and_native_100", StandardMessageCodec.INSTANCE);
        // 接收消息監聽
        mMessageChannel.setMessageHandler(new BasicMessageChannel.MessageHandler<Object>() {
            @Override
            public void onMessage(Object o, BasicMessageChannel.Reply<Object> reply) {

                Map<Object, Object> arguments = (Map<Object, Object>) o;

                //方法名標識
                String lMethod = (String) arguments.get("method");

                //測試 reply.reply()方法 發消息給Flutter
                if (lMethod.equals("test")) {
                    Toast.makeText(mContext, "flutter 調用到了 android test", Toast.LENGTH_SHORT).show();
                    //回調Flutter
                    Map<String, Object> resultMap = new HashMap<>();
                    resultMap.put("message", "reply.reply 返回給flutter的數據");
                    resultMap.put("code", 200);
                    //回調 此方法只能使用一次
                    reply.reply(resultMap);

                } else if (lMethod.equals("test2")) {
                    //測試 mMessageChannel.send 發消息給Flutter
                    //Android 可通過這個方法來主動向 Flutter中發送消息
                    //只有Flutter 中注冊了消息監聽 才能接收到這個方法向 Flutter 中發送的消息
//                    channelSendMessage();
                } else if (lMethod.equals("test3")) {
                    //測試通過Flutter打開Android Activity
                    Toast.makeText(mContext, "flutter 調用到了 android test3", Toast.LENGTH_SHORT).show();
                    Intent lIntent = new Intent(MyFlutterActivity.this, TestBasicMessageActivity.class);
                    mContext.startActivity(lIntent);
                }
            }
        });

    }

  1.2 原生給Flutter發消息

//原生端

private void channelSendMessage() {
        mMessageChannel = new BasicMessageChannel<Object>(initFlutterEngine().getDartExecutor(), "flutter_and_native_100", StandardMessageCodec.INSTANCE);

        Toast.makeText(this, "flutter 調用到了 android test", Toast.LENGTH_SHORT).show();
        //構建參數
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("message", "reply.reply 返回給flutter的數據");
        resultMap.put("code", 200);
        //向 Flutter 中發送消息
        //參數 二可以再次接收到 Flutter 中的回調
        //也可以直接使用 mMessageChannel.send(resultMap)
        mMessageChannel.send(resultMap, new BasicMessageChannel.Reply<Object>() {
            @Override
            public void reply(Object o) {
                Log.d("mMessageChannel", "mMessageChannel send 回調 " + o); //消息沒有收到???
            }
        });
    }

  //Fluttrer 端

 void messageChannelFunction(){
    messageChannel.setMessageHandler((message) async {
      print('message: $message');
      return '返回Native端的數據001';//這是native端的響應 ,執行了
    });
  }

  

2.MethodChannel 方式  

直接跨Native,Flutter調用方法

2.1 Native端 發送 + 監聽接收

/**
     * 設置MethodChannel 監聽
     *
     * @param flutterEngine
     */
    private void setMethodChannel(FlutterEngine flutterEngine) {
        MethodChannel channel = new MethodChannel(flutterEngine.getDartExecutor(), "study_3/methodChannel");
        channel.setMethodCallHandler(new MethodChannel.MethodCallHandler() {
            @Override
            public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
                switch (methodCall.method) {
//                        case NATIVE_METHOD_LOGIN:
//                            login(context, (String) methodCall.argument("phone"), (String) methodCall.argument("code"));
//                            break;
                }
            }
        });
    }

    private void invokeMethodChannel(FlutterEngine flutterEngine) {
        MethodChannel channel = new MethodChannel(flutterEngine.getDartExecutor(), "cn.withflutter.plugins.flutter");
        //在Android端調用Flutter中的getInputParams方法,參數是以Json的格式傳遞。這里是無參方法使用null
        channel.invokeMethod("getInputParams", "{'arg1':'來自Native'}", new MethodChannel.Result() {

            @Override
            public void success(@Nullable Object result) {

            }

            @Override
            public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) {

            }

            @Override
            public void notImplemented() {

            }
        });
    }

  2.2 Flutter端 發送+監聽接收

class PluginChannel {
  static const _methodChannelName = "study_3/methodChannel";
  static const _methodChannel = MethodChannel(_methodChannelName);

  static void invokeMethod() {
    _methodChannel.invokeMethod("getAge", {"name": "lili"}).then((result) {
      print('flutter receive response:$result');
    });
  }

  static void listenMethod() {
    _methodChannel.setMethodCallHandler((methodCall) async {
      print('flutter listen:$methodCall');
      return "男";
    });
  }
}

  3.EventChannel 模式

EventChannel並沒有分別提供發送和收聽消息的方法,它只提供了一個receiveBroadcastStream方法,用於發送消息,同時返回一個流(Stream),用於監聽平台插件成功返回的所有事件信息,這個流可以被監聽 不止一次。因此我們可以用於native端需要持續傳遞數據到flutter的情況,比如監聽電量,調用攝像頭等等
 
flutter:
class PluginChannel {

  static const _eventChannelName = "study_3/eventChannel";
  static const _eventChannel = EventChannel(_eventChannelName);

  static void event() {
    _eventChannel.receiveBroadcastStream("event arg")
        .listen((result) {
      print('flutter listen:$result');
    });
  }
}

  

android:

private void eventChannelDemo(FlutterEngine flutterEngine){
EventChannel channel = new EventChannel(flutterEngine.getDartExecutor(),"study_3/methodChannel");
channel.setStreamHandler(new EventChannel.StreamHandler() {
@Override
public void onListen(Object arguments, EventChannel.EventSink events) {
events.success(1);
events.success(2);
events.success(3);
events.success(4);
events.endOfStream();
}

@Override
public void onCancel(Object arguments) {

}
});

}

  



 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM