英文:
Use gradle task change activity attribute in AndroidManifest.xml
问题
我想在我的清单文件中为所有活动设置一个属性(android:configChanges="screenSize|smallestScreenSize|screenLayout"),并且我尝试的方式如下:
我已经在我的应用程序模块的build.gradle文件中添加了一些代码片段:
android.applicationVariants.all { variant ->
print("check variant:${variant.getClass()}\n")
variant.outputs.each { output ->
print("check output all task:${output.getName()}\n")
def processorTask = output.processManifestProvider.getOrNull()
print("check processorTask:${processorTask.getName()}\n")
// ProcessApplicationManifest
// https://android.googlesource.com/platform/tools/base/+/studio-master-dev/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/ProcessApplicationManifest.java
processorTask.doLast { task ->
def directory = task.getBundleManifestOutputDirectory()
def srcManifestFile = "$directory${File.separator}AndroidManifest.xml"
print("check manifest file:$srcManifestFile\n")
def manifestContent = new File(srcManifestFile).getText()
def xml = new XmlParser(false, false).parseText(manifestContent)
print("check manifest application:${xml.application.size()}")
xml.application[0].activity.forEach{
it.attributes().put('android:configChanges', 'screenSize|smallestScreenSize|screenLayout')
}
def serializeContent = groovy.xml.XmlUtil.serialize(xml)
def targetFile = new File(srcManifestFile)
targetFile.write(serializeContent)
}
}
}
执行命令gradlew assembleDebug
后,它会生成一个文件和一个apk文件。文件内容如下所示:
图片内容是我需要的,但生成的apk文件内容如下所示:
它丢失了在gradle任务中添加的属性。我想知道如何使它工作,请帮忙。
我的环境
-
操作系统:Windows 10 64位
-
Android Studio版本:3.5.2
-
com.android.tools.build:gradle:3.5.2
英文:
I want to set an attribue(android:configChanges="screenSize|smallestScreenSize|screenLayout") for all activities in my manifest file with gradle file,and what I'm trying like follow:
I had add some code snippet in my app module's build.gradle file :
android.applicationVariants.all { variant ->
print("check variant:${variant.getClass()}\n")
variant.outputs.each { output ->
print("check output all task:${output.getName()}\n")
def processorTask = output.processManifestProvider.getOrNull()
print("check processorTask:${processorTask.getName()}\n")
//ProcessApplicationManifest
//https://android.googlesource.com/platform/tools/base/+/studio-master-dev/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/ProcessApplicationManifest.java
processorTask.doLast {task ->
def directory = task.getBundleManifestOutputDirectory()
def srcManifestFile = "$directory${File.separator}AndroidManifest.xml"
print("check manifest file:$srcManifestFile\n")
def manifestContent = new File(srcManifestFile).getText()
def xml = new XmlParser(false, false).parseText(manifestContent)
print("check manifest application:${xml.application.size()}")
xml.application[0].activity.forEach{
it.attributes().put('android:configChanges', 'screenSize|smallestScreenSize|screenLayout')
}
def serializeContent = groovy.xml.XmlUtil.serialize(xml)
def targetFile = new File(srcManifestFile)
targetFile.write(serializeContent)
}
}
}
After execute command gradlew assembleDebug
it generates a file and an apk.File content like this picture
The picture's content is what I'm need,but the generated apk file's content is this:
It lose attributes which added in gradle task.I want to know how to make it works,please help.
My environment
- OS:Windows 10 64 bit
- Android Studio Version: 3.5.2
- com.android.tools.build:gradle:3.5.2
答案1
得分: 1
以下是已翻译的代码部分:
project.afterEvaluate {
def variants = null
try {
variants = android.applicationVariants
} catch (Throwable t) {
try {
variants = libraryVariants
} catch (Throwable tt) {}
}
if (variants != null) {
variants.all { variant ->
variant.outputs.each { output ->
def task = output.processManifestProvider.get()
if (task == null) {
return
}
task.doLast {
def manifestFile = new File(task.manifestOutputDirectory.get().getAsFile(),"AndroidManifest.xml")
if (manifestFile == null || !manifestFile.exists()) {
return
}
def parser = new XmlParser(false, true)
def manifest = parser.parse(manifestFile)
def app = manifest.'application'[0]
app.'activity'.each{act->
String value = act.attributes()['android:configChanges']
if (value == null) {
value = "keyboardHidden|orientation|screenSize"
} else {
String[] valueSplit = value.split("\\|")
if (!valueSplit.contains("keyboardHidden")) {
value+="|keyboardHidden"
}
if (!valueSplit.contains("orientation")) {
value+="|orientation"
}
if (!valueSplit.contains("screenSize")) {
value+="|screenSize"
}
}
act.attributes()["android:configChanges"] = value
}
manifestFile.setText(XmlUtil.serialize(manifest), "utf-8")
}
}
}
}
}
请将此代码段添加到 app/build.gradle
的末尾。
英文:
After several days,I addressed this issue by my self,the correct way:
project.afterEvaluate {
def variants = null
try {
variants = android.applicationVariants
} catch (Throwable t) {
try {
variants = libraryVariants
} catch (Throwable tt) {}
}
if (variants != null) {
variants.all { variant ->
variant.outputs.each { output ->
def task = output.processManifestProvider.get()
if (task == null) {
return
}
task.doLast {
def manifestFile = new File(task.manifestOutputDirectory.get().getAsFile(),"AndroidManifest.xml")
if (manifestFile == null || !manifestFile.exists()) {
return
}
def parser = new XmlParser(false, true)
def manifest = parser.parse(manifestFile)
def app = manifest.'application'[0]
app.'activity'.each{act->
String value = act.attributes()['android:configChanges']
if (value == null) {
value = "keyboardHidden|orientation|screenSize"
} else {
String[] valueSplit = value.split("\\|")
if (!valueSplit.contains("keyboardHidden")) {
value+="|keyboardHidden"
}
if (!valueSplit.contains("orientation")) {
value+="|orientation"
}
if (!valueSplit.contains("screenSize")) {
value+="|screenSize"
}
}
act.attributes()["android:configChanges"] = value
}
manifestFile.setText(XmlUtil.serialize(manifest), "utf-8")
}
}
}
}
}
Add this code snippet into end of app/build.gradle
.
Well,the above way is only for the situation which every element of activity is not include attribute android:configChanges
or will got another question😂😂😂,I post it here.
Well again,🐶🐶🐶after several try,I fixed this problem by myself and I post correct answer in my another issue.
答案2
得分: 0
你可以使用清单占位符来解决:
-
清单:
<activity android:name=".YourActivity" android:configChanges="${configChanges}"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
-
Gradle:
defaultConfig {manifestPlaceholders = [ configChanges:"orientation"]}
英文:
You can solve by using manifest placeholders:
-
Manifest:
<activity android:name=".YourActivity" android:configChanges="${configChanges}"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
-
Gradle:
defaultConfig {manifestPlaceholders = [ configChanges:"orientation"]}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论