推广

Flutter Plugin 开发过程,详细记录

iseeyu3年前 (2024-02-22)推广121

BinaryMessage.png

Flutter端对三种Channel的书写

1、定义

//字符串需和原生保持一致
  MethodChannel _methodChannel = MethodChannel("flutter/live/methodChannel");
  EventChannel _eventChannel = EventChannel("flutter/live/eventChannel");
  BasicMessageChannel _messageChannel = BasicMessageChannel("flutter/live/messageChannel", StandardMessageCodec());

2、原生调用Flutter

_methodChannel.setMethodCallHandler((call) async {
      print('_methodChannel 收到:' + call.toString());
    });
_eventChannel.receiveBroadcastStream().listen((event) {
      print('_eventChannel 收到:' + event);
    });
_messageChannel.setMessageHandler((message) async {
      print('_messageChannel 收到:' + message);
    });

3、Flutter调用原生

_methodChannel.invokeMethod("startLive",{"url" : "rtmp://192.168.101.164"});

Map msg = {"startLive":"rtmp://192.168.101.164"};
                _messageChannel.send(msg);

原生端实现书写

两种方案
1、创建flutter plugin项目。

  • 1.1 上传https://pub.flutter-io.cn/ 或github,在Flutter项目中引用
dio: ^3.0.6
  • 1.2 本地引用
flutter_ijkplayer:
    path:
      plugins/flutter_ijkplayer

2、直接在Flutter项目文件夹下的iOS文件夹和Android文件夹中写实现逻辑,所以这种方案只能在本项目使用。

iOS端对三种Channel的书写

1、创建
- (void)createMethodChannel:(NSObject<FlutterPluginRegistrar>*)registrar {
    FlutterMethodChannel* methodChannel = [FlutterMethodChannel
    methodChannelWithName:@"flutter/live/methodChannel"
          binaryMessenger:[registrar messenger]];
    [registrar addMethodCallDelegate:self channel:methodChannel];
}
- (void)createEventChannel:(NSObject<FlutterPluginRegistrar>*)registrar {
    FlutterEventChannel *eventChannel = [FlutterEventChannel eventChannelWithName:@"flutter/live/eventChannel" binaryMessenger:[registrar messenger]];
    [eventChannel setStreamHandler:self];
}
- (void)createMessageChannel:(NSObject<FlutterPluginRegistrar>*)registrar {
    FlutterBasicMessageChannel *messageChannel = [FlutterBasicMessageChannel messageChannelWithName:@"flutter/live/messageChannel" binaryMessenger:[registrar messenger]];
    [messageChannel setMessageHandler:^(id  _Nullable message, FlutterReply  _Nonnull callback) {
        NSLog(@"MessageChannel 收到:%@",message);
//        NSString *method=message[@"method"];
//        if ([method isEqualToString:@"startLive"]) {
//            NSLog(@"Flutter MessageChannel 收到:startLive");
//        }
    }];
}
2、监听回调

1、MethodChannel

- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {

  if ([call.method isEqualToString:@"startLive"]) {
      NSLog(@"Flutter MethodChannel 收到:startLive");
  }
  else {
    result(FlutterMethodNotImplemented);
  }
}

2、EventChannel,通过绑定FlutterEventSink,让eventSink来发送消息

@property (nonatomic) FlutterEventSink eventSink;
- (FlutterError * _Nullable)onCancelWithArguments:(id _Nullable)arguments {
    _eventSink = nil;
    return nil;
}

- (FlutterError * _Nullable)onListenWithArguments:(id _Nullable)arguments eventSink:(nonnull FlutterEventSink)events {
    _eventSink = events;
    return nil;
}

3、BasicMessageChannel 创建的时候绑定

注意事项:

如果直接在Flutter项目中直接写plugin,每次运行都会更新GeneratedPluginRegistrant这个类,是按podfile的描述重新生成,所以不要在GeneratedPluginRegistrant里边写。

1、可以直接在AppDelegate里写

2、可以封装FlutterChannelPlugin工具类,在AppDelegate入口函数调用

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  
  [GeneratedPluginRegistrant registerWithRegistry:self];
  
  [FlutterChannelPlugin registerWithRegistrar:[self registrarForPlugin:@"FlutterChannelPlugin"]];
  
}
  • 2.1、FlutterChannelPlugin需遵循代理(FlutterPlugin,FlutterStreamHandler)

  • 2.2、FlutterChannelPlugin需实现FlutterPlugin代理的类方法,作为入口

+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
    FlutterChannelPlugin *plugin = [[FlutterChannelPlugin alloc] init];
    [plugin createMethodChannel:registrar];
    [plugin createEventChannel:registrar];
    [plugin createMessageChannel:registrar];
}

3、如果需要跳转原生页面则需拿到当前控制器
可通过下面方法实现

@property(strong, nonatomic) UIViewController *viewController;

+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
  FlutterMethodChannel* channel = [FlutterMethodChannel
      methodChannelWithName:@"flutter_rtmp_plugin"
            binaryMessenger:[registrar messenger]];

  UIViewController *viewController =
    [UIApplication sharedApplication].delegate.window.rootViewController;

  FlutterRtmpPlugin* instance = [[FlutterRtmpPlugin alloc] initWithViewController:viewController];
  [registrar addMethodCallDelegate:instance channel:channel];
}

