Gradle Tasks: Export an Android native plugin into Unity with gradle
I’m developing some Android Native Plugins for Unity and decided to implement some Gradle Tasks to export the plugin into Unity as a .jar, .aar or a library android project.
Each native functionality is in a separate android module, as you can see in the picture. IMHO, this way it’s possible to import only the necessary modules into each project and it’s also easier to test, maintain and update (I would appreciate your input about this question).
I needed a Gradle Task that could be written once and used on each module as necessary. So all my tasks are inside the build.gradle file for the entire project.
Here is the complete build.gradle file. Next, we’ll see how to use it.
Gradle Tasks
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.2.3' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { jcenter() } } // MY GRADLE TASKS subprojects { // path to Assets folder of the Unity Project String unityAssetsDir = "${rootDir.getPath()}/../addcomponent-native-unity/Assets/"; // path to the specific directory inside the Assets folder String unityTargetDir = unityAssetsDir + "Plugins/Android/"; // how to call the tasks group on the Gradle View String taskGroupName = "plugins"; // the current build type, right now it has no difference: debug; release String buildType = "debug"; /***** .JAR *****/ task exportJAR(dependsOn: "assemble" + buildType.capitalize(), type: Copy, group: taskGroupName) { // where the .jar file is located when we build the module String sourceDir = "${buildDir.getPath()}/intermediates/bundles/" + buildType + "/"; // how the .jar file is called when we build the module String sourceFilename = "classes.jar"; // how we want to call the .jar file when importing into Unity String targetFilename = "addcomponent-${project.name}.jar"; // copy the .jar file into the Unity folder // include the .jar file and rename it from(sourceDir) into(unityTargetDir) include(sourceFilename) rename(sourceFilename, targetFilename) } /***** .AAR *****/ task exportAAR(dependsOn: "assemble" + buildType.capitalize(), type: Copy, group: taskGroupName) { // where the .aar file is located when we build the module String sourceDir = "${buildDir.getPath()}/outputs/aar/"; // how the .aar file is called when we build the module String sourceFilename = "${project.name}-" + buildType + ".aar"; // how we want to call the .aar file when importing into Unity String targetFilename = "addcomponent-${project.name}.aar"; // copy the .aar file into the Unity folder // include the .aar file and rename it from(sourceDir) into(unityTargetDir) include(sourceFilename) rename(sourceFilename, targetFilename) } /***** LIBRARY PROJECT *****/ // this task creates a necessary project.properties file so that Unity recognizes the folder // as a library android project task createProperties() << { // project.properties path String properties = unityTargetDir + "addcomponent-${project.name}/" + "project.properties"; // creates the file def file = new File(properties); file.createNewFile(); } task exportLibrary(dependsOn: ["assemble" + buildType.capitalize()], type: Copy, group: taskGroupName) { // where the .jar file is located when we build the module String sourceDir = "${buildDir.getPath()}/intermediates/bundles/" + buildType + "/"; // the res folder String resources = "res/"; // the manifest filename String manifest = "AndroidManifest.xml"; // copy the jar file, // include the res folder and the AndroidManitest.xml // place the jar file inside a /libs folder from(sourceDir) into(unityTargetDir + "addcomponent-${project.name}/") include(resources, manifest, 'classes.jar') rename('classes.jar', 'libs/classes.jar') } // run the create properties task at the end exportLibrary.finalizedBy createProperties } // END OF MY GRADLE TASKS task clean(type: Delete) { delete rootProject.buildDir } |
The easiest way to use the new Gradle Tasks is selecting them on the Gradle Window.




Each one of the modules will have a group called plugins with the three tasks inside, exportAAR, exportJAR and exportLibrary. You can double-click on the task name to run it.
However, this will run the selected task on all modules!
This is not the intended behaviour when trying to export a single module into the desired project. So far, I was not able to understand why it happens when using the gradle window. So I’ve decided to run the tasks using the Terminal window.
To run a task for a single module type the following:
./gradlew <modulename>:<taskname>
Just as an example, the next image is the result when you export the same module using all the different tasks.




To know more about Android Native Plugins, check my previous tutorial on the subject and to get really deep into it, I highly recommend this great tutorial by eppz.
I will post a later article on building each one of this modules and on building a Unity Project including plugins and resolving dependencies issues, merging manifests, using the Google Play Resolver, etc (I’m still fighting with all this).
Stay tuned 🙂
Happy Coding
You must log in to post a comment.