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:[email protected]
/// @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对话 该死的空格 点此快速加群

相关推荐
阅文作家助手开发团队_山神17 小时前
第四章(下) Delta 到 HTML 转换:块级与行内样式渲染深度解析
flutter
MaoJiu17 小时前
Flutter造轮子系列:flutter_permission_kit
flutter·swiftui
阅文作家助手开发团队_山神21 小时前
第四章(下):Delta 到 HTML 转换的核心方法解析
flutter
xiaoyan20151 天前
flutter3.32+deepseek+dio+markdown搭建windows版流式输出AI模板
flutter·openai·deepseek
阅文作家助手开发团队_山神1 天前
第四章(上):HTML 到 Delta 转换的核心方法解析
flutter
stringwu1 天前
Flutter高效开发利器:Riverpod框架简介及实践指南
flutter
耳東陈1 天前
Flutter开箱即用一站式解决方案2.0-全局无需Context的Toast
flutter
阅文作家助手开发团队_山神2 天前
第三章: Flutter-quill 数据格式Delta
flutter
阅文作家助手开发团队_山神2 天前
第二章:Document 模块与 DOM 树详解
flutter
程序员老刘2 天前
20%的选择决定80%的成败
flutter·架构·客户端