Gradle-如何从AndroidManifest获取值?

Gradle-如何从AndroidManifest获取值?,android,gradle,android-manifest,android-gradle-plugin,Android,Gradle,Android Manifest,Android Gradle Plugin,Android项目的内部build.gradle task runAndroidApplication(type: Exec, dependsOn: ':installDebug') { //TODO update Activity name below or find a way to get it from AndroidManifest.xml if (System.properties['os.name'].toLowerCase().contains('windows'

Android项目的内部
build.gradle

task runAndroidApplication(type: Exec, dependsOn: ':installDebug') {
    //TODO update Activity name below or find a way to get it from AndroidManifest.xml
    if (System.properties['os.name'].toLowerCase().contains('windows')) {
        // windows
        commandLine 'cmd', '/c', 'adb', 'shell', 'am', 'start', '-n', "com.example.androidapptorun.MainActivity"      
    } else {
        // linux 
        commandLine 'adb', 'shell', 'am', 'start', '-n', "com.example.androidapptorun.MainActivity"
    }
}
如何从默认活动的AndroidManifest中获取主活动的值? (另外,如果有多个活动,选择其中一个活动的逻辑将使其变长, 而处理将在Android工具中进行)

有没有更好的方法从android插件解析
AndroidManifest.xml


更新:可以满足某些需要,但我不需要参数版本,就可以通过在Eclipse中快速运行。您可以使用
XmlSlurper

例如:

AndroidManifest.xml

<manifest package="com.example.your.app">

我刚刚为adt20(L)、gradle1.12和
com.android.tools.build:Gradle:0.12.2写了这篇文章

它与风格、构建类型(不要忘记
myBuildType.initWith(existingBuildType)
)和
applicationIdSuffix
)一起工作

将以下内容放在android{…}
的末尾:

applicationVariants.all { variant ->
    if (variant.install) {
         tasks.create(name: "run${variant.name.capitalize()}", type: Exec, dependsOn: variant.install) {
            description "Installs the APK for ${variant.description}, and then runs the main launcher activity."
            def getMainActivity = { file ->
                new XmlSlurper().parse(file).application.activity.find{ it.'intent-filter'.find{ filter ->
                    return filter.action  .find{it.@name.text() == 'android.intent.action.MAIN'} \
                        && filter.category.find{it.@name.text() == 'android.intent.category.LAUNCHER'}
                }}.@name
            }
            doFirst {
                def activityClass = getMainActivity(variant.processManifest.manifestOutputFile)
                commandLine android.adbExe, 'shell', 'am', 'start', '-n', "${variant.packageName}/${activityClass}"
            }
        }
    }
}
对于库,您需要将
applicationVariants
更改为
libraryVariants
:请参阅

更新:ADT 20、Gradle 2.1和
com.android.tools.build:Gradle:0.13.1

applicationVariants.all { variant ->
    if (variant.install) {
        tasks.create(name: "run${variant.name.capitalize()}", type: Exec, dependsOn: variant.install) {
            description "Installs the APK for ${variant.description}, and then runs the main launcher activity."
            def getMainActivity = { file ->
                new XmlSlurper().parse(file).application.activity.find{ it.'intent-filter'.find{ filter ->
                    return filter.action  .find{it.'@android:name'.text() == 'android.intent.action.MAIN'      } \
                        && filter.category.find{it.'@android:name'.text() == 'android.intent.category.LAUNCHER'}
                }}.'@android:name'
            }
            doFirst {
                def activityClass = getMainActivity(variant.outputs.processManifest.manifestOutputFile)
                commandLine android.adbExe, 'shell', 'am', 'start', '-n', "${variant.applicationId}/${activityClass}"

                // or without the XML hacking: commandLine android.adbExe, 'shell', 'monkey', '-p', variant.applicationId, '1'
            }
        }
    }
}

你们看到了吗?那个就是在运行时从应用程序中读取
AndroidManifest.xml
。问题是关于构建系统梯度,即编译时,没有Android类。Found和XmlSluper。不是很干净的解决方案…gradle android命令插件[1]可以为您实现这一点。但是ATM不支持Windows。[1] 谢谢你的链接。也许将来他们会为manifest.xml提供很好的API谢谢,这非常有用。另外,您可以使用
android.sourceset.main.manifest.srcFile
而不是
“AndroidManifest.xml”
来自动定位清单文件
applicationVariants.all { variant ->
    if (variant.install) {
        tasks.create(name: "run${variant.name.capitalize()}", type: Exec, dependsOn: variant.install) {
            description "Installs the APK for ${variant.description}, and then runs the main launcher activity."
            def getMainActivity = { file ->
                new XmlSlurper().parse(file).application.activity.find{ it.'intent-filter'.find{ filter ->
                    return filter.action  .find{it.'@android:name'.text() == 'android.intent.action.MAIN'      } \
                        && filter.category.find{it.'@android:name'.text() == 'android.intent.category.LAUNCHER'}
                }}.'@android:name'
            }
            doFirst {
                def activityClass = getMainActivity(variant.outputs.processManifest.manifestOutputFile)
                commandLine android.adbExe, 'shell', 'am', 'start', '-n', "${variant.applicationId}/${activityClass}"

                // or without the XML hacking: commandLine android.adbExe, 'shell', 'monkey', '-p', variant.applicationId, '1'
            }
        }
    }
}