Android Groovy 动态(十三)

首先申明下,本文为笔者学习《Groovy 程序设计》的笔记,并加入笔者自己的理解和归纳总结。

1. 动态访问

访问属性

class AGroovyClass {
    int value = 10
}

obj = new AGroovyClass()
pName = "value"

println obj["value"] // 10
println obj.value // 10
println obj["$pName"] // 10
println obj."$pName" // 10

obj.properties.each {
    println it
}
// value=10
// class=class AGroovyClass
println obj.properties.value //  10

访问方法

class AGroovyClass {
    def add(val1, val2) {
        val1 + val2
    }
}
obj = new AGroovyClass()
mName = 'add'
method = AGroovyClass.metaClass.getMetaMethod(mName, null, null)
println method.invoke(obj, 11, 13) // 24
println method.invoke(obj, "Hello ", "World!") // Hello World!

println obj.invokeMethod(mName, [11, 13]) // 24
println obj.invokeMethod(mName, ["Hello ", "World!"]) // Hello World!

2. Expando类提供了动态合成类的能力。

动态属性

peopleA = new Expando()
peopleA.name = "Jack"
peopleA["addr"] = "ShangHai"
println peopleA // {name=Jack, addr=ShangHai}

peopleB = new Expando(name : "Mike", addr : "ShengZhen")
println peopleB // {name=Mike, addr=ShengZhen}

动态方法

peopleA = new Expando(name : "Jack", addr : "ShangHai", toString : { "$name live in $addr" } )
println peopleA.toString() // Jack live in ShangHai

peopleB = new Expando(name : "Mike", addr : "ShengZhen")
peopleB.toString = { "$name live in $addr" }
println peopleB.toString() // Mike live in ShengZhen

3. 方法合成

方法合成在调用时动态地确定方法的行为。

GroovyObject中合成方法,使用methodMissing()方法来拦截未定义方法并进行处理。

class AGroovyClass {
    def methodMissing(String name, args) {
        println "In methodMissing " + name

        if (name == "add") {
            println "In add function"
        }
    }
}
obj = new AGroovyClass()
obj.add()
obj.del()
obj.add()

返回

In methodMissing add
In add function
In methodMissing del
In methodMissing add
In add function

把动态办法添加到metaClass中,这样不必每次都进入methodMissing()方法中。缓存add()方法,第二次调用时直接使用metaClassadd()方法,提高了效率。

class AGroovyClass {
    def methodMissing(String name, args) {
        println "In methodMissing " + name

        if (name == "add") {
            println "In add function"

            def func = { Object[] vargs ->
                println "in add func " + vargs
            }
            AGroovyClass instance = this
            instance.metaClass."$name" = func
            func(args)
        }
    }
}
obj = new AGroovyClass()
obj.add(11)
obj.add(11, 12)
obj.add("Hello ", "World!")

返回

In methodMissing add
In add function
in add func [11]
in add func [11, 12]
in add func [Hello , World!]

GroovyInterceptable中合成方法,使用invokeMethod()方法来拦截未定义方法并进行处理。每次都先查询metaClass中是否存在该方法,存在的话直接调用,不存在的再定义。

class AnInterceptable implements GroovyInterceptable {

    def invokeMethod(String name, args) {
        System.out.println("In invokeMethod " + name) 

        def method = metaClass.getMetaMethod(name, args)
        if (method) { // 直接进行方法调用
            method.invoke(this, args)
        } else { // 调用metaClass的invokeMethod方法,会在methodMissing中重新定义。
            metaClass.invokeMethod(this, name, args)
        }
    }

    def methodMissing(String name, args) {
        System.out.println("In methodMissing " + name)

        if (name == "add") {
            System.out.println("In add function");

            def func = { Object[] vargs ->
                System.out.println("in add func " + vargs)
            }
            AnInterceptable instance = this
            instance.metaClass."$name" = func
            func(args)
        }
    }
}
obj = new AnInterceptable()
obj.add(11)
obj.add(11, 12)
obj.add("Hello ", "World!")

返回

In invokeMethod add
In methodMissing add
In add function
in add func [11]
In invokeMethod add
in add func [11, 12]
In invokeMethod add
in add func [Hello , World!]

MetaClass合成

class AGroovyClass {
}
AGroovyClass.metaClass.methodMissing = { String name, args ->
    println "In methodMissing " + name

    if (name == "add") {
        println "In add function"

        def func = { Object[] vargs ->
            println "in add func " + vargs
        }
        AGroovyClass.metaClass."$name" = func
        func(args)
    }
}
obj = new AGroovyClass()
obj.add(11)
obj.add(11, 12)
obj.add("Hello ", "World!")

返回

In methodMissing add
In add function
in add func [11]
in add func [11, 12]
in add func [Hello , World!]

4. 动态委托

Teacher的工作委托给各个科目去完成。

class Chinese {
    def chineseTech() {
        println "Chinese Teacher do the work"
    }
}

class English {
    def englishTech() {
        println "Chinese Teacher do the work"
    }
}

class Math {
    def mathTech() {
        println "Chinese Teacher do the work"
    }
}

class Teacher {
    Teacher() {
        delegateTo Chinese, English, Math
    }

    def delegateTo(Class... classes) {
        def objOfDelegate = classes.collect { it.newInstance() }

        Teacher instance = this
        instance.metaClass.methodMissing = { String name, args ->
            println "In methodMissing"
            def delegate = objOfDelegate.find {
                it.metaClass.respondsTo(it, name, args)
            }
            if (delegate) {
                instance.metaClass."$name" = { Object[] vargs ->
                    delegate.invokeMethod(name, vargs)
                }
                delegate.invokeMethod(name, args)
            } else {
                println "no delegate"
            }
        }
    }
}

tech = new Teacher();
tech.chineseTech()
tech.englishTech()
tech.mathTech()
tech.mathTech()
tech.physicsTech()

返回

In methodMissing
Chinese Teacher do the work
In methodMissing
English Teacher do the work
In methodMissing
Math Teacher do the work
Math Teacher do the work
In methodMissing
no delegate
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
动态创建Gradle是指在Android项目中通过代码的方式来生成或修改Gradle配置文件。这样可以在运行时根据需要添加、删除或修改依赖项、插件和其他构建配置。 在Android项目中,可以通过Groovy或Kotlin脚本来动态创建Gradle。通过编写脚本,可以使用Gradle提供的API来操作Gradle配置文件。例如,可以使用API添加依赖项、修改版本号、配置构建类型等。 要动态创建Gradle,可以在项目的build.gradle文件中使用Groovy或Kotlin代码块。在这些代码块中,可以使用Gradle提供的API来操作Gradle配置。例如,可以使用`dependencies`块来添加依赖项,使用`android`块来配置Android构建选项。 需要注意的是,动态创建Gradle需要对GradleAndroid构建系统有一定的了解。同时,修改Gradle配置可能会对项目的构建和运行产生影响,因此在进行修改之前应该进行充分的测试和验证。 总结来说,动态创建Gradle是通过在Android项目中使用Groovy或Kotlin脚本来生成或修改Gradle配置文件,以实现根据需要添加、删除或修改依赖项、插件和其他构建配置的目的。 #### 引用[.reference_title] - *1* [Android Gradle - AndroidStudio 中 Gradle 依赖全解](https://blog.csdn.net/qq_20451879/article/details/114280089)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Android Studio之GradleGradle插件的区别](https://blog.csdn.net/s_nshine/article/details/104021909)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值