Flutter-->Namespace not specified.

更新Android gradle 7.5.0之后, 运行项目会出现Namespace not specified.问题, 这里出一个我的解决方案.

由于很多库都不可能及时更新适配gradle 7.5.0, 所以可以等pub get将子库拉取到本地之后, 在本地手动添加namespace属性,即可解决本文问题.

作为程序猿,那肯定不可能手动修改, 这种体力活是干不会的.

祭出本文干货dart脚本:

dart 复制代码
import 'dart:convert';
import 'dart:io';

import 'package:yaml/yaml.dart';

///
/// Email:angcyo@126.com
/// @author angcyo
/// @date 2024/10/08
///
/// 更新Gradle到7.5.0之后, 需要指定namespace属性, 不指定会报错.
/// ```
/// Namespace not specified.
/// ```
///
/// ```
/// android {
///     if (project.android.hasProperty("namespace")) {
///         namespace 'com.angcyo.xxx'
///     }
/// }
/// ```
///
/// 此脚本用于在`build.gradle`文件的`android{ ... }`中加入`namespace`属性.
///
void main() async {
  final currentPath = Directory.current.path;
  print('脚本工作路径->$currentPath');

  //读取yaml配置信息
  final localYamlFile = File("$currentPath/script.local.yaml");
  final yamlFile = File("$currentPath/script.yaml");
  final localYaml = loadYaml(
      localYamlFile.existsSync() ? localYamlFile.readAsStringSync() : "");
  final yaml = loadYaml(yamlFile.readAsStringSync());

  //---

  // 需要修改库的名字集合, 不指定全部
  // [YamlList]
  final names =
      yaml["androidCompileSdkNames"] ?? localYaml["androidCompileSdkNames"];

  //获取所有依赖的子库
  final dependenciesFile = File("$currentPath/.flutter-plugins-dependencies");
  final androidDependencies =
      jsonDecode(dependenciesFile.readAsStringSync())?["plugins"]?["android"];
  if (androidDependencies is List) {
    //{
    //    "name": "device_info_plus",
    //    "path": "/Users/angcyo/.pub-cache/hosted/pub.dev/device_info_plus-10.1.1/",
    //    "native_build": true,
    //    "dependencies": []
    // },
    int index = 0;
    for (final dependency in androidDependencies) {
      final name = dependency["name"];
      final path = dependency["path"];
      if (path != null) {
        if (names == null || names.contains(name)) {
          final namespace = getPackageFromAndroidManifest(path);
          if (namespace != null) {
            colorLog(
                "正在添加[${index + 1}/${androidDependencies.length}]->$path -> namespace:$namespace");
            appendNamespace(path, namespace);
          } else {
            colorLog("未找到[package]信息, 请检查[${getAndroidManifestPath(path)}]文件.");
          }
        }
      }
      index++;
    }
  } else {
    colorLog("未找到子模块的依赖信息, 请检查[${dependenciesFile.path}]文件.");
  }
}

/// 核心修改方法
/// 添加flutter子库android工程中`build.gradle`文件加入`namespace`
/// [flutterPath] flutter工程子库根路径
void appendNamespace(String flutterPath, String namespace) {
  final androidPath = "$flutterPath/android";
  final androidPathFile = File("$androidPath/build.gradle");
  if (androidPathFile.existsSync()) {
    final androidPathFileContent = androidPathFile.readAsStringSync();
    if (!androidPathFileContent.contains("namespace")) {
      //修改 android {
      final newContent = androidPathFileContent
          .replaceAllMapped(RegExp(r"android *{ *"), (match) {
        return 'android { \n    if (project.android.hasProperty("namespace")) namespace "$namespace" //by angcyo ${DateTime.now()}\n';
      });
      //写入文件
      androidPathFile.writeAsStringSync(newContent);
      colorLog("修改成功->$androidPathFile", 250);
    } else {
      colorLog("跳过已存在[namespace]信息 -> ${androidPathFile.path}");
    }
  }
}

/// 获取AndroidManifest.xml文件路径
String getAndroidManifestPath(String flutterPath) {
  return "$flutterPath/android/src/main/AndroidManifest.xml";
}

/// 从`AndroidManifest.xml`文件中获取`package`
String? getPackageFromAndroidManifest(String flutterPath) {
  final androidManifestFile = File(getAndroidManifestPath(flutterPath));
  if (androidManifestFile.existsSync()) {
    final content = androidManifestFile.readAsStringSync();
    final package = RegExp(r'package=\"(.*?)\"').firstMatch(content)?.group(1);
    return package;
  }
  return null;
}

void colorLog(dynamic msg, [int col = 93]) {
  print('\x1B[38;5;${col}m$msg');
}

Flutter工程的任意位置, 新建一个dart文件, 粘贴上述代码, 使用dart运行main方法即可.


群内有各(pian)种(ni)各(jin)样(qun)的大佬,等你来撩.

联系作者

点此QQ对话 该死的空格 点此快速加群

相关推荐
江上清风山间明月1 天前
Flutter开发的应用页面非常多时如何高效管理路由
android·flutter·路由·页面管理·routes·ongenerateroute
Zsnoin能2 天前
flutter国际化、主题配置、视频播放器UI、扫码功能、水波纹问题
flutter
早起的年轻人2 天前
Flutter CupertinoNavigationBar iOS 风格导航栏的组件
flutter·ios
HappyAcmen2 天前
关于Flutter前端面试题及其答案解析
前端·flutter
coooliang2 天前
Flutter 中的单例模式
javascript·flutter·单例模式
coooliang2 天前
Flutter项目中设置安卓启动页
android·flutter
JIngles1232 天前
flutter将utf-8编码的字节序列转换为中英文字符串
java·javascript·flutter
B.-2 天前
在 Flutter 中实现文件读写
开发语言·学习·flutter·android studio·xcode
freflying11193 天前
使用jenkins构建Android+Flutter项目依赖自动升级带来兼容性问题及Jenkins构建速度慢问题解决
android·flutter·jenkins
机器瓦力3 天前
Flutter应用开发:对象存储管理图片
flutter