1+ package cn.hx.plugin.junkcode.task
2+
3+ import cn.hx.plugin.junkcode.ext.JunkCodeConfig
4+ import cn.hx.plugin.junkcode.template.ResTemplate
5+ import cn.hx.plugin.junkcode.utils.JunkUtil
6+ import com.squareup.javapoet.ClassName
7+ import com.squareup.javapoet.JavaFile
8+ import com.squareup.javapoet.MethodSpec
9+ import com.squareup.javapoet.TypeSpec
10+ import org.gradle.api.DefaultTask
11+ import org.gradle.api.file.DirectoryProperty
12+ import org.gradle.api.file.RegularFileProperty
13+ import org.gradle.api.tasks.*
14+
15+ import javax.lang.model.element.Modifier
16+ import java.nio.file.Files
17+ import java.nio.file.Path
18+
19+ abstract class GenerateJunkCodeTask extends DefaultTask {
20+
21+ @Nested
22+ abstract JunkCodeConfig config
23+
24+ @Input
25+ String namespace
26+
27+ @OutputDirectory
28+ abstract DirectoryProperty getJavaOutputFolder ()
29+
30+ @OutputDirectory
31+ abstract DirectoryProperty getResOutputFolder ()
32+
33+ @OutputFile
34+ abstract RegularFileProperty getManifestOutputFile ()
35+
36+ @Internal
37+ List<String > activityList = new ArrayList<> ()
38+
39+ @TaskAction
40+ void taskAction () {
41+ getJavaOutputFolder(). get(). asFile. deleteDir()
42+ getResOutputFolder(). get(). asFile. deleteDir()
43+ for (int i = 0 ; i < config. packageCount; i++ ) {
44+ String packageName
45+ if (config. packageBase. isEmpty()) {
46+ packageName = JunkUtil . generateName(i)
47+ } else {
48+ packageName = config. packageBase + " ." + JunkUtil . generateName(i)
49+ }
50+ generateActivity(packageName)
51+ generateOtherClass(packageName)
52+ }
53+ generateManifest()
54+ generateDrawable()
55+ generateStringsFile()
56+ generateKeep()
57+ }
58+
59+ private void generateActivity (String packageName ) {
60+ for (int i = 0 ; i < config. activityCountPerPackage; i++ ) {
61+ def activityPreName = JunkUtil . generateName(i)
62+ def className = activityPreName. capitalize() + " Activity"
63+ def layoutName = " ${ config.resPrefix.toLowerCase()}${ packageName.replace(".", "_")} _activity_${ activityPreName} "
64+ generateLayout(layoutName)
65+ if (! config. excludeActivityJavaFile) {
66+ def typeBuilder = TypeSpec . classBuilder(className)
67+ typeBuilder. superclass(ClassName . get(" android.app" , " Activity" ))
68+ typeBuilder. addModifiers(Modifier . PUBLIC )
69+ // onCreate方法
70+ def bundleClassName = ClassName . get(" android.os" , " Bundle" )
71+ typeBuilder. addMethod(MethodSpec . methodBuilder(" onCreate" )
72+ .addAnnotation(Override . class)
73+ .addModifiers(Modifier . PROTECTED )
74+ .addParameter(bundleClassName, " savedInstanceState" )
75+ .addStatement(" super.onCreate(savedInstanceState)" )
76+ .addStatement(" setContentView(\$ T.layout.${ layoutName} )" , ClassName . get(namespace, " R" ))
77+ .build())
78+ if (config. typeGenerator) {
79+ config. typeGenerator. execute(typeBuilder)
80+ } else {
81+ // 其它方法
82+ for (int j = 0 ; j < config. methodCountPerClass; j++ ) {
83+ def methodName = JunkUtil . generateName(j)
84+ def methodBuilder = MethodSpec . methodBuilder(methodName)
85+ if (config. methodGenerator) {
86+ config. methodGenerator. execute(methodBuilder)
87+ } else {
88+ JunkUtil . generateMethods(methodBuilder)
89+ }
90+ typeBuilder. addMethod(methodBuilder. build())
91+ }
92+ }
93+ def javaFile = JavaFile . builder(packageName, typeBuilder. build()). build()
94+ writeJavaFile(javaFile)
95+ activityList. add(packageName + " ." + className)
96+ }
97+ }
98+ }
99+
100+
101+ /**
102+ * 生成Manifest
103+ */
104+ private void generateManifest () {
105+ def manifestFile = getManifestOutputFile(). get(). asFile
106+ StringBuilder sb = new StringBuilder ()
107+ sb. append(" <manifest xmlns:android=\" http://schemas.android.com/apk/res/android\" >\n " )
108+ sb. append(" <application>\n " )
109+ for (i in 0 .. < activityList. size()) {
110+ sb. append(" <activity android:name=\" ${ activityList.get(i)} \" />\n " )
111+ }
112+ sb. append(" </application>\n " )
113+ sb. append(" </manifest>" )
114+ JunkUtil . writeStringToFile(manifestFile, sb. toString())
115+ }
116+
117+ private void generateOtherClass (String packageName ) {
118+ for (int j = 0 ; j < config. otherCountPerPackage; j++ ) {
119+ def className = JunkUtil . generateName(j). capitalize()
120+ def typeBuilder = TypeSpec . classBuilder(className)
121+ if (config. typeGenerator) {
122+ config. typeGenerator. execute(typeBuilder)
123+ } else {
124+ typeBuilder. addModifiers(Modifier . PUBLIC )
125+ for (int k = 0 ; k < config. methodCountPerClass; k++ ) {
126+ def methodName = JunkUtil . generateName(k)
127+ def methodBuilder = MethodSpec . methodBuilder(methodName)
128+ if (config. methodGenerator) {
129+ config. methodGenerator. execute(methodBuilder)
130+ } else {
131+ JunkUtil . generateMethods(methodBuilder)
132+ }
133+ typeBuilder. addMethod(methodBuilder. build())
134+ }
135+ }
136+ def javaFile = JavaFile . builder(packageName, typeBuilder. build()). build()
137+ writeJavaFile(javaFile)
138+ }
139+ }
140+
141+ /**
142+ * 生成layout
143+ * @param layoutName
144+ */
145+ private void generateLayout (String layoutName ) {
146+ def layoutFile = new File (getResOutputFolder(). get(). asFile, " layout/${ layoutName} .xml" )
147+ if (config. layoutGenerator) {
148+ def builder = new StringBuilder ()
149+ config. layoutGenerator. execute(builder)
150+ JunkUtil . writeStringToFile(layoutFile, builder. toString())
151+ } else {
152+ def layoutStr = String . format(ResTemplate . LAYOUT_TEMPLATE , JunkUtil . generateId())
153+ JunkUtil . writeStringToFile(layoutFile, layoutStr)
154+ }
155+ }
156+
157+
158+ /**
159+ * 生成drawable
160+ * @param drawableName
161+ */
162+ void generateDrawable () {
163+ for (int i = 0 ; i < config. drawableCount; i++ ) {
164+ def drawableName = " ${ config.resPrefix.toLowerCase()}${ JunkUtil.generateName(i)} "
165+ def drawableFile = new File (getResOutputFolder(). get(). asFile, " drawable/${ drawableName} .xml" )
166+ if (config. drawableGenerator) {
167+ def builder = new StringBuilder ()
168+ config. drawableGenerator. execute(builder)
169+ JunkUtil . writeStringToFile(drawableFile, builder. toString())
170+ } else {
171+ def drawableStr = String . format(ResTemplate . DRAWABLE , JunkUtil . generateColor())
172+ JunkUtil . writeStringToFile(drawableFile, drawableStr)
173+ }
174+ }
175+ }
176+
177+ /**
178+ * 生成strings.xml
179+ */
180+ void generateStringsFile () {
181+ List<String > stringList = new ArrayList<> ()
182+ for (int i = 0 ; i < config. stringCount; i++ ) {
183+ stringList. add(" ${ config.resPrefix.toLowerCase()}${ JunkUtil.generateName(i)} " )
184+ }
185+ def stringFile = new File (getResOutputFolder(). get(). asFile, " values/strings.xml" )
186+ StringBuilder sb = new StringBuilder ()
187+ sb. append(" <resources>\n " )
188+ for (i in 0 .. < stringList. size()) {
189+ sb. append(" <string name=\" ${ stringList.get(i)} \" >${ stringList.get(i)} </string>\n " )
190+ }
191+ sb. append(" </resources>\n " )
192+ JunkUtil . writeStringToFile(stringFile, sb. toString())
193+ }
194+
195+ private void generateKeep () {
196+ def keepFile = new File (getResOutputFolder(). get(). asFile, " raw/android_junk_code_keep.xml" )
197+ StringBuilder sb = new StringBuilder ()
198+ sb. append(" <resources xmlns:tools=\" http://schemas.android.com/tools\"\n " +
199+ " tools:keep=\" @layout/${ config.resPrefix} *, @drawable/${ config.resPrefix} *\" />\n " )
200+ JunkUtil . writeStringToFile(keepFile, sb. toString())
201+ }
202+
203+ private void writeJavaFile (JavaFile javaFile ) {
204+ def outputDirectory = new File (getJavaOutputFolder(). get(). asFile, " java" ). toPath()
205+ if (! javaFile. packageName. isEmpty()) {
206+ for (String packageComponent : javaFile. packageName. split(" \\ ." )) {
207+ outputDirectory = outputDirectory. resolve(packageComponent);
208+ }
209+ Files . createDirectories(outputDirectory);
210+ }
211+ Path outputPath = outputDirectory. resolve(javaFile. typeSpec. name + " .java" );
212+ JunkUtil . writeStringToFile(outputPath. toFile(), javaFile. toString())
213+ }
214+ }
0 commit comments