Flutter多渠道打包的解决方案(walle)

我们的应用集成了TalkingData这个第三方工具来统计日活、事件等,需要在应用启动时初始化SDK,这个时候需要传入当前渠道,以便数据的统计。 由于最开始是用脚本一个个打包,一直想解决打包过慢的问题,但是网上大多教程是基于命令行参数或flavor,实质上并没有根本解决打包效率的问题。直到发现了文章的主角 walle。

背景

  1. 我们的应用集成了TalkingData这个第三方工具来统计日活、事件等,需要在应用启动时初始化SDK,这个时候需要传入当前渠道,以便数据的统计。

  2. 由于最开始是用脚本一个个打包,一直想解决打包过慢的问题,但是网上大多教程是基于命令行参数或flavor,实质上并没有根本解决打包效率的问题。直到发现了文章的主角 walle

应用解决方案

walle

walle是美团开源的一个打包插件,这里就不做介绍了,传送门

flutter插件

由于源码Android端的,就想着写一个Flutter插件吧。代码也很简单,已经上传到pub仓库。使用步骤可以参考 Github | Pub仓库

插件源码

  1. 在 android/build.gradle 文件中添加依赖

buildscript {
    repositories {
        // 不加这个找不到walle依赖
        maven {
            url 'https://maven.aliyun.com/repository/jcenter'        }
        maven {
            url 'https://maven.aliyun.com/repository/google'        }
        google()
        mavenCentral()
    }}rootProject.allprojects {
    repositories {
        // 同上
        maven {
            url 'https://maven.aliyun.com/repository/jcenter'        }
        maven {
            url 'https://maven.aliyun.com/repository/google'        }
        google()
        mavenCentral()
    }}// ...// 末尾添加dependencies {
    implementation 'com.meituan.android.walle:library:1.1.7'}
  1. Android端注册文件(android/src/main/java/net/niuxiaoer/package_by_walle/PackageByWallePlugin.java)

import com.meituan.android.walle.WalleChannelReader;/** PackageByWallePlugin */public class PackageByWallePlugin implements FlutterPlugin, MethodCallHandler {
  /// The MethodChannel that will the communication between Flutter and native Android
  ///
  /// This local reference serves to register the plugin with the Flutter Engine and unregister it
  /// when the Flutter Engine is detached from the Activity
  private MethodChannel channel;
  private Context applicationContext;

  @Override
  public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
    this.applicationContext = flutterPluginBinding.getApplicationContext();
    channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "package_by_walle");
    channel.setMethodCallHandler(this);
  }

  @Override
  public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
    if (call.method.equals("getPackingChannel")) {
      try {
        // 这里调用walle的方法
        String channel = WalleChannelReader.getChannel(this.applicationContext);
        result.success(channel);
      } catch(Exception e) {
        result.success("unknown");
      }
    }  else if (call.method.equals("getPackingInfo")) {
      ChannelInfo channelInfo = WalleChannelReader.getChannelInfo(this.applicationContext);
      if (channelInfo != null) {
        Map<String, String> extraInfo = channelInfo.getExtraInfo();
        result.success(extraInfo);
      } else {
        result.success(null);
      }
    } else {
      result.notImplemented();
    }
  }

  @Override
  public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
    channel.setMethodCallHandler(null);
  }}
  1. iOS端注册文件(ios/Classes/PackageByWallePlugin.m)

@implementation PackageByWallePlugin+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
  FlutterMethodChannel* channel = [FlutterMethodChannel
      methodChannelWithName:@"package_by_walle"
            binaryMessenger:[registrar messenger]];
  PackageByWallePlugin* instance = [[PackageByWallePlugin alloc] init];
  [registrar addMethodCallDelegate:instance channel:channel];}- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
  if ([@"getPackingChannel" isEqualToString:call.method]) {
    result(@"AppStore");
  } else {
    result(FlutterMethodNotImplemented);
  }}@end
  1. dart文件(lib/package_by_walle.dart)

class PackageByWalle {
  static const MethodChannel _channel = MethodChannel('package_by_walle');

  static Future<String?> get getPackingChannel async {
    final String? version = await _channel.invokeMethod('getPackingChannel');
    return version;
  }

  static Future<Map<dynamic, dynamic>?> get getPackingInfo async {
    if (Platform.isAndroid) {
      final Map<dynamic, dynamic>? info = await _channel.invokeMethod('getPackingInfo');
      return info;
    } else {
      return null;
    }
  }}

插件使用

参考example

以往的解决方案

编写NodeJS脚本,通过修改配置文件一个一个渠道进行打包

提升

使用脚本的方式打一个渠道包需要3-4分钟,总共就需要等待半个多小时。现在一共只需要三分钟左右,节省了大量的时间,真香~

来源: 互联网
本文观点不代表码客-全球程序员交流社区立场,不承担法律责任,文章及观点也不构成任何投资意见。

赞 ()