- (instancetype)initWithViewController:(UIViewController *)viewController {
  self = [super init];
  if (self) {
    self.viewController = viewController;
  }
  return self;
}

- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
  if ([call.method isEqualToString:@"startLive"]) {
      NSDictionary * dict = call.arguments;
      NSLog(@"流地址是 %@",dict[@"url"]);

      LFViewController *liveVC = [[LFViewController alloc] init];
      liveVC.liveUrl = dict[@"url"];
      liveVC.modalPresentationStyle = UIModalPresentationFullScreen;
      [self.viewController presentViewController:liveVC animated:YES completion:nil];
  }
  else {
    result(FlutterMethodNotImplemented);
  }
}

Android端的书写

MethodChannel, 另外两种Channel参照iOS,两者类似

1、入口函数中创建MethodChannel

 public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
    final MethodChannel channel = new MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "flutterplugintemp");
    channel.setMethodCallHandler(this);
  }

2、遵循两个协议

implements FlutterPlugin, MethodCallHandler 

3、实现协议方法,在方法中写代码实现。

public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
    if(call.method.equals("startLive")){
      Intent intent = new Intent(context,LivingActivity.class);
      String url = call.argument("url");
      intent.putExtra("url",url);
      intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK );
      context.startActivity(intent);

    } else {
      result.notImplemented();
    }
注意事项

flutter 1.12版本之前的入口函数是

public static void registerWith(Registrar registrar) {

flutter 1.12版本以后是

public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {

若果写错会收不到Flutter的方法回调

2、若果要跳转原生页面则需要拿到app的当前context或activity
可通过这种写法获取

//
private Context context;

public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
    FlutterRtmpPlugin plugin = new FlutterRtmpPlugin();
    plugin.context = flutterPluginBinding.getApplicationContext();
    final MethodChannel channel = new MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "flutter_rtmp_plugin");
    channel.setMethodCallHandler(plugin);
  }
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
    if(call.method.equals("startLive")){
      Intent intent = new Intent(context,LivingActivity.class);
      String url = call.argument("url");
      intent.putExtra("url",url);
      intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK );
      context.startActivity(intent);

    } else {
      result.notImplemented();
    }
  }

总结:

以上是plugin的基本使用,要想应付各种复杂的场景还需多参考google官方插件源码,来汲取养分。
比如 camera

扫描二维码推送至手机访问。

版权声明:本文由西安泽虎代运营发布,如需转载请注明出处。

转载请注明出处https://www.0291.com.cn/post/56603.html

相关文章

西安企业做百度推广,一个月花三千和花三万到底差在哪?

4|最近跟几个西安的老板聊天,发现一个挺有意思的现象:同样做百度推广,有人一个月花三千块,询盘不断;有人一个月砸三万,水花都没见着。问他们区别在哪,大多数人说不清楚,只知道'钱花了,没效果'。 5| 6|百度推广这东西,说复杂也复杂,说简单也简单。核心就一件事:让你的潜在客户搜某个词的时候,你的信息...

我想当策划,大学应该选什么专业?

我想当策划,大学应该选什么专业?

学,广告,传播,公关,这些专业其实都可以。另外也可以学像汉语言文学,以及一些跟文学相关的一些专业,会对你找工作有帮助。但是,你想从事这个这份职业,除了专业的学习之外,更多的是,你要在上学的时候积极参与一些更营销策划相关的社会实践。比如说你可以做一些兼职,比如说帮别人去写稿,...

服装市场营销策略分析,“定位不慎满盘皆输”

服装市场营销策略分析,“定位不慎满盘皆输”

不同的区域需要不同的策略,而不同的营销策略需要不同的销售思路来配合。因此,在研究女装产品销售思路之前,最好先对于市场与营销策略做一次深入地了解。1.市场区域化(market segmentation):目标营销的第一步,是将整个市场拆分成若干个同性质的小市场。2.目标市场的...

晚间悦读丨你的思维方式,决定你的人生高度!

晚间悦读丨你的思维方式,决定你的人生高度!

越长大,越发现,能够决定你人生高度的,往往是你的认知层次。 你的认知在哪个层级,你的人生就处在什么状态。你认知的高度,决定了你人生的高度。 那如何才能升级方式、提升认知能力呢?可以从这三个方面做出改变。 NO. 1 改变态度 有人...

编写项目营销策划方案六大要点

编写项目营销策划方案六大要点

现在商业发展非常迅速,的需求非常的大,但是要做好营销策划是有一定难度的,我把自己做营销策划的一些体会在这里分享给朋友们。营销策划方案六大要点我们先说项目营销策划方案这个话题。大部分的营销策划人都是在企业里工作,大部分项目之初都是来源于一个想法,创始人、老板或者创始团队的一个...

【商场营销策划】如何进行商场营销策划?

【商场营销策划】如何进行商场营销策划?

商场是策划者们关注的永恒话题,那么究竟该如何作好商场营销策划呢?掌握以下这几点营销策略设计原则,至关重要!1.义利兼顾的原则。商场在获取利润的同时要充分考虑到消费者的合法利益和商场的长远利益。在作商场活动营销策略方案的时候应该将这一点作为首要的原则。对商场有利而对顾客不利的...

现在,非常期待与您的又一次邂逅

我们努力让每一部企业宣传片和抖音短视频成为商业大片