求助:如何创建Android Library Module模板以快速生成功能模块骨架
Hey there! I’ve been exactly where you are—building reusable activity templates saved me tons of time, but scaling that to library modules felt like a missing piece. Let’s break down how to build a custom library module template that lets you input a module name, pick a language (Java/Kotlin), and generate a fully functional skeleton automatically.
Step 1: Set Up the Template Directory Structure
First, navigate to your Android Studio templates folder (the path varies by OS):
- Windows:
C:\Users\<YourUsername>\.AndroidStudio<Version>\config\templates - Mac:
~/Library/Application Support/Google/AndroidStudio<Version>/templates
Create a new folder named CustomFeatureLibrary (or whatever you want to call your template). Inside it, you’ll need these core files:
template.xml: Defines template metadata and user input fieldsrecipe.xml.ftl: The "script" that handles file generation and project setuproot/: A folder containing all your template files (build.gradle, source code, etc.)
Step 2: Configure template.xml
This file tells Android Studio what inputs to ask the user, and basic info about your template. Here’s an example:
<?xml version="1.0" encoding="UTF-8"?> <template name="Custom Feature Library" description="Generates a modular library with Model, Adapter, Holder skeleton" category="Android" formfactor="Mobile" minApi="21"> <parameter id="moduleName" name="Library Module Name" type="string" constraints="nonempty" default="FeatureLibrary"/> <parameter id="language" name="Language" type="enum" default="kotlin" options="java,kotlin"/> <thumbs> <thumb>template_thumb.png</thumb> <!-- Optional: Add a thumbnail for your template --> </thumbs> <globals> <global id="packageName" value="com.example.${moduleName?lower_case?replace(' ', '_')}"/> </globals> </template>
- The
globalssection creates a derivedpackageNamefrom the user’smoduleName(lowercase, spaces replaced with underscores) to keep things consistent.
Step 3: Write the recipe.xml.ftl (The Magic Part)
This is where you define exactly what files to create, where to put them, and how to modify the project’s settings. Here’s a complete example:
<?xml version="1.0" encoding="UTF-8"?> <recipe> <!-- Create the module directory --> <mkdir path="${escapeXmlAttribute(projectDir)}/${moduleName}"/> <!-- Copy core library files --> <copy from="root/build.gradle.ftl" to="${projectDir}/${moduleName}/build.gradle"/> <copy from="root/AndroidManifest.xml" to="${projectDir}/${moduleName}/src/main/AndroidManifest.xml"/> <!-- Handle language-specific source files --> <if condition="${language} == 'kotlin'"> <mkdir path="${projectDir}/${moduleName}/src/main/kotlin/${packageName?replace('.', '/')}"/> <copy from="root/kotlin/Model.kt.ftl" to="${projectDir}/${moduleName}/src/main/kotlin/${packageName?replace('.', '/')}/Model.kt"/> <copy from="root/kotlin/ItemAdapter.kt.ftl" to="${projectDir}/${moduleName}/src/main/kotlin/${packageName?replace('.', '/')}/ItemAdapter.kt"/> <copy from="root/kotlin/ItemHolder.kt.ftl" to="${projectDir}/${moduleName}/src/main/kotlin/${packageName?replace('.', '/')}/ItemHolder.kt"/> </if> <if condition="${language} == 'java'"> <mkdir path="${projectDir}/${moduleName}/src/main/java/${packageName?replace('.', '/')}"/> <copy from="root/java/Model.java.ftl" to="${projectDir}/${moduleName}/src/main/java/${packageName?replace('.', '/')}/Model.java"/> <copy from="root/java/ItemAdapter.java.ftl" to="${projectDir}/${moduleName}/src/main/java/${packageName?replace('.', '/')}/ItemAdapter.java"/> <copy from="root/java/ItemHolder.java.ftl" to="${projectDir}/${moduleName}/src/main/java/${packageName?replace('.', '/')}/ItemHolder.java"/> </if> <!-- Add the module to settings.gradle --> <open file="${projectDir}/settings.gradle"/> <execute command="sed -i '' '$a include \':${moduleName}\'' ${projectDir}/settings.gradle" os="mac"/> <execute command="echo include \':${moduleName}\' >> ${projectDir}/settings.gradle" os="windows"/> <!-- Open the build.gradle of the new module after generation --> <open file="${projectDir}/${moduleName}/build.gradle"/> </recipe>
- The
executecommands add the new module tosettings.gradle—note the OS-specific syntax (sed for Mac, echo for Windows). - Use
${packageName?replace('.', '/')}to convert the package name (likecom.example.mylibrary) into a directory path (com/example/mylibrary).
Step 4: Prepare Your Template Files in the root/ Folder
Inside the root folder, create the files you want to generate, using FTL placeholders for dynamic values. For example:
- root/build.gradle.ftl:
plugins { id 'com.android.library' <if condition="${language} == 'kotlin'">id 'org.jetbrains.kotlin.android'</if> } android { namespace '${packageName}' compileSdk 34 defaultConfig { minSdk 21 targetSdk 34 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles "consumer-rules.pro" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } <if condition="${language} == 'kotlin'"> kotlinOptions { jvmTarget = '1.8' } </if> } dependencies { implementation 'androidx.core:core-ktx:1.12.0' implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'com.google.android.material:material:1.11.0' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' } - root/kotlin/Model.kt.ftl:
package ${packageName} data class Model( val id: Int, val title: String, val description: String )
Step 5: Test Your Template
- Restart Android Studio
- Go to File > New > New Module
- You should see your custom template listed under the Android category
- Input your module name, pick a language, and generate—your library skeleton should be ready to go!
Debugging Tips
- If the template doesn’t show up, double-check the directory structure and template.xml syntax
- If files aren’t generated correctly, check the Android Studio logs (Help > Show Log in Explorer/Finder) for errors
- Test both Java and Kotlin options to make sure language-specific logic works as expected
内容的提问来源于stack exchange,提问作者Mostafa Addam