相关推荐

  • 置顶 开发项目接单群,免费入群了

    无论你是Android、ios、java、php,或者你是产品经理、老板,都可以免费入群接单或者发布项目,全程不收取任何费用。

    2025年02月21日 15点27分
  • 鸿蒙Next-AttributeModifier结合@Styles和@Extend深度解析使用

    声明式语法引入了@Styles和@Extend两个装饰器,可以解决复用相同自定义样式的问题,但是存在以下受限场景:

    2025年03月03日 15点40分
  • ConstraintLayout之layout_constraintDimensionRatio属性详解

    layout_constraintDimensionRatio 是 ConstraintLayout 提供的一个强大功能,它可以让 View 按照固定的宽高比例自适应尺寸。使用这个属性,可以在 ConstraintLayout 中根据已知的宽度或高度,自动计算另一个维度,确保 View 保持特定的宽高比。

    2025年03月03日 15点39分
  • Android事件分发时,你浓眉大眼的onTouch()竟然没有执行?

    在开发需求时,有这么一个场景:Activity中有一个ViewGroup作为Parent,ViewGroup里面又有一个Webview作为Child。当一进入页面时,系统输入法自动弹起,而在点击Parent区域时,需要收起系统输入法。背景介绍完毕,当时的第一想法就是通过Parent设置setOnTouchListener,然后在onTouch()回调中来实现:

    2025年03月02日 15点10分
  • Android SDK封装与发布实战指南

    Android SDK封装与发布实战指南

    2025年03月02日 15点05分
  • 鸿蒙Next开发-添加水印以及点击穿透设置

    在鸿蒙Next中,为App全局添加水印可以通过以下方式实现,其中通过窗口添加水印是一种常见且高效的方式。以下是具体方案和实现细节:

    2025年02月26日 23点15分
  • 鸿蒙Next开发-普通函数和箭头函数 this指向的区别以及对UI刷新的影响

    鸿蒙Next开发-普通函数和箭头函数 this指向的区别以及对UI刷新的影响

    2025年02月26日 23点14分
  • 深入探索ArkUI @Builder与@BuilderParam的进阶应用

    在ArkUI的组件化开发体系中,@Builder和@BuilderParam这对装饰器组合扮演着UI模块化的重要角色。二者的差异与配合体现了声明式UI的核心思想:

    2025年02月26日 23点12分
  • Deepseek推荐:Android 开发者需要掌握的系统知识大纲

    一、操作系统基础1. Linux 内核机制内容介绍 Android 基于 Linux 内核,核心机制包括进程管理、内存管理、文件系统、Binder 驱动等。

    2025年02月26日 23点09分
  • Android App 厂商角标适配

    本篇介绍一下笔者在维护IM应用时,设置App角标的相关经验。同时这里设置角标都是基于系统厂商的Launcher,没有适配三方的Launcher应用,因为我们统计下来发现近些年使用三方Launcher应用比较少了,大部分用户还是以系统Launcher为主。所在在我们的项目中,主要是适配各个厂商。

    2025年02月26日 23点07分
  • 鸿蒙Next-方法装饰器以及防抖方法注解实现

    以下是关于 鸿蒙Next(HarmonyOS NEXT)中 MethodDecorator 的详细介绍及使用指南,结合了多个技术来源的实践总结:

    2025年02月26日 22点58分
  • DevEco Studio常用快捷键以及如何跟AndroidStudio的保持同步

    DevEco Studio是华为推出的用于开发HarmonyOS应用的集成开发环境,它提供了丰富的快捷键以提高开发效率,以下为你详细介绍不同操作场景下的常用快捷键:

    2025年02月26日 22点56分
  • Android | 利用ItemDecoration绘制RecyclerView分割线

    RecyclerView.ItemDecoration 是 Android 提供的一种扩展机制,用于为 RecyclerView 的每个子项(Item)添加装饰(Decoration)。它通常用于绘制分割线、边距、背景等,目的是增强 RecyclerView 的显示效果。

    2025年02月26日 22点52分
  • Android 布局优化:利用 ViewStub 和 Merge 提升性能

    提升界面渲染性能是一个至关重要的任务,尤其是在应用启动时,渲染界面需要快速且流畅。为了优化 UI 渲染速度,Android 提供了许多工具,其中 ViewStub 和 Merge 标签是非常有效的布局优化手段。通过合理使用这两者,可以延迟加载不必要的视图、减少布局的嵌套层级,从而加速应用的启动和运行。

    2025年02月26日 22点47分
  • 玩转 ImageView.ScaleType:图片的缩放与裁剪技巧

    ImageView 是最常用的控件之一,它用于展示各种类型的图片。为了能够根据需求调整图片的显示效果,Android 提供了 ImageView.ScaleType 枚举,它可以灵活地控制图片如何适应 ImageView 的尺寸。本文将探讨 ImageView.ScaleType 的不同选项、使用场景及其实现技巧。

    2025年02月26日 22点45分
  • Android加快你的编译速度

    工欲善其事,必先利其器。如果每次运行项目都要花费5-10分钟,那人的心态都要崩了。

    2025年02月25日 15点40分

发表回复

评论列表

点击查看更多

    联系我们

    在线咨询: QQ交谈

    微信:dxmcpjl

    邮件:1529097251#qq.com

    工作时间:周一至周五,9:30-18:30,节假日休息

    微信