为什么使用多渠道打包
统计与分析 | 应用打包成不同的版本,投放到不同的市场或平台。统计应用在各个市场的用户下载量、新增用户量等数据,有助于分析应用在不同市场的表现和用户喜好。 |
推广与营销 | 针对不同的市场或用户群体进行定制化的推广和营销活动 |
风险管理 | 需要切换API环境或进行其他配置更改。多渠道打包可以帮助开发者更好地管理不同版本和配置,降低这种风险。 |
提高效率 | 多渠道打包方案可以实现快速打包,例如使用gradle变量动态替换或第三方公司的批量打包方案,可以大大提高打包效率,节省开发者的时间。 |
动态渠道名称变量
xml
<!--value的值填写渠道名称,例如yingyongbao。这里设置动态渠道名称变量-->
<meta-data android:value="xiaomi" android:name="UMENG_CHANNEL"/>
<!--<meta-data android:value="${UMENG_CHANNEL_VALUE}" android:name="UMENG_CHANNEL"/>-->
productFlavors 配置渠道
ini
/*配置渠道*/
productFlavors {
yingyongbao {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "yingyongbao"]
}
oppo {
manifestPlaceholders = [UMENG_CHANNEL_VALUE: "oppo"]
}
}
flavorDimensions配置
如果不配置执行多渠道打包命令时会有如下异常:
*
A problem occurred evaluating root project 'android'.
> A problem occurred configuring project ':app'.
> com.android.builder.errors.EvalIssueException: All flavors must now belong to a named flavor dimension. Learn more at https://d.android.com/r/tools/flavorDimensions-missing-error-message.html
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
* Get more help at https://help.gradle.org
读取清单文件下的渠道名称
kotlin
class MainActivity: FlutterActivity() {
private val CHANNEL = "channel.flutter.dev"
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
.setMethodCallHandler { call: MethodCall, result: MethodChannel.Result ->
//与Flutter Client invokeMethod调用字符串标识符匹配
if (call.method == "channelMetaValue") {
val channelValue: String = channelMetaValue()
//initBlueTooth为后面安卓端需要调取的方法
result.success(channelValue)
} else {
result.notImplemented()
}
}
}
private fun channelMetaValue(): String {
val pm: PackageManager = packageManager
var channel: String = "";
try {
val info: ApplicationInfo = pm.getApplicationInfo(getPackageName(),
PackageManager.GET_META_DATA)
channel = info.metaData.getString("UMENG_CHANNEL").toString()
} catch (e: PackageManager.NameNotFoundException) {
e.printStackTrace()
}
return channel;
}
}
Flutter工程获取渠道名称
less
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late var channel = _channelValue();
String _channelValue() {
return '${'这里显示渠道名称'}\n';
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
channel,
style: Theme.of(context).textTheme.headlineMedium,
),
GestureDetector(
onTap: () async {
channel = await channelName();
setState(() {});
},
child: const Text(
'\n获取渠道名称\n',
),
)
],
),
),
);
}
///app当前市场
///android 例如:小米、华为、opppo
///ios - AppStore
Future<String> channelName() async {
String channel = '';
if (Platform.isAndroid) {
const platform = MethodChannel('channel.flutter.dev');
channel = await platform.invokeMethod('channelMetaValue');
} else if (Platform.isIOS) {
channel = 'ios';
}
return channel;
}
}
执行命令进行多渠道打包
多渠道打包案例
切换到分支flutter_multi_channel