Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gradle - how does interface org.gradle.api.Action work?

Tags:

android

gradle

I'm trying to understand android plugin, when I look at "defaultConfig", I find the method is

public void defaultConfig(Action<ProductFlavor> action) {
    this.checkWritability();
    action.execute(this.defaultConfig);
}

and calling action.execute(this.defaultConfit) invokes the closure against this.defaultConfig.

This is confusing, so I looked at doc of interface Action to see what magic it has.

According to doc of Action interface, when calling action.execute(obj), it actually "Performs this action against the given object", and the given object here is obj.

How does this work?

ASAIK, if I wish to call a method against obj, I use "it" to reference to the obj: it.doSth(), otherwise the method will be invoked against "this".

But when using Action interface, "it" is no more necessary and method calls within this interface will just be invoked against "it".

I also write some code to test it:

class Main {
        Test test = new Test()
        test.actionReceiver {
//            actionName "test ok"
            it.actionName "test ok"

        }

    }

    static interface MyAction<T> {
        void execute(T)
    }

    static class MyActionReceiver {
        void actionName(String name) {
            println name
        }
    }

    static class Test {
        MyActionReceiver actionReceiver = new MyActionReceiver()

        void actionReceiver(MyAction<MyActionReceiver> action) {
            action.execute(actionReceiver)
        }

    }

}

If my interface MyAction had the magic that Action interface has, then calling actionName without "it" should just work, however it didn't.

My question is: how Action interface works and how can I make my interface work the same way?

like image 969
gaolf Avatar asked Oct 30 '22 03:10

gaolf


1 Answers

Gradle tasks can contain one or more Actions. You can find more about Actions here: https://docs.gradle.org/current/javadoc/org/gradle/api/Action.html#execute(T) Actions are typically defined in the

doFirst{...}

or

doLast{...}

block of a task definition. See:

task hello {
    doLast {
        println 'Hello world!'
    }
}

When writing custom tasks you can simply annotate your main action with the @TaskAction annotation:

task hello(type: GreetingTask)

class GreetingTask extends DefaultTask {
    @TaskAction
    def greet() {
         println 'hello from GreetingTask'
     }
}

Some more helpful links:

https://docs.gradle.org/current/userguide/tutorial_using_tasks.html https://docs.gradle.org/current/javadoc/org/gradle/api/Task.html

like image 50
and_dev Avatar answered Nov 15 '22 06:11

and_dev