├── Generate.java ├── build ├── freemarker.jar ├── marker ├── .gitignore.ftl ├── .gitignore1.ftl ├── AndroidManifest.xml.ftl ├── ExampleInstrumentedTest.java.ftl ├── ExampleUnitTest.java.ftl ├── MainActivity.java.ftl ├── build.gradle.ftl ├── build.gradle1.ftl ├── globals.xml.ftl └── proguard-rules.pro.ftl └── res ├── drawable-v24 └── ic_launcher_foreground.xml ├── drawable └── ic_launcher_background.xml ├── layout └── activity_main.xml ├── mipmap-anydpi-v26 ├── ic_launcher.xml └── ic_launcher_round.xml ├── mipmap-hdpi ├── ic_launcher.png └── ic_launcher_round.png ├── mipmap-mdpi ├── ic_launcher.png └── ic_launcher_round.png ├── mipmap-xhdpi ├── ic_launcher.png └── ic_launcher_round.png ├── mipmap-xxhdpi ├── ic_launcher.png └── ic_launcher_round.png ├── mipmap-xxxhdpi ├── ic_launcher.png └── ic_launcher_round.png └── values ├── colors.xml ├── strings.xml └── styles.xml /Generate.java: -------------------------------------------------------------------------------- 1 | 2 | import java.io.File; 3 | import java.io.FileWriter; 4 | import java.util.ArrayList; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | import freemarker.template.Configuration; 10 | import freemarker.template.Template; 11 | 12 | public class Generate { 13 | //当前java文件所在的路径,即这个工具所在的根目录。 14 | public final static String ROOT_PATH = Generate.class.getResource("").getPath(); 15 | //模板文件所在的路径。 16 | public final static String FTL_PATH = ROOT_PATH+"/marker"; 17 | 18 | //项目根目录。 19 | public static String PROJECT_ROOT = ""; 20 | 21 | //包名 22 | public static String PACKGE_NAME = ""; 23 | 24 | //所有依赖库拼接而成的字符串,以#分割。 25 | public static String DEPENDENCIES_STR_IN = ""; 26 | 27 | //项目根目录下build.gradle所需要的配置(通常以classpath开头) 28 | public static String DEPENDENCIES_STR_OUT = ""; 29 | 30 | //项目根目录下build.gradle所需要的仓库配置。(如 jcenter()、mavenCentral()) 31 | public static String DEPENDENCIES_REPOSITORIES = ""; 32 | 33 | public static void main(String[] args) throws Exception { 34 | //传递进来三个参数,第一个是项目名,第二个是包名,第三个是所有的依赖库拼接而成的字符串。 35 | PROJECT_ROOT = args[0]; 36 | PACKGE_NAME = args[1]; 37 | 38 | createBuildGradle(); 39 | 40 | createAppBuildGradle(PROJECT_ROOT+"/app"); 41 | createAndroidManifest(); 42 | createIgnoreAndProguardFiles(); 43 | createTestFiles(); 44 | createMainActivity(); 45 | } 46 | 47 | //生成module的build.gradle文件 48 | private static void createAppBuildGradle(String appPath) throws Exception { 49 | Template template = getTemplate("build.gradle1.ftl"); 50 | File file = new File(appPath+"/build.gradle"); 51 | if(!file.exists()) { 52 | file.createNewFile(); 53 | } 54 | FileWriter fileWriter = new FileWriter(file); 55 | Map map = new HashMap<>(); 56 | 57 | map.put("packageName", PACKGE_NAME); 58 | template.process(map, fileWriter); 59 | fileWriter.close(); 60 | } 61 | 62 | /* 63 | * 生成项目的build.gradle 64 | * */ 65 | public static void createBuildGradle() throws Exception{ 66 | // 在模板文件目录中找到名称为name的文件 67 | Template template = getTemplate("build.gradle.ftl"); 68 | FileWriter fileWriter = new FileWriter(new File(PROJECT_ROOT+"/build.gradle")); 69 | 70 | Map map = new HashMap<>(); 71 | map.put("gradlePluginVersion", "3.2.1"); 72 | template.process(map, fileWriter); 73 | fileWriter.close(); 74 | } 75 | 76 | /* 77 | * 生成AndroidManifest文件 78 | * */ 79 | 80 | public static void createAndroidManifest() throws Exception { 81 | Template template = getTemplate("AndroidManifest.xml.ftl"); 82 | FileWriter fileWriter = new FileWriter(new File(PROJECT_ROOT+"/app/src/main/AndroidManifest.xml")); 83 | Map map = new HashMap<>(); 84 | map.put("packageName", PACKGE_NAME); 85 | template.process(map, fileWriter); 86 | fileWriter.close(); 87 | } 88 | 89 | 90 | /*创建混淆文件和忽略文件*/ 91 | 92 | public static void createIgnoreAndProguardFiles() throws Exception{ 93 | //project下的忽略文件 94 | Template template = getTemplate(".gitignore.ftl"); 95 | File projectIgnoreFile = new File(PROJECT_ROOT+"/.gitignore"); 96 | if(!projectIgnoreFile.exists()) { 97 | projectIgnoreFile.createNewFile(); 98 | } 99 | FileWriter fileWriter = new FileWriter(projectIgnoreFile); 100 | Map map = new HashMap<>(); 101 | template.process(map, fileWriter); 102 | 103 | 104 | //module下的忽略文件 105 | Template template1 = getTemplate(".gitignore1.ftl"); 106 | File moduleIgnoreFile = new File(PROJECT_ROOT+"/app/.gitignore"); 107 | if(!moduleIgnoreFile.exists()) { 108 | moduleIgnoreFile.createNewFile(); 109 | } 110 | FileWriter fileWriter1 = new FileWriter(moduleIgnoreFile); 111 | Map map1 = new HashMap<>(); 112 | template1.process(map1, fileWriter1); 113 | fileWriter1.close(); 114 | 115 | //创建混淆文件 116 | Template template2 = getTemplate("proguard-rules.pro.ftl"); 117 | File proguardFile = new File(PROJECT_ROOT+"/app/proguard-rules.pro"); 118 | if(!proguardFile.exists()) { 119 | proguardFile.createNewFile(); 120 | } 121 | FileWriter fileWriter2 = new FileWriter(proguardFile); 122 | Map map2 = new HashMap<>(); 123 | template2.process(map2, fileWriter2); 124 | 125 | //关流。 126 | fileWriter.close(); 127 | fileWriter1.close(); 128 | fileWriter2.close(); 129 | 130 | } 131 | 132 | /* 133 | * 创建Test文件 134 | * */ 135 | public static void createTestFiles() throws Exception{ 136 | 137 | //创建ExampleUnitTest类 138 | Template template = getTemplate("ExampleUnitTest.java.ftl"); 139 | String [] packages = PACKGE_NAME.split("\\."); 140 | String testFilePath = PROJECT_ROOT+"/app/src/test/java"; 141 | for(int i=0;i map = new HashMap<>(); 150 | map.put("packageName", PACKGE_NAME); 151 | template.process(map, fileWriter); 152 | 153 | 154 | //创建ExampleInstrumentedTest类 155 | Template template1 = getTemplate("ExampleInstrumentedTest.java.ftl"); 156 | String androidTestFilePath = PROJECT_ROOT+"/app/src/androidTest/java"; 157 | for(int i=0;i map1 = new HashMap<>(); 166 | map1.put("packageName", PACKGE_NAME); 167 | template1.process(map1, fileWriter1); 168 | fileWriter.close(); 169 | fileWriter1.close(); 170 | } 171 | 172 | 173 | public static void createMainActivity() throws Exception{ 174 | Template template = getTemplate("MainActivity.java.ftl"); 175 | String [] packages = PACKGE_NAME.split("\\."); 176 | String mainActivityPath = PROJECT_ROOT+"/app/src/main/java"; 177 | for(int i=0;i map = new HashMap<>(); 186 | map.put("packageName", PACKGE_NAME); 187 | template.process(map, fileWriter); 188 | fileWriter.close(); 189 | } 190 | 191 | 192 | public static Template getTemplate(String templateName) throws Exception{ 193 | Configuration configuration = new Configuration(); 194 | configuration.setDirectoryForTemplateLoading(new File(FTL_PATH)); 195 | Template template = configuration.getTemplate(templateName); 196 | return template; 197 | } 198 | 199 | } 200 | -------------------------------------------------------------------------------- /build: -------------------------------------------------------------------------------- 1 | # @author Huxin 2019/2/2 2 | 3 | echo "create project start..." 4 | 5 | #check project name 6 | #if empty 7 | if [ -z "$1" ];then 8 | echo "please input the project name,such as './bulid Test com.example '" 9 | echo "create project fail !" 10 | exit 0 11 | fi 12 | 13 | #if exist 14 | if [ -d "$1" ]; then 15 | echo "The project \"$1\" had exists, you must use another name" 16 | echo "create project fail !" 17 | exit 0 18 | fi 19 | 20 | #check project package name 21 | if [ -z "$2" ];then 22 | package="com.example.apps"; 23 | else 24 | #package=$(echo $2 | tr '[A-Z]' '[a-z]' ) 25 | package=$2 26 | fi 27 | 28 | 29 | #get lowercase project name 30 | var=$(echo $1 | tr '[A-Z]' '[a-z]' ) 31 | 32 | package_dir=$(echo $package | sed -e 's/\./\//g' ) 33 | 34 | #make project dir 35 | mkdir $1 36 | 37 | #into project root dir 38 | cd $1 39 | 40 | #init gradle 41 | gradle init 42 | 43 | if [ $? -eq 0 ]; then 44 | #back tools root dir 45 | cd .. 46 | fi 47 | 48 | 49 | #change code path 50 | rm -rf $1/app/src/main/java/ 51 | mkdir -p $1/app/src/main/java/$package_dir 52 | 53 | mkdir -p $1/app/src/test/java/$package_dir 54 | 55 | mkdir -p $1/app/src/androidTest/java/$package_dir 56 | 57 | cp -r res/ $1/app/src/main/res 58 | 59 | sed -i "s/appName/$1/g" $1/app/src/main/res/values/strings.xml 60 | 61 | #into project root dir 62 | cd $1 63 | echo "" >settings.gradle 64 | echo "include ':app'" >settings.gradle 65 | cd app 66 | 67 | mkdir libs 68 | 69 | #back project root dir 70 | cd .. 71 | cd .. 72 | 73 | file=$4 74 | 75 | # generate class 76 | class=$(echo $file | awk -F '.' '{print $1}') 77 | 78 | 79 | echo "start compile......." 80 | 81 | # compile java class 82 | javac -encoding UTF-8 -cp freemarker.jar Generate.java 83 | 84 | if [ $? -eq 0 ]; then 85 | echo "compile success,ready run..." 86 | 87 | # run 88 | java -cp ".;freemarker.jar" Generate "$1" "$2" 89 | if [ $? -eq 0 ]; then 90 | echo "run complete!" 91 | else 92 | echo "run error!" 93 | fi 94 | else 95 | echo "compile error!" 96 | fi 97 | 98 | rm -f Generate.class 99 | 100 | 101 | echo "All has been done !" 102 | 103 | 104 | -------------------------------------------------------------------------------- /freemarker.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BestAndroider/AndroidProjectGenerateTool/2d068b4e5b392bb7f5363dbeef01fb656f462ad6/freemarker.jar -------------------------------------------------------------------------------- /marker/.gitignore.ftl: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches/build_file_checksums.ser 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | .DS_Store 9 | /build 10 | /captures 11 | .externalNativeBuild 12 | -------------------------------------------------------------------------------- /marker/.gitignore1.ftl: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /marker/AndroidManifest.xml.ftl: -------------------------------------------------------------------------------- 1 | 3 | 4 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /marker/ExampleInstrumentedTest.java.ftl: -------------------------------------------------------------------------------- 1 | package ${packageName}; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("${packageName}", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /marker/ExampleUnitTest.java.ftl: -------------------------------------------------------------------------------- 1 | package ${packageName}; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /marker/MainActivity.java.ftl: -------------------------------------------------------------------------------- 1 | package ${packageName}; 2 | 3 | import android.support.v7.app.AppCompatActivity; 4 | import android.os.Bundle; 5 | 6 | public class MainActivity extends AppCompatActivity { 7 | 8 | @Override 9 | protected void onCreate(Bundle savedInstanceState) { 10 | super.onCreate(savedInstanceState); 11 | setContentView(R.layout.activity_main); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /marker/build.gradle.ftl: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | google() 6 | jcenter() 7 | } 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:${gradlePluginVersion}' 10 | // NOTE: Do not place your application dependencies here; they belong 11 | // in the individual module build.gradle files 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | google() 18 | jcenter() 19 | } 20 | } 21 | 22 | task clean(type: Delete) { 23 | delete rootProject.buildDir 24 | } 25 | -------------------------------------------------------------------------------- /marker/build.gradle1.ftl: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 28 5 | defaultConfig { 6 | applicationId "${packageName}" 7 | minSdkVersion 15 8 | targetSdkVersion 28 9 | versionCode 1 10 | versionName "1.0" 11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | 20 | } 21 | 22 | dependencies { 23 | implementation fileTree(include: ['*.jar'], dir: 'libs') 24 | implementation 'com.android.support:appcompat-v7:28.0.0-alpha1' 25 | implementation 'com.android.support.constraint:constraint-layout:1.1.0' 26 | testImplementation 'junit:junit:4.12' 27 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 28 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 29 | } 30 | -------------------------------------------------------------------------------- /marker/globals.xml.ftl: -------------------------------------------------------------------------------- 1 | 2 | 3 | <#include "root://gradle-projects/common/globals.xml.ftl" /> 4 | 5 | 6 | 7 | 8 | 9 | <#include "root://activities/common/kotlin_globals.xml.ftl" /> 10 | 11 | -------------------------------------------------------------------------------- /marker/proguard-rules.pro.ftl: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 18 | 19 | -------------------------------------------------------------------------------- /res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BestAndroider/AndroidProjectGenerateTool/2d068b4e5b392bb7f5363dbeef01fb656f462ad6/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BestAndroider/AndroidProjectGenerateTool/2d068b4e5b392bb7f5363dbeef01fb656f462ad6/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BestAndroider/AndroidProjectGenerateTool/2d068b4e5b392bb7f5363dbeef01fb656f462ad6/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BestAndroider/AndroidProjectGenerateTool/2d068b4e5b392bb7f5363dbeef01fb656f462ad6/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BestAndroider/AndroidProjectGenerateTool/2d068b4e5b392bb7f5363dbeef01fb656f462ad6/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BestAndroider/AndroidProjectGenerateTool/2d068b4e5b392bb7f5363dbeef01fb656f462ad6/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BestAndroider/AndroidProjectGenerateTool/2d068b4e5b392bb7f5363dbeef01fb656f462ad6/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BestAndroider/AndroidProjectGenerateTool/2d068b4e5b392bb7f5363dbeef01fb656f462ad6/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BestAndroider/AndroidProjectGenerateTool/2d068b4e5b392bb7f5363dbeef01fb656f462ad6/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BestAndroider/AndroidProjectGenerateTool/2d068b4e5b392bb7f5363dbeef01fb656f462ad6/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #008577 4 | #00574B 5 | #D81B60 6 | 7 | -------------------------------------------------------------------------------- /res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | appName 3 | 4 | -------------------------------------------------------------------------------- /res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | --------------------------------------------------------------------------------