PowerShell案例:修改AndroidManifest.xml解决flutter插件example代码编译失败的问题

本文讲述了在编写Flutter工程模板脚本时遇到的batch脚本处理XML文件问题,以及如何转向使用PowerShell解决。通过示例展示了如何使用PowerShell修改AndroidManifest.xml文件,包括添加命名空间、修改应用属性等,解决了与引入库的冲突。最终提供了具体的PowerShell脚本实现,演示了利用setAttribute的重载方法保留命名空间。

学习powershell的初衷是因为在编写flutter工程模版脚本的过程中遇到一个极不起眼却很棘手的问题:batch脚本无法满足复杂的xml文件修改需求。这是由于xml文件中大量存在<>,这与batch的重定向符是相同的,导致在echo每行xml内容时出现各种莫名其妙的问题。第一时间想到的是flutter SDK是如何处理AndroidManifest.xml的呢?遂开始翻阅flutter SDK中的bat文件(在FLUTTER_HOME的bin文件夹下),发现SDK中涉及到复杂的操作都交给了powershell,于是整理powershell的基本语法有了PowerShell脚本:快速入门一文。言归正传,来看看如何使用powershell实现xml文件的修改。

需求

我们来看看flutter在生成插件工程时example默认生成的清单文件:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.flutter_example">
    <application
        android:name="io.flutter.app.FlutterApplication"
        android:label="flutter_example"
        android:icon="@mipmap/ic_launcher">
		
		<!-- 无关部分省略. -->
    </application>
</manifest>

根据编译失败的提示信息,主要是application的name、label属性与引入的安卓基础库冲突导致,解决办法很简单,修改成如下的样子:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
	xmlns:tools="http://schemas.android.com/tools"
    package="com.example.flutter_example">
    <application
    	tools:replace="android:label,name"
    	android:usesCleartextTraffic="true"
        android:name="io.flutter.app.FlutterApplication"
        android:label="flutter_example"
        android:icon="@mipmap/ic_launcher">
		
		<!-- 无关部分省略. -->
    </application>
</manifest>

主要有3处修改:

  1. manifest 增加了xmlns:tools=“http://schemas.android.com/tools”
  2. application增加了tools:replace=“android:label,name”
  3. application增加了android:usesCleartextTraffic=“true”

思路自然是为doc的manifest 和application新增对应的属性即可,具体操作可以参照PowerShell脚本:快速入门中xml章节。
然而有个问题,用setAttribute(string name, string value)方法设置application属性时,调用:$application.setAttribute('tools:replace', 'android:label,name'),实际生成的却是:replace="android:label,name"命名空间没了!!!

解决思路:查看node和attribute的数据类型以及相应的类方法,看看是否有重载方法可以满足需求。分别对node和attribute对象执行get-member查看所有类方法:$var | get-memer,然后根据方法名进行测试,最终找到node具有setAttribute方法的重载setAttribute(string name, string nsUri, string value)可以解决命名空间丢失的问题,最终的解决方案如下:

实现

param([string]$examplePath=$(throw "Where is example code path?"))
# 找到要修改清单文件的绝对路径
$srcPath=$examplePath+"\android\app\src\main\AndroidManifest.xml"
# 创建doc对象
[XML]$manifest = gc $srcPath
$rootNode=$manifest.selectNodes('/manifest[1]')
$toolsUri="http://schemas.android.com/tools"
$androidUri="http://schemas.android.com/apk/res/android"
# 修改manifest节点属性
$rootNode.setAttribute("xmlns:tools","http://schemas.android.com/tools")
$app=$manifest.selectNodes('/manifest/application[1]')
# 修改application节点属性
$app.setAttribute('replace',$toolsUri,'android:label,name') | Out-Null
$app.setAttribute('usesCleartextTraffic',$androidUri,'true') | Out-Null
# 将doc修改保存到源文件
$manifest.Save($srcPath) | Out-Null
### 解决 AndroidManifest.xml 文件无法删除的问题 当遇到无法删除 `AndroidManifest.xml` 文件的情况时,通常是因为文件被占用或权限不足。以下是几种可能的原因及解决方案: #### 1. 文件被占用 如果文件正在被其他进程使用,则无法删除此文件。可以通过关闭所有与项目相关的应用程序和服务来释放文件。 - **Windows**: 使用任务管理器结束相关进程。 - **Linux/macOS**: 使用命令行工具如 `lsof` 查找并终止占用文件的进程[^1]。 ```bash # Linux/macOS 下查找占用文件的进程 lsof | grep AndroidManifest.xml kill -9 PID # 替换PID为实际进程ID ``` #### 2. 权限问题 有时即使没有程序占用文件,也可能由于权限不够而无法删除。此时需要获取管理员权限再尝试删除操作。 - **Windows**: 右键点击资源管理器中的文件夹选项卡上的“在此处打开 PowerShell 窗口”,输入以下命令: ```powershell Takeown /F .\path\to\file\AndroidManifest.xml /A icacls .\path\to\file\AndroidManifest.xml /grant administrators:F del .\path\to\file\AndroidManifest.xml ``` - **Linux/macOS**: 使用 sudo 提升权限后执行 rm 命令 ```bash sudo rm ./path/to/file/AndroidManifest.xml ``` #### 3. 版本控制系统锁定 如果是通过 Git 或 SVN 进行版本控制的工作目录下遇到了此类情况,可能是 VCS 锁定了这些文件。建议先清理工作区后再重试删除动作。 对于 git 用户来说,可以运行如下指令清除索引缓存: ```bash git reset HEAD . rm -rf .git/index.lock ``` 之后再次尝试删除目标文件即可[^2].
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值