団結
ユニティ版 | Gradle バージョン | Android Gradle プラグインのバージョン |
---|---|---|
2023.1 | 7.3.3 | 7.2.1 |
2022.2 | 7.2 | 7.1.2 |
2022.1 2021.3 2021.2 2021.1 2021.1.16f1 以降 2020.3 2020.3.15f1 以降 |
6.1.1 | 4.0.1 |
2021.1 から 2021.1.15f1 まで 2020.1、2020.2、2020.3 から 2020.3.14f1 まで |
5.6.4 | 4.0.1 |
2019.4 | 5.1.1 | 3.4.0 |
アンドロイド:
プラグインのバージョン | 必要な Gradle バージョン |
---|---|
1.0.0 - 1.1.3 | 2.2.1 - 2.3 |
1.2.0 - 1.3.1 | 2.2.1 - 2.9 |
1.5.0 | 2.2.1 - 2.13 |
2.0.0 - 2.1.2 | 2.10 - 2.13 |
2.1.3 - 2.2.3 | 2.14.1+ |
2.3.0+ | 3.3+ |
3.0.0+ | 4.1+ |
3.1.0+ | 4.4+ |
3.2.0 - 3.2.1 | 4.6+ |
3.3.0 - 3.3.3 | 4.10.1+ |
3.4.0 - 3.4.3 | 5.1.1+ |
3.5.0 - 3.5.4 | 5.4.1+ |
3.6.0 - 3.6.4 | 5.6.4+ |
4.0.0+ | 6.1.1+ |
4.1.0+ | 6.5+ |
4.2.0+ | 6.7.1+ |
7.0 | 7.0+ |
7.1 / 7.1.2 | 7.2+ |
7.2 | 7.3+ |
7.3 / 7.3.0 | 7.4+ |
オンラインで見つかったバージョン:
android.applicationVariants.all { variant ->
variant.outputs.all { output ->
def processResources = output.hasProperty("processResourcesProvider") ?
output.processResourcesProvider.get() : output.processResources
processResources.doFirst { pm ->
String manifestPath = processResources.manifestFile
println "=====change manifestPath=====$manifestPath"
def manifestContent = file(manifestPath).getText()
def android = new groovy.xml.Namespace('http://schemas.android.com/apk/res/android', 'android')
def xml = new XmlParser().parseText(manifestContent)
def mainActivity = xml.application[0].activity.findAll() { ac ->
def action = ac.depthFirst().findAll() { node ->
return node.attribute(android.name) == 'android.intent.action.MAIN'
}
return action.size() > 0;
}
println "=====found main activity=====${mainActivity.size()} $mainActivity"
mainActivity[0].attributes().put(android.launchMode, 'singleTop')
def serialize = groovy.xml.XmlUtil.serialize(xml)
file(manifestPath).write(serialize)
}
}
}
android:LaunchModeから apk と AAB のバージョンをサポートするなぜ Unity はそれを singleTask として持っているのですか? - Unity フォーラム
// Override LibraryManifest.xml values and switch launchMode to standard
android.applicationVariants.all { variant ->
variant.outputs.each { output ->
def processManifest = output.getProcessManifestProvider().get()
processManifest.doLast { task ->
def outputDir = task.getManifestOutputDirectory()
File outputDirectory
if (outputDir instanceof File) {
outputDirectory = outputDir
} else {
outputDirectory = outputDir.get().asFile
}
File manifestOutFile = file("$outputDirectory/AndroidManifest.xml")
if (manifestOutFile.exists() && manifestOutFile.canRead() && manifestOutFile.canWrite()) {
def newManifest = manifestOutFile.getText().replace("android:launchMode=\"singleTask\"", "android:launchMode=\"standard\"")
manifestOutFile.write(newManifest, 'UTF-8')
}
// Make sure to modify bundle_manifest as well
outputDir = task.getBundleManifestOutputDirectory();
if (outputDir instanceof File) {
outputDirectory = outputDir
} else {
outputDirectory = outputDir.get().asFile
}
manifestOutFile = file("$outputDirectory/AndroidManifest.xml")
if (manifestOutFile.exists() && manifestOutFile.canRead() && manifestOutFile.canWrite()) {
def bundleManifest = manifestOutFile.getText().replace("android:launchMode=\"singleTask\"", "android:launchMode=\"standard\"")
manifestOutFile.write(bundleManifest, 'UTF-8')
}
}
}
}
私の最適化されたバージョンは次のとおりです (unity2022.2 より前のバージョンのみをサポートしています)。
// Override LibraryManifest.xml values and switch launchMode to singleTop
android.applicationVariants.all { variant ->
variant.outputs.each { output ->
def processManifest = output.getProcessManifestProvider().get()
processManifest.doLast { task ->
def outputDir = task.getManifestOutputDirectory()
println "=====change manifestPath==A===$outputDir"
File outputDirectory
if (outputDir instanceof File) {
outputDirectory = outputDir
} else {
outputDirectory = outputDir.get().asFile
}
File manifestOutFile = file("$outputDirectory/AndroidManifest.xml")
println "=====change manifestPath==B===$outputDirectory"
if (manifestOutFile.exists() && manifestOutFile.canRead() && manifestOutFile.canWrite()) {
/* def newManifest = manifestOutFile.getText().replace("android:launchMode=\"singleTask\"", "android:launchMode=\"standard\"")
manifestOutFile.write(newManifest, 'UTF-8') */
def manifestContent = file(manifestOutFile).getText()
def android = new groovy.xml.Namespace('http://schemas.android.com/apk/res/android', 'android')
def xml = new XmlParser().parseText(manifestContent)
def mainActivity = xml.application[0].activity.findAll() { ac ->
def action = ac.depthFirst().findAll() { node ->
return node.attribute(android.name) == 'android.intent.action.MAIN'
}
return action.size() > 0;
}
println "=====found main activity=====${mainActivity.size()} $mainActivity"
mainActivity[0].attributes().put(android.launchMode, 'singleTop')
def serialize = groovy.xml.XmlUtil.serialize(xml)
file(manifestOutFile).write(serialize)
}
// Make sure to modify bundle_manifest as well
outputDir = task.getBundleManifestOutputDirectory();
if (outputDir instanceof File) {
outputDirectory = outputDir
} else {
outputDirectory = outputDir.get().asFile
}
println "=====change manifestPath==C===$outputDirectory"
manifestOutFile = file("$outputDirectory/AndroidManifest.xml")
if (manifestOutFile.exists() && manifestOutFile.canRead() && manifestOutFile.canWrite()) {
/* def bundleManifest = manifestOutFile.getText().replace("android:launchMode=\"singleTask\"", "android:launchMode=\"standard\"")
manifestOutFile.write(bundleManifest, 'UTF-8') */
def manifestContent = file(manifestOutFile).getText()
def android = new groovy.xml.Namespace('http://schemas.android.com/apk/res/android', 'android')
def xml = new XmlParser().parseText(manifestContent)
def mainActivity = xml.application[0].activity.findAll() { ac ->
def action = ac.depthFirst().findAll() { node ->
return node.attribute(android.name) == 'android.intent.action.MAIN'
}
return action.size() > 0;
}
println "=====found main activity=====${mainActivity.size()} $mainActivity"
mainActivity[0].attributes().put(android.launchMode, 'singleTop')
def serialize = groovy.xml.XmlUtil.serialize(xml)
file(manifestOutFile).write(serialize)
}
}
}
}
ファローアップ:
参考リンク:
Android 12 は、エクスポートされたピット回避の詳細な分析に自動的に適応します - プログラマーが求めたもの
Android 12 は、エクスポートされた詳細な分析に自動的に適応し、落とし穴を回避します-コラム-SoundNet RTE Developer Community
上記のスクリプトは unity 2022.2 では有効ではなくなりました. 上記のリンクを参照して、さまざまなスクリプトの組み合わせを記述してください. android studio (plugs 7.4.1) と unity2022 で 3 つのスクリプトを試した後、最終的に最も効果的なスクリプトが得られました.
スクリプト 1 (unity は有効、android studio は無効)
android.applicationVariants.all { variant ->
variant.outputs.each { output ->
def vn
if (variant.getFlavorName() != null && variant.getFlavorName() != "") {
vn = variant.name;
} else {
if (variant.getBuildType().name == "release") {
vn = "Release"
} else {
vn = "Debug"
}
}
def taskName = "process${vn}MainManifest";
try {
println("=============== taskName ${taskName} ===============")
project.getTasks().getByName(taskName)
} catch (Exception e) {
return
}
///你的自定义名字
project.getTasks().getByName(taskName).doFirst {
it.getManifests().getFiles().each {
if (it.exists() && it.canRead() && it.canWrite()) {
def manifestFile = it
///这里第二个参数是 false ,所以 namespace 是展开的,所以下面不能用 androidSpace,而是用 nameTag
def xml = new XmlParser(false, false).parse(manifestFile)
if (xml.application != null && xml.application.size() > 0) {
def mainActivity = xml.application[0].activity.findAll { ac ->
def action = ac.depthFirst().findAll() { node ->
if(node != null){
return node.attributes().get("android:name") == 'android.intent.action.MAIN'
}
}
return action.size() > 0;
}
println "=====found main1 activity=====${mainActivity.size()} $mainActivity"
if(mainActivity[0]!=null){
mainActivity[0].attributes().put("android:launchMode", 'singleTop')
}
//mainActivity[0].attributes().put(android.launchMode, 'singleTop')
println "=====found main2 activity=====${mainActivity.size()} $mainActivity"
def serialize = groovy.xml.XmlUtil.serialize(xml)
file(it).write(serialize)
}
}
}
}
}
}
スクリプト 2 (android studio と UNITY の両方が無効)
android.applicationVariants.all { variant ->
variant.outputs.each { output ->
output.processResources.doLast {
String manifestPath = output.processResources.manifestFile
println "=====found manifestPath activity=====${manifestPath}"
def manifestOutFile = new File(manifestPath)
if (manifestOutFile.exists() && manifestOutFile.canRead() && manifestOutFile.canWrite()) {
///这里第二个参数是 false ,所以 namespace 是展开的,所以下面不能用 androidSpace,而是用 nameTag
def xml = new XmlParser(false, false).parse(manifestOutFile)
def nameTag = "android:name"
println "=====found xml activity=====${xml}"
if (xml.application != null && xml.application.size() > 0) {
def mainActivity = xml.application[0].activity.findAll { ac ->
def action = ac.depthFirst().findAll() { node ->
if (node != null) {
return node.attributes().get(nameTag) == 'android.intent.action.MAIN'
}
}
return action.size() > 0;
}
println "=====found main1 activity=====${mainActivity.size()} $mainActivity"
if (mainActivity[0] != null) {
mainActivity[0].attributes().put("android:launchMode", 'singleTop')
}
//mainActivity[0].attributes().put(android.launchMode, 'singleTop')
println "=====found main2 activity=====${mainActivity.size()} $mainActivity"
def serialize = groovy.xml.XmlUtil.serialize(xml)
file(manifestOutFile).write(serialize)
}
}
}
}
}
スクリプト 3 (android stuido unity の両方が有効)
android.applicationVariants.all { variant ->
variant.outputs.each { output ->
def processManifest = output.getProcessManifestProvider().get()
println("=============== processManifest ${processManifest} ===============")
processManifest.doLast() { task ->
def outputDir = task.multiApkManifestOutputDirectory
File outputDirectory
if (outputDir instanceof File) {
outputDirectory = outputDir
} else {
outputDirectory = outputDir.get().asFile
}
File manifestOutFile = file("$outputDirectory/AndroidManifest.xml")
println("----------- ${manifestOutFile} ----------- ")
if (manifestOutFile.exists() && manifestOutFile.canRead() && manifestOutFile.canWrite()) {
///这里第二个参数是 false ,所以 namespace 是展开的,所以下面不能用 androidSpace,而是用 nameTag
def xml = new XmlParser(false, false).parse(manifestOutFile)
println "=====found xml activity=====${xml}"
if (xml.application != null && xml.application.size() > 0) {
def mainActivity = xml.application[0].activity.findAll { ac ->
def action = ac.depthFirst().findAll() { node ->
if (node != null) {
return node.attributes().get('android:name') == 'android.intent.action.MAIN'
}
}
return action.size() > 0;
}
println "=====found main1 activity=====${mainActivity.size()} $mainActivity"
if (mainActivity[0] != null) {
mainActivity[0].attributes().put('android:launchMode', 'singleTop')
}
println "=====found main2 activity=====${mainActivity.size()} $mainActivity"
def serialize = groovy.xml.XmlUtil.serialize(xml)
file(manifestOutFile).write(serialize)
}
}
}
}
}