背景
我们的应用集成了
TalkingData
这个第三方工具来统计日活、事件等,需要在应用启动时初始化SDK,这个时候需要传入当前渠道,以便数据的统计。由于最开始是用脚本一个个打包,一直想解决打包过慢的问题,但是网上大多教程是基于命令行参数或
flavor
,实质上并没有根本解决打包效率的问题。直到发现了文章的主角walle
。
应用解决方案
walle
walle
是美团开源的一个打包插件,这里就不做介绍了,传送门。
flutter插件
由于源码Android
端的,就想着写一个Flutter
插件吧。代码也很简单,已经上传到pub
仓库。使用步骤可以参考 Github | Pub仓库。
插件源码
- 在 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'
}
- 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);
}
}
- 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
- 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分钟,总共就需要等待半个多小时。现在一共只需要三分钟左右,节省了大量的时间,真香~
本文已同步到个人博客