Created a new module Android library

Answered

Hello, when Android Studio removed support for the old fashioned template files, we starting using plugins to support the "New Module" templates that used to work. The idea is that users can right click on an app, select "Other->Custom Module" and then a new Android module would appear with customized build.gradle files.  

Here's what I'm trying.  The error is Can't support Java Module and Gradle Module in one project.  How do I make an Android Module?

fun RecipeExecutor.customModuleSetup(
moduleData: ModuleTemplateData,
packageName: String,
entityName: String,
moduleName: String,
) {
val (projectData) = moduleData
val project = projectInstance ?: return
addAllKotlinDependencies(moduleData)

val file = try {
WriteCommandAction.writeCommandAction(project).compute(ThrowableComputable<ContentEntry, RuntimeException> {
var f: VirtualFile = createProjectSubFile(ModuleRootManager.getInstance(ModuleManager.getInstance(project).modules[0]).contentRoots[0].path, "$moduleName/$moduleName.iml")
val module = ModuleManager.getInstance(project).newModule(f.path, ModuleTypeId.JAVA_MODULE)
PsiTestUtil.addContentRoot(module, f.parent)
})
} catch (e: IOException) {
throw RuntimeException(e)
}

if (file != null) {
gradleFile(moduleName).save(PsiManager.getInstance(project).findDirectory(file.file!!)!!, "", "build.gradle")
}
}

@Throws(IOException::class)
fun createProjectSubFile(projectPath: String?, relativePath: String?): VirtualFile {
val f = File(projectPath, relativePath)
FileUtil.ensureExists(f.getParentFile())
FileUtil.ensureCanCreateFile(f)
val created: Boolean = f.createNewFile()
if (!created && !f.exists()) {
throw AssertionError("Unable to create the project sub file: " + f.getAbsolutePath())
}
return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(f)!!
}


fun String.save(srcDir: PsiDirectory, subDirPath: String, fileName: String) {
try {
val destDir = subDirPath.split(".").toDir(srcDir)
val psiFile = PsiFileFactory
.getInstance(srcDir.project)
.createFileFromText(fileName, KotlinLanguage.INSTANCE, this)
destDir.add(psiFile)
}catch (exc: Exception) {
exc.printStackTrace()
}
}

 

 

0
1 comment
Official comment

Hi, Dinhxphong,

Major idea behind all these templates in Android Plugin is that one never need to manipulate with IDEA project structure directly. Instead, valid gradle files should be generated, and then gradle sync should be invoked. Sync is automatically invoked by the wizard after user clicks "finish". Files are generated and updated by different recipes during model rendering.

Given that `RecipeExecutor.customModuleSetup` is a recipe for a new module, proper way to include new module into android-gradle project is to use `addIncludeToSettings(moduleName)`. E.g.

import com.android.tools.idea.npw.module.recipes.androidConfig
import com.android.tools.idea.wizard.template.impl.activities.common.addAllKotlinDependencies
...

fun
RecipeExecutor.customModuleSetup(
moduleData: ModuleTemplateData
) {
// com.android.tools.idea.wizard.template.RecipeExecutor.addIncludeToSettings
addIncludeToSettings(moduleData.name)

// com.android.tools.idea.wizard.template.RecipeExecutor.save
save(createGradleFileContent(), moduleData.rootDir.resolve("build.gradle"))

// com.android.tools.idea.wizard.template.RecipeExecutor.applyPlugin
applyPlugin("com.android.library")
applyPlugin("com.example.myplugin")
addAllKotlinDependencies(moduleData)
}

private fun createGradleFileContent(): String {
return androidConfig(
buildApiString = "24",
explicitBuildToolsVersion = true,
buildToolsVersion = "30.0.3",
minApi = "30",
targetApi = "30",
useAndroidX = true,
cppFlags = "",
isLibraryProject = true,
hasApplicationId = true,
applicationId = "com.example.mylib",
)
// see also: com.android.tools.idea.npw.module.recipes.CommonModuleRecipeKt#generateCommonModule
}

For more examples please take a look at the android plugin sources. Good starting point is `com.android.tools.idea.npw.module.NewAndroidModuleDescriptionProvider`, which contributes different types of Android modules to the "New Module Wizard".

-- Thanks

Please sign in to leave a comment.