推广

Flutter Plugin 开发过程,详细记录

iseeyu2年前 (2024-02-22)推广114

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

相关文章

5个世界顶级思维,你能看懂几个?

文 | 洞见William 来源 | 洞见 人生,就是一场邂逅问题的修行。 不论是走荆棘的小路,还是宽阔的草原,问题就像脚下的路,一直走才会延伸。 而命运,就藏匿在我们思考问题的方式里。 老话说,只要思想不滑坡,办法总比困难多。 学历是铜牌,能力是银牌,是金牌...

分享软文广告为什么会吸引人。

分享软文广告为什么会吸引人。

身为90后,大概没人喜欢看电视广告,因为电视广告生硬、反复、枯燥,看到那些没有特色的广告,根本没有购物的欲望,恨不得给电视也冲个VIP,让其快进。那为什么同为广告,广告就很受90后喜欢呢? 那是因为软文广告,具备以下,打动人心的特质。其中最受女生喜欢的就是种草类软文广告,随意的一...

拼多多做流量有影响吗(拼多多刷流量有用吗)

拼多多做流量有影响吗(拼多多刷流量有用吗)

一般来说,影响拼多多店铺权重的因素有这些:销量、点击率、转化率、动销率同店铺DSR评分。而在拼多多做流量的话,其实和这五个因素优势有一定的相关性的,所以说,拼多多做流量对权重是有一定的影响的。合理对拼多多店铺进行做流量的话,对店铺的权重是有益无害的。...

淘宝客服营销技巧有哪些(做淘宝客服的技巧)

淘宝客服营销技巧有哪些(做淘宝客服的技巧)

许多准顾客即使有意购买,也不喜欢迅速签下订单,他总要东挑西拣,在产品颜色、规格、式样、交货日期上不停地打转。...

运营人必备7种推广技能!你知道吗?

运营人必备7种推广技能!你知道吗?

01 推广技能 对于运营人员来说,不论你是做用户运营还是社区运营都会向用户或其他人进行推广,当你在进行活动的时候你需要联系渠道或产品内部来推广产品,因此推广技能做为运营技能的重要技能自然是有它重要的地方。 02 推广技能有哪些 推广是指将自己的产...

教你如何设计网站能提高用户搜索流程体验。

教你如何设计网站能提高用户搜索流程体验。

搜索功能在大多数网站都成了一个不可或缺的功能,除非网站极其扁平、信息极少,否则都需要配备搜索功能。在信息轰炸的互联网,用户都是带着目的去搜索。初的搜索框只是一个普通的UI控件,但随着用户使用频率上升,以及对用户体验越来越重视,站长们更加重视搜索框的设计。怎么建立网站搜索框,是能满足用户整个搜索的需...

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

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