-
我们的应用集成了
TalkingData
这个第三方工具来统计日活、事件等,需要在应用启动时初始化SDK,这个时候需要传入当前渠道,以便数据的统计。
-
由于最开始是用脚本一个个打包,一直想解决打包过慢的问题,但是网上大多教程是基于命令行参数或
flavor
,实质上并没有根本解决打包效率的问题。直到发现了文章的主角
walle
。
walle
是美团开源的一个打包插件,这里就不做介绍了,
传送门
。
由于源码是
Android
端的,就想着写一个
Flutter
插件吧。代码也很简单,已经上传到
pub
仓库。使用步骤可以参考
Github
|
Pub仓库
。
经过线上测试,存在部分机型获取不到渠道的情况,请慎重使用
参考
example
-
在 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;
public class PackageByWallePlugin implements FlutterPlugin, MethodCallHandler {
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 {
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);
- 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;
使用脚本的方式打一个渠道包需要3-4分钟,总共就需要等待半个多小时。现在一共只需要三分钟左右,效率方面提升很大。
本文已同步到个人博客
背景我们的应用集成了TalkingData这个第三方工具来统计日活、事件等,需要在应用启动时初始化SDK,这个时候需要传入当前渠道,以便数据的统计。由于最开始是用脚本一个个打包,一直想解决打包过慢的问题,但是网上大多教程是基于命令行参数或flavor,实质上并没有根本解决打包效率的问题。直到发现了文章的主角 walle。应用解决方案wallewalle是美团开源的一个打包插件,这里就不做介绍了,传送门。flutter插件由于源码Android端的,就想着写一个Flutter插件吧。
首先在lib建立多个main.dart,比如main_local.dart表示本地开发运行时执行的入口文件,main_develop.dart和main.dart分别表示开发环境和生产环境:
├── api/
├── main.dart
├── main_develop.dart
├── models/
├── pages/
├── utils/
└── widgets/
这样如果...
2019-06-19
公司已经开始在项目中使用
Flutter进行跨平台开发了,并且已经在其中一款应用上线了,过程并没有多曲折,按照官网教程一步步进行,继承、
打包、测试、发版。
最近另外一个项目有新的需求,也开始使用
Flutter,在集成
打包的时候出现了问题:
A/
flutter: [FATAL:
flutter/shell/common/shell.cc(218)] Check failed: vm. Must be able to initialize the VM.
收集到的错误日志如下:
1.配置--dart-define,如下:
--dart-define=APP_CHANNEL=www.baidu.com --dart-define=OTHER_VAR=这是测试环境
Flutter多渠道调试设置 (安卓篇,Android Studio)
在build.gradle中定义不同的风味(flavor),一套代码可在同一个设备上同时安装名称、图标、applicationId不同的两个应用
android {
flavorDimensions "app"
productFlavors {
// 生产环境
flavoronline {
dimension
类似于Android第三方库引入是在gradle文件中,Flutter相要引入第三方包也要对应配置文件pubspec.yaml。
yaml全称是 :Yet Another Markup Language ,任是一种标记语言。
这里我是采用了官方的例子来展示如何引入第三方包:https://flutterchina.club/get-started/codelab/
我们直接看pubspec.yaml 这个文件
name: startup_namer
description: A new Flutt
Flutter支持在不同的渠道上进行打包,可以根据不同的渠道配置不同的应用包。下面是实现Flutter多渠道打包的步骤:
1. 在Flutter项目根目录下的`android/app`目录下创建一个名为`channel`的文件夹,用于存放不同渠道的配置文件。
2. 在`channel`文件夹下创建不同渠道的配置文件,例如`channel/dev.properties`、`channel/prod.properties`等。配置文件的内容可以包括应用包名、应用名称、应用图标、应用版本号等信息。例如:
# dev.properties
# 应用包名
package_name=com.example.dev
# 应用名称
app_name=dev_app
# 应用图标
app_icon=dev_icon
# 应用版本号
app_version=1.0.0
3. 在`android/app/build.gradle`文件中添加如下配置:
android {
// ...
defaultConfig {
// ...
//应用包名
applicationId "com.example.app"
//应用名称
manifestPlaceholders = [
appName: "My App"
//应用版本号
versionCode 1
versionName "1.0.0"
// ...
// ...
buildTypes {
release {
// ...
//在release模式下,根据不同渠道打包
applicationVariants.all { variant ->
variant.outputs.all {
def outputFile = outputFileName
if (outputFile.endsWith('.apk') || outputFile.endsWith('.aab')) {
def fileName = outputFile.replace(".${outputFile.split("\\.").last()}", "")
def channelPropertiesFile = file("channel/${variant.flavorName}.properties")
if (channelPropertiesFile.exists()) {
def channelProperties = new Properties()
channelProperties.load(new FileInputStream(channelPropertiesFile))
outputFileName = "${fileName}_${channelProperties.getProperty("app_version")}_${channelProperties.getProperty("app_name")}.apk"
output.outputFileName = outputFileName
manifestPlaceholders = [
appName: channelProperties.getProperty("app_name"),
appIcon: channelProperties.getProperty("app_icon")
4. 在Flutter项目根目录下运行以下命令,生成不同渠道的应用包:
flutter build apk --flavor dev
flutter build apk --flavor prod
其中,`--flavor`参数指定了打包时所使用的渠道配置文件。
5. 打包完成后,在`build\app\outputs\flutter-apk`目录下可以看到生成的不同渠道的应用包。
注意事项:
- 渠道名称需要与`buildTypes`中的名称一致。
- 配置文件中的属性名需要与`build.gradle`文件中指定的属性名一致。
- 打包时需要分别运行不同渠道的打包命令。