├── .gitignore ├── LICENSE ├── README.md ├── annotation ├── build.gradle ├── gradle.properties └── src │ └── main │ └── kotlin │ └── com │ └── github │ └── snowdream │ └── toybricks │ └── annotation │ ├── Implementation.kt │ ├── Interface.kt │ └── InterfaceLoader.kt ├── app ├── .gitignore ├── build.gradle ├── gradle.properties ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── github │ │ └── snowdream │ │ └── toybricks │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── github │ │ │ └── snowdream │ │ │ └── toybricks │ │ │ └── app │ │ │ ├── IText.java │ │ │ ├── MainActivity.java │ │ │ └── impl │ │ │ ├── NewTextGobalImpl.java │ │ │ ├── NewTextImpl.java │ │ │ └── TextImpl.java │ └── res │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── github │ └── snowdream │ └── toybricks │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle ├── plugins │ ├── .gitignore │ ├── LICENSE │ ├── android-bintray-push.gradle │ ├── android-library.gradle │ ├── android.gradle │ ├── build.gradle │ ├── gradle.properties │ ├── init.gradle │ ├── java-bintray-push.gradle │ ├── java-groovy-library.gradle │ ├── java-kotlin-library.gradle │ ├── maven-push.gradle │ └── util.gradle ├── proguard │ ├── proguard-android-all.txt │ ├── proguard-android-app-optimize.txt │ ├── proguard-android-app.txt │ ├── proguard-android-lib-optimize.txt │ ├── proguard-android-lib.txt │ ├── proguard-android-optimize.txt │ ├── proguard-android.txt │ └── proguard-project.txt └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── lib ├── .gitignore ├── build.gradle ├── gradle.properties ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── github │ │ └── snowdream │ │ └── toybricks │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── kotlin │ │ └── com │ │ │ └── github │ │ │ └── snowdream │ │ │ └── toybricks │ │ │ ├── ToyBricks.kt │ │ │ └── annotation │ │ │ └── impl │ │ │ └── DefaultInterfaceLoader.kt │ └── res │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── com │ └── github │ └── snowdream │ └── toybricks │ └── ExampleUnitTest.java ├── plugin ├── build.gradle ├── gradle.properties └── src │ └── main │ ├── groovy │ └── com │ │ └── github │ │ └── snowdream │ │ └── toybricks │ │ └── plugin │ │ ├── ToyBricksJsonEntity.groovy │ │ ├── ToybricksPlugin.groovy │ │ └── ToybricksTask.groovy │ └── resources │ └── META-INF │ └── gradle-plugins │ └── com.github.snowdream.toybricks.properties ├── processor ├── build.gradle ├── gradle.properties └── src │ └── main │ └── kotlin │ └── com │ └── github │ └── snowdream │ └── toybricks │ └── processor │ ├── BaseAnnotatedClass.kt │ ├── BaseContainerHandler.kt │ ├── Handler.kt │ ├── ImplementationAnnotatedClass.kt │ ├── InterfaceAnnotatedClass.kt │ ├── InterfaceImplementationHandler.kt │ ├── ProcessingException.kt │ ├── ProcessorManager.kt │ ├── ToyBricksJsonEntity.kt │ └── ToyBricksProcessor.kt └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/windows,linux,macos,git,intellij+iml,eclipse,vim,sublimetext,visualstudiocode,android,gradle,maven 3 | 4 | ### Vim ### 5 | # swap 6 | [._]*.s[a-w][a-z] 7 | [._]s[a-w][a-z] 8 | # session 9 | Session.vim 10 | # temporary 11 | .netrwhist 12 | *~ 13 | # auto-generated tag files 14 | tags 15 | 16 | 17 | ### Windows ### 18 | # Windows image file caches 19 | Thumbs.db 20 | ehthumbs.db 21 | 22 | # Folder config file 23 | Desktop.ini 24 | 25 | # Recycle Bin used on file shares 26 | $RECYCLE.BIN/ 27 | 28 | # Windows Installer files 29 | *.cab 30 | *.msi 31 | *.msm 32 | *.msp 33 | 34 | # Windows shortcuts 35 | *.lnk 36 | 37 | 38 | ### macOS ### 39 | *.DS_Store 40 | .AppleDouble 41 | .LSOverride 42 | 43 | # Icon must end with two \r 44 | Icon 45 | # Thumbnails 46 | ._* 47 | # Files that might appear in the root of a volume 48 | .DocumentRevisions-V100 49 | .fseventsd 50 | .Spotlight-V100 51 | .TemporaryItems 52 | .Trashes 53 | .VolumeIcon.icns 54 | .com.apple.timemachine.donotpresent 55 | # Directories potentially created on remote AFP share 56 | .AppleDB 57 | .AppleDesktop 58 | Network Trash Folder 59 | Temporary Items 60 | .apdisk 61 | 62 | 63 | ### Git ### 64 | *.orig 65 | 66 | 67 | ### Intellij+iml ### 68 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 69 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 70 | .idea 71 | 72 | ## File-based project format: 73 | *.iws 74 | 75 | ## Plugin-specific files: 76 | 77 | # IntelliJ 78 | /out/ 79 | 80 | # mpeltonen/sbt-idea plugin 81 | .idea_modules/ 82 | 83 | # JIRA plugin 84 | atlassian-ide-plugin.xml 85 | 86 | # Crashlytics plugin (for Android Studio and IntelliJ) 87 | com_crashlytics_export_strings.xml 88 | crashlytics.properties 89 | crashlytics-build.properties 90 | fabric.properties 91 | 92 | ### Intellij+iml Patch ### 93 | # Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 94 | 95 | *.iml 96 | modules.xml 97 | .idea/misc.xml 98 | *.ipr 99 | 100 | 101 | ### Eclipse ### 102 | 103 | .metadata 104 | bin/ 105 | tmp/ 106 | *.tmp 107 | *.bak 108 | *.swp 109 | *~.nib 110 | local.properties 111 | .settings/ 112 | .loadpath 113 | .recommenders 114 | 115 | # Eclipse Core 116 | .project 117 | 118 | # External tool builders 119 | .externalToolBuilders/ 120 | 121 | # Locally stored "Eclipse launch configurations" 122 | *.launch 123 | 124 | # PyDev specific (Python IDE for Eclipse) 125 | *.pydevproject 126 | 127 | # CDT-specific (C/C++ Development Tooling) 128 | .cproject 129 | 130 | # JDT-specific (Eclipse Java Development Tools) 131 | .classpath 132 | 133 | # Java annotation processor (APT) 134 | .factorypath 135 | 136 | # PDT-specific (PHP Development Tools) 137 | .buildpath 138 | 139 | # sbteclipse plugin 140 | .target 141 | 142 | # Tern plugin 143 | .tern-project 144 | 145 | # TeXlipse plugin 146 | .texlipse 147 | 148 | # STS (Spring Tool Suite) 149 | .springBeans 150 | 151 | # Code Recommenders 152 | .recommenders/ 153 | 154 | 155 | ### Linux ### 156 | 157 | # temporary files which can be created if a process still has a handle open of a deleted file 158 | .fuse_hidden* 159 | 160 | # KDE directory preferences 161 | .directory 162 | 163 | # Linux trash folder which might appear on any partition or disk 164 | .Trash-* 165 | 166 | # .nfs files are created when an open file is removed but is still being accessed 167 | .nfs* 168 | 169 | 170 | ### SublimeText ### 171 | # cache files for sublime text 172 | *.tmlanguage.cache 173 | *.tmPreferences.cache 174 | *.stTheme.cache 175 | 176 | # workspace files are user-specific 177 | *.sublime-workspace 178 | 179 | # project files should be checked into the repository, unless a significant 180 | # proportion of contributors will probably not be using SublimeText 181 | # *.sublime-project 182 | 183 | # sftp configuration file 184 | sftp-config.json 185 | 186 | # Package control specific files 187 | Package Control.last-run 188 | Package Control.ca-list 189 | Package Control.ca-bundle 190 | Package Control.system-ca-bundle 191 | Package Control.cache/ 192 | Package Control.ca-certs/ 193 | bh_unicode_properties.cache 194 | 195 | # Sublime-github package stores a github token in this file 196 | # https://packagecontrol.io/packages/sublime-github 197 | GitHub.sublime-settings 198 | 199 | 200 | ### VisualStudioCode ### 201 | .vscode/* 202 | !.vscode/settings.json 203 | !.vscode/tasks.json 204 | !.vscode/launch.json 205 | 206 | 207 | ### Android ### 208 | # Built application files 209 | *.apk 210 | *.ap_ 211 | 212 | # Files for the ART/Dalvik VM 213 | *.dex 214 | 215 | # Java class files 216 | *.class 217 | 218 | # Generated files 219 | gen/ 220 | out/ 221 | 222 | # Gradle files 223 | .gradle/ 224 | build/ 225 | 226 | # Local configuration file (sdk path, etc) 227 | 228 | # Proguard folder generated by Eclipse 229 | proguard/ 230 | 231 | # Log Files 232 | *.log 233 | 234 | # Android Studio Navigation editor temp files 235 | .navigation/ 236 | 237 | # Android Studio captures folder 238 | captures/ 239 | 240 | # Intellij 241 | 242 | # Keystore files 243 | *.jks 244 | 245 | # External native build folder generated in Android Studio 2.2 and later 246 | .externalNativeBuild 247 | 248 | ### Android Patch ### 249 | gen-external-apklibs 250 | 251 | 252 | ### Maven ### 253 | target/ 254 | pom.xml.tag 255 | pom.xml.releaseBackup 256 | pom.xml.versionsBackup 257 | pom.xml.next 258 | release.properties 259 | dependency-reduced-pom.xml 260 | buildNumber.properties 261 | .mvn/timing.properties 262 | 263 | 264 | ### Gradle ### 265 | .gradle 266 | /build/ 267 | 268 | # Ignore Gradle GUI config 269 | gradle-app.setting 270 | 271 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 272 | !gradle-wrapper.jar 273 | 274 | # Cache of project 275 | .gradletasknamecache 276 | 277 | # # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 278 | # gradle/wrapper/gradle-wrapper.properties -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, and 10 | distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by the copyright 13 | owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all other entities 16 | that control, are controlled by, or are under common control with that entity. 17 | For the purposes of this definition, "control" means (i) the power, direct or 18 | indirect, to cause the direction or management of such entity, whether by 19 | contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the 20 | outstanding shares, or (iii) beneficial ownership of such entity. 21 | 22 | "You" (or "Your") shall mean an individual or Legal Entity exercising 23 | permissions granted by this License. 24 | 25 | "Source" form shall mean the preferred form for making modifications, including 26 | but not limited to software source code, documentation source, and configuration 27 | files. 28 | 29 | "Object" form shall mean any form resulting from mechanical transformation or 30 | translation of a Source form, including but not limited to compiled object code, 31 | generated documentation, and conversions to other media types. 32 | 33 | "Work" shall mean the work of authorship, whether in Source or Object form, made 34 | available under the License, as indicated by a copyright notice that is included 35 | in or attached to the work (an example is provided in the Appendix below). 36 | 37 | "Derivative Works" shall mean any work, whether in Source or Object form, that 38 | is based on (or derived from) the Work and for which the editorial revisions, 39 | annotations, elaborations, or other modifications represent, as a whole, an 40 | original work of authorship. For the purposes of this License, Derivative Works 41 | shall not include works that remain separable from, or merely link (or bind by 42 | name) to the interfaces of, the Work and Derivative Works thereof. 43 | 44 | "Contribution" shall mean any work of authorship, including the original version 45 | of the Work and any modifications or additions to that Work or Derivative Works 46 | thereof, that is intentionally submitted to Licensor for inclusion in the Work 47 | by the copyright owner or by an individual or Legal Entity authorized to submit 48 | on behalf of the copyright owner. For the purposes of this definition, 49 | "submitted" means any form of electronic, verbal, or written communication sent 50 | to the Licensor or its representatives, including but not limited to 51 | communication on electronic mailing lists, source code control systems, and 52 | issue tracking systems that are managed by, or on behalf of, the Licensor for 53 | the purpose of discussing and improving the Work, but excluding communication 54 | that is conspicuously marked or otherwise designated in writing by the copyright 55 | owner as "Not a Contribution." 56 | 57 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf 58 | of whom a Contribution has been received by Licensor and subsequently 59 | incorporated within the Work. 60 | 61 | 2. Grant of Copyright License. 62 | 63 | Subject to the terms and conditions of this License, each Contributor hereby 64 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 65 | irrevocable copyright license to reproduce, prepare Derivative Works of, 66 | publicly display, publicly perform, sublicense, and distribute the Work and such 67 | Derivative Works in Source or Object form. 68 | 69 | 3. Grant of Patent License. 70 | 71 | Subject to the terms and conditions of this License, each Contributor hereby 72 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 73 | irrevocable (except as stated in this section) patent license to make, have 74 | made, use, offer to sell, sell, import, and otherwise transfer the Work, where 75 | such license applies only to those patent claims licensable by such Contributor 76 | that are necessarily infringed by their Contribution(s) alone or by combination 77 | of their Contribution(s) with the Work to which such Contribution(s) was 78 | submitted. If You institute patent litigation against any entity (including a 79 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a 80 | Contribution incorporated within the Work constitutes direct or contributory 81 | patent infringement, then any patent licenses granted to You under this License 82 | for that Work shall terminate as of the date such litigation is filed. 83 | 84 | 4. Redistribution. 85 | 86 | You may reproduce and distribute copies of the Work or Derivative Works thereof 87 | in any medium, with or without modifications, and in Source or Object form, 88 | provided that You meet the following conditions: 89 | 90 | You must give any other recipients of the Work or Derivative Works a copy of 91 | this License; and 92 | You must cause any modified files to carry prominent notices stating that You 93 | changed the files; and 94 | You must retain, in the Source form of any Derivative Works that You distribute, 95 | all copyright, patent, trademark, and attribution notices from the Source form 96 | of the Work, excluding those notices that do not pertain to any part of the 97 | Derivative Works; and 98 | If the Work includes a "NOTICE" text file as part of its distribution, then any 99 | Derivative Works that You distribute must include a readable copy of the 100 | attribution notices contained within such NOTICE file, excluding those notices 101 | that do not pertain to any part of the Derivative Works, in at least one of the 102 | following places: within a NOTICE text file distributed as part of the 103 | Derivative Works; within the Source form or documentation, if provided along 104 | with the Derivative Works; or, within a display generated by the Derivative 105 | Works, if and wherever such third-party notices normally appear. The contents of 106 | the NOTICE file are for informational purposes only and do not modify the 107 | License. You may add Your own attribution notices within Derivative Works that 108 | You distribute, alongside or as an addendum to the NOTICE text from the Work, 109 | provided that such additional attribution notices cannot be construed as 110 | modifying the License. 111 | You may add Your own copyright statement to Your modifications and may provide 112 | additional or different license terms and conditions for use, reproduction, or 113 | distribution of Your modifications, or for any such Derivative Works as a whole, 114 | provided Your use, reproduction, and distribution of the Work otherwise complies 115 | with the conditions stated in this License. 116 | 117 | 5. Submission of Contributions. 118 | 119 | Unless You explicitly state otherwise, any Contribution intentionally submitted 120 | for inclusion in the Work by You to the Licensor shall be under the terms and 121 | conditions of this License, without any additional terms or conditions. 122 | Notwithstanding the above, nothing herein shall supersede or modify the terms of 123 | any separate license agreement you may have executed with Licensor regarding 124 | such Contributions. 125 | 126 | 6. Trademarks. 127 | 128 | This License does not grant permission to use the trade names, trademarks, 129 | service marks, or product names of the Licensor, except as required for 130 | reasonable and customary use in describing the origin of the Work and 131 | reproducing the content of the NOTICE file. 132 | 133 | 7. Disclaimer of Warranty. 134 | 135 | Unless required by applicable law or agreed to in writing, Licensor provides the 136 | Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, 137 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, 138 | including, without limitation, any warranties or conditions of TITLE, 139 | NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are 140 | solely responsible for determining the appropriateness of using or 141 | redistributing the Work and assume any risks associated with Your exercise of 142 | permissions under this License. 143 | 144 | 8. Limitation of Liability. 145 | 146 | In no event and under no legal theory, whether in tort (including negligence), 147 | contract, or otherwise, unless required by applicable law (such as deliberate 148 | and grossly negligent acts) or agreed to in writing, shall any Contributor be 149 | liable to You for damages, including any direct, indirect, special, incidental, 150 | or consequential damages of any character arising as a result of this License or 151 | out of the use or inability to use the Work (including but not limited to 152 | damages for loss of goodwill, work stoppage, computer failure or malfunction, or 153 | any and all other commercial damages or losses), even if such Contributor has 154 | been advised of the possibility of such damages. 155 | 156 | 9. Accepting Warranty or Additional Liability. 157 | 158 | While redistributing the Work or Derivative Works thereof, You may choose to 159 | offer, and charge a fee for, acceptance of support, warranty, indemnity, or 160 | other liability obligations and/or rights consistent with this License. However, 161 | in accepting such obligations, You may act only on Your own behalf and on Your 162 | sole responsibility, not on behalf of any other Contributor, and only if You 163 | agree to indemnify, defend, and hold each Contributor harmless for any liability 164 | incurred by, or claims asserted against, such Contributor by reason of your 165 | accepting any such warranty or additional liability. 166 | 167 | END OF TERMS AND CONDITIONS 168 | 169 | APPENDIX: How to apply the Apache License to your work 170 | 171 | To apply the Apache License to your work, attach the following boilerplate 172 | notice, with the fields enclosed by brackets "[]" replaced with your own 173 | identifying information. (Don't include the brackets!) The text should be 174 | enclosed in the appropriate comment syntax for the file format. We also 175 | recommend that a file or class name and description of purpose be included on 176 | the same "printed page" as the copyright notice for easier identification within 177 | third-party archives. 178 | 179 | Copyright [yyyy] [name of copyright owner] 180 | 181 | Licensed under the Apache License, Version 2.0 (the "License"); 182 | you may not use this file except in compliance with the License. 183 | You may obtain a copy of the License at 184 | 185 | http://www.apache.org/licenses/LICENSE-2.0 186 | 187 | Unless required by applicable law or agreed to in writing, software 188 | distributed under the License is distributed on an "AS IS" BASIS, 189 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 190 | See the License for the specific language governing permissions and 191 | limitations under the License. 192 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ToyBricks 2 | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.snowdream/toybricks/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.snowdream/toybricks) 3 | [![GITHUB](https://img.shields.io/github/issues/badges/ToyBricks.svg)](https://github.com/SnowdreamFramework/ToyBricks/issues) 4 | [![LICENSE](https://img.shields.io/hexpm/l/plug.svg)](http://www.apache.org/licenses/LICENSE-2.0.html) 5 | 6 | ## 中文文档 7 | 1. [ToyBricks简介以及原理分析](https://mp.weixin.qq.com/s?__biz=MzIyNTczOTYwMA==&mid=2247483911&idx=1&sn=16a661bee016146fa7ee83f15a0ea615&chksm=e87a5438df0ddd2e847a742fca7c5e31538350a1585158ee72a31f83cf4dc549aff13080c5f7#rd) 8 | 1. [ToyBricks用户手册](https://mp.weixin.qq.com/s?__biz=MzIyNTczOTYwMA==&mid=2247483913&idx=1&sn=d1e2d807f08f653b3675dafe4bbcd56c&chksm=e87a5436df0ddd20e48141d504570d2895c2b546cbacb58a454c275295f5c408d0ebb04e68c7#rd) 9 | 10 | ## Introduction 11 | 12 | Android Library that provide simpler way to achieve modularity. 13 | 14 | ## Compile System requirements 15 | JDK 7+ 16 | 17 | ## Download 18 | For Java project add in build.gradle file: 19 | 20 | ```groovy 21 | dependencies { 22 | compile 'com.github.snowdream.toybricks:annotation:(latest version)' 23 | annotationProcessor 'com.github.snowdream.toybricks:processor:(latest version)' 24 | compile 'com.github.snowdream:toybricks:(latest version)' 25 | } 26 | ``` 27 | 28 | For Kotlin project add in build.gradle file: 29 | ```groovy 30 | kapt { 31 | generateStubs = true 32 | } 33 | 34 | dependencies { 35 | compile 'com.github.snowdream.toybricks:annotation:(latest version)' 36 | kapt 'com.github.snowdream.toybricks:processor:(latest version)' 37 | compile 'com.github.snowdream:toybricks:(latest version)' 38 | } 39 | ``` 40 | 41 | ## Advantage 42 | 1. Support for Java and Kotlin 43 | 1. APT: Compile-Time Annotation Processing with Java 44 | 1. No need to configure proguard yourself 45 | 1. Smart checking for @Interface and @Implementation 46 | 47 | ## Disadvantage 48 | 1. Singleton class for kotlin start with object is not supported. 49 | 50 | ## Usage 51 | For interface, annotate it with @Interface 52 | ```java 53 | @Interface 54 | public interface IText { 55 | 56 | String getText(); 57 | } 58 | ``` 59 | 60 | For default implementation, annotate it with @Implementation, and implements the defined Interface. 61 | ```java 62 | @Implementation(IText.class/*,singleton = true*/) 63 | public class NewTextImpl implements IText { 64 | @Override 65 | public String getText() { 66 | return "NewTextImpl Implementation from "+ getClass().getCanonicalName(); 67 | } 68 | } 69 | ``` 70 | 71 | For global implementation, annotate it with @Implementation, and implements the defined Interface. 72 | ```java 73 | @Implementation(value = IText.class,global = true/*,singleton = true*/) 74 | public class NewTextGobalImpl implements IText { 75 | @Override 76 | public String getText() { 77 | return "NewTextImpl Implementation from "+ getClass().getCanonicalName() ; 78 | } 79 | } 80 | ``` 81 | 82 | Now, You can get the implementation for the interface as follows: 83 | ```java 84 | IText text = ToyBricks.getImplementation(IText.class); 85 | ``` 86 | 87 | ## Attention 88 | 1. For one interface, You can have only one default implementation and only one global implementation at the same time. 89 | 1. For interface,it should be public. 90 | 1. For implementation, it should be public,but not be abstract. it should inherit from the interface, and provide an empty public constructor. 91 | 1. You can add `singleton = true` to define Singleton for java and kotlin 92 | 1. Global implementation has the higher priority than default implementation. so, if them exist at the same time ,the global implementation will be used. 93 | 94 | ## Suggestion 95 | 1. you should usually define the default implementation for one interface, not the global one. 96 | 1. when you want to realize a new implementation for the interface, you can define the new implementation as global. 97 | 1. when the global implementation is achieved and fully tested, delete the default implementation, and change the new global implementation to the default implementation. 98 | 99 | ## Contacts 100 | * Email:yanghui1986527#gmail.com 101 | * QQ Group: 529327615 102 | * WeChat Official Accounts: sn0wdr1am 103 | 104 | ![sn0wdr1am](https://static.dingtalk.com/media/lADOmAwFCs0BAs0BAg_258_258.jpg) 105 | 106 | ## License 107 | ``` 108 | Copyright (C) 2017 snowdream 109 | 110 | Licensed under the Apache License, Version 2.0 (the "License"); 111 | you may not use this file except in compliance with the License. 112 | You may obtain a copy of the License at 113 | 114 | http://www.apache.org/licenses/LICENSE-2.0 115 | 116 | Unless required by applicable law or agreed to in writing, software 117 | distributed under the License is distributed on an "AS IS" BASIS, 118 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 119 | See the License for the specific language governing permissions and 120 | limitations under the License. 121 | ``` 122 | -------------------------------------------------------------------------------- /annotation/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'eclipse' 2 | apply plugin: 'idea' 3 | apply from: "${rootDir}/gradle/plugins/java-kotlin-library.gradle" 4 | -------------------------------------------------------------------------------- /annotation/gradle.properties: -------------------------------------------------------------------------------- 1 | PACKAGE_NAME=com.github.snowdream.toybricks.annotation 2 | POM_GROUP_ID=com.github.snowdream.toybricks 3 | POM_ARTIFACT_ID=annotation 4 | POM_NAME=annotation 5 | POM_PACKAGING=jar 6 | -------------------------------------------------------------------------------- /annotation/src/main/kotlin/com/github/snowdream/toybricks/annotation/Implementation.kt: -------------------------------------------------------------------------------- 1 | package com.github.snowdream.toybricks.annotation 2 | 3 | 4 | import kotlin.reflect.KClass 5 | 6 | /** 7 | * Created by snowdream on 17/2/10. 8 | */ 9 | @Retention(AnnotationRetention.BINARY) 10 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FILE) 11 | annotation class Implementation(val value: KClass<*>, val global: Boolean = false, val singleton: Boolean = false) 12 | -------------------------------------------------------------------------------- /annotation/src/main/kotlin/com/github/snowdream/toybricks/annotation/Interface.kt: -------------------------------------------------------------------------------- 1 | package com.github.snowdream.toybricks.annotation 2 | 3 | /** 4 | * Created by snowdream on 17/2/11. 5 | */ 6 | @kotlin.annotation.Retention(AnnotationRetention.BINARY) 7 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FILE) 8 | annotation class Interface 9 | -------------------------------------------------------------------------------- /annotation/src/main/kotlin/com/github/snowdream/toybricks/annotation/InterfaceLoader.kt: -------------------------------------------------------------------------------- 1 | package com.github.snowdream.toybricks.annotation 2 | 3 | /** 4 | * Created by snowdream on 17/2/9. 5 | */ 6 | interface InterfaceLoader { 7 | 8 | /** 9 | * get Implementation for the interface. 10 | */ 11 | fun getImplementation(clazz: Class): T? 12 | } 13 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'eclipse' 2 | apply plugin: 'idea' 3 | apply from: "${rootDir}/gradle/plugins/android.gradle" 4 | 5 | kapt { 6 | generateStubs = true 7 | } 8 | 9 | dependencies { 10 | compile 'com.github.snowdream:annotation:0.7@aar' 11 | 12 | compile project(':lib') 13 | compile "com.github.snowdream.toybricks:annotation:0.9.10" 14 | 15 | //annotationProcessor project(':processor') 16 | // kapt "com.github.snowdream.toybricks:processor:0.9.10" 17 | annotationProcessor "com.github.snowdream.toybricks:processor:0.9.10" 18 | } 19 | 20 | apply plugin: 'com.github.snowdream.toybricks' -------------------------------------------------------------------------------- /app/gradle.properties: -------------------------------------------------------------------------------- 1 | PACKAGE_NAME=com.github.snowdream.toybricks.app 2 | VERSION_NAME=1.0 3 | VERSION_CODE=1 -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/snowdream/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/github/snowdream/toybricks/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.github.snowdream.toybricks; 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 | * Instrumentation 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() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.github.snowdream.toybricks", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/snowdream/toybricks/app/IText.java: -------------------------------------------------------------------------------- 1 | package com.github.snowdream.toybricks.app; 2 | 3 | import com.github.snowdream.toybricks.annotation.Interface; 4 | 5 | /** 6 | * Created by snowdream on 17/2/11. 7 | */ 8 | @Interface 9 | public interface IText { 10 | 11 | String getText(); 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/snowdream/toybricks/app/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.github.snowdream.toybricks.app; 2 | 3 | import android.support.v7.app.AppCompatActivity; 4 | import android.os.Bundle; 5 | import android.widget.TextView; 6 | import com.github.snowdream.toybricks.ToyBricks; 7 | 8 | public class MainActivity extends AppCompatActivity { 9 | 10 | @Override 11 | protected void onCreate(Bundle savedInstanceState) { 12 | super.onCreate(savedInstanceState); 13 | setContentView(R.layout.activity_main); 14 | 15 | IText text = ToyBricks.getImplementation(IText.class); 16 | 17 | StringBuilder builder = new StringBuilder(); 18 | builder.append(text.getText()); 19 | 20 | ((TextView)findViewById(R.id.text)).setText(builder.toString()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/snowdream/toybricks/app/impl/NewTextGobalImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.snowdream.toybricks.app.impl; 2 | 3 | import com.github.snowdream.toybricks.annotation.Implementation; 4 | import com.github.snowdream.toybricks.app.IText; 5 | 6 | /** 7 | * Created by snowdream on 17/2/11. 8 | */ 9 | @Implementation(value = IText.class,global = true,singleton = true) 10 | public class NewTextGobalImpl implements IText { 11 | @Override 12 | public String getText() { 13 | return "NewTextImpl Implementation from "+ getClass().getCanonicalName() ; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/snowdream/toybricks/app/impl/NewTextImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.snowdream.toybricks.app.impl; 2 | 3 | import com.github.snowdream.toybricks.annotation.Implementation; 4 | import com.github.snowdream.toybricks.app.IText; 5 | 6 | /** 7 | * Created by snowdream on 17/2/11. 8 | */ 9 | @Implementation(IText.class) 10 | public class NewTextImpl implements IText { 11 | @Override 12 | public String getText() { 13 | return "NewTextImpl Implementation from "+ getClass().getCanonicalName(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/github/snowdream/toybricks/app/impl/TextImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.snowdream.toybricks.app.impl; 2 | 3 | import com.github.snowdream.toybricks.app.IText; 4 | 5 | /** 6 | * Created by snowdream on 17/2/11. 7 | */ 8 | public class TextImpl implements IText { 9 | @Override 10 | public String getText() { 11 | return "Defalt Implementation from "+ getClass().getCanonicalName(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SnowdreamFramework/ToyBricks/4691bf6def006ef0bf191ec239058c7f53722de9/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SnowdreamFramework/ToyBricks/4691bf6def006ef0bf191ec239058c7f53722de9/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SnowdreamFramework/ToyBricks/4691bf6def006ef0bf191ec239058c7f53722de9/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SnowdreamFramework/ToyBricks/4691bf6def006ef0bf191ec239058c7f53722de9/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SnowdreamFramework/ToyBricks/4691bf6def006ef0bf191ec239058c7f53722de9/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | toybricks 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/test/java/com/github/snowdream/toybricks/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.github.snowdream.toybricks; 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() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.1.1' 3 | ext.dokka_version = '0.9.13' 4 | 5 | repositories { 6 | maven { url 'file:///' + System.getenv("ANDROID_HOME")+ '/extras/android/m2repository/'} 7 | maven { url 'file:///' + new File(System.getProperty('user.home'), '.m2/repository').absolutePath} 8 | maven { url 'http://maven.aliyun.com/nexus/content/groups/public' } 9 | jcenter { url "http://jcenter.bintray.com/"} 10 | maven { url "http://repo1.maven.org/maven2"} 11 | maven { url "https://jitpack.io" } 12 | maven { url "http://oss.sonatype.org/content/repositories/snapshots" } 13 | } 14 | 15 | dependencies { 16 | classpath 'com.android.tools.build:gradle:2.2.2' 17 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' //for bintray_push.gradle 18 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.1'//for bintray_push.gradle 19 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" //for kotlin 20 | classpath "org.jetbrains.dokka:dokka-android-gradle-plugin:${dokka_version}" //for kotlin android dokka 21 | classpath "org.jetbrains.dokka:dokka-gradle-plugin:${dokka_version}" //for kotlin java dokka 22 | 23 | classpath 'com.github.snowdream.toybricks:android-toybricks-gradle-plugin:0.9.10' 24 | // classpath files('plugin/build/libs/android-toybricks-gradle-plugin-0.9.10.jar') 25 | // classpath "com.github.snowdream.toybricks:annotation:0.9.10" 26 | // classpath 'com.squareup:javapoet:1.8.0' 27 | } 28 | 29 | } 30 | 31 | allprojects { 32 | 33 | repositories { 34 | maven { url 'file:///' + System.getenv("ANDROID_HOME")+ '/extras/android/m2repository/'} 35 | maven { url 'file:///' + new File(System.getProperty('user.home'), '.m2/repository').absolutePath} 36 | maven { url 'http://maven.aliyun.com/nexus/content/groups/public' } 37 | jcenter { url "http://jcenter.bintray.com/"} 38 | maven { url "http://repo1.maven.org/maven2"} 39 | maven { url "https://jitpack.io" } 40 | maven { url "http://oss.sonatype.org/content/repositories/snapshots" } 41 | } 42 | 43 | tasks.withType(JavaCompile) { 44 | options.encoding = "UTF-8" 45 | } 46 | 47 | tasks.withType(Javadoc) { 48 | options { 49 | locale = 'en_US' 50 | encoding = 'UTF-8' 51 | charSet = 'UTF-8' 52 | links("http://docs.oracle.com/javase/7/docs/api/") 53 | } 54 | } 55 | } 56 | 57 | 58 | task wrapper(type: Wrapper) { 59 | gradleVersion = '3.3' 60 | distributionUrl = "http://android-mirror.bugly.qq.com:8080/gradle/gradle-${gradleVersion}-bin.zip" 61 | } 62 | 63 | task clean(type: Delete) { 64 | delete rootProject.buildDir 65 | } 66 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | # from gradle.properties in project build dir. 21 | PACKAGE_NAME=com.github.snowdream 22 | VERSION_NAME=0.9.10 23 | VERSION_CODE=9 24 | MIN_SDK_VERSION=14 25 | TARGET_SDK_VERSION=25 26 | COMPILE_SDK_VERSION=25 27 | BUILD_TOOLS_VERSION=25.0.2 28 | 29 | 30 | POM_GROUP_ID=com.github.snowdream 31 | POM_ARTIFACT_ID=android 32 | POM_VERSION=0.9.10 33 | POM_NAME=SnowdreamFramework 34 | POM_PACKAGING=pom 35 | POM_DESCRIPTION=SnowdreamFramework 36 | POM_URL=https://github.com/SnowdreamFramework/ToyBricks 37 | POM_INCEPTION_YEAR=2017 38 | 39 | POM_SCM_URL=git@github.com:SnowdreamFramework/ToyBricks.git 40 | POM_SCM_CONNECTION=scm:git:git@github.com:SnowdreamFramework/ToyBricks.git 41 | POM_SCM_DEV_CONNECTION=scm:git:git@github.com:SnowdreamFramework/ToyBricks.git 42 | 43 | POM_LICENCE_NAME=The Apache Software License, Version 2.0 44 | POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt 45 | POM_LICENCE_DIST=repo 46 | POM_LICENCE_COMMENTS=A business-friendly OSS license 47 | 48 | POM_DEVELOPER_ID=snowdream 49 | POM_DEVELOPER_NAME=YangHui 50 | POM_DEVELOPER_EMAIL=yanghui1986527@gmail.com 51 | POM_DEVELOPER_URL=http://snowdream.github.io 52 | 53 | POM_ISSUE_MANAGEMENT_SYSTEM=Github 54 | POM_ISSUE_MANAGEMENT_URL=https://github.com/SnowdreamFramework/ToyBricks/issues -------------------------------------------------------------------------------- /gradle/plugins/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/windows,linux,macos,git,intellij+iml,eclipse,vim,sublimetext,visualstudiocode,android,gradle,maven 3 | 4 | ### Vim ### 5 | # swap 6 | [._]*.s[a-w][a-z] 7 | [._]s[a-w][a-z] 8 | # session 9 | Session.vim 10 | # temporary 11 | .netrwhist 12 | *~ 13 | # auto-generated tag files 14 | tags 15 | 16 | 17 | ### Windows ### 18 | # Windows image file caches 19 | Thumbs.db 20 | ehthumbs.db 21 | 22 | # Folder config file 23 | Desktop.ini 24 | 25 | # Recycle Bin used on file shares 26 | $RECYCLE.BIN/ 27 | 28 | # Windows Installer files 29 | *.cab 30 | *.msi 31 | *.msm 32 | *.msp 33 | 34 | # Windows shortcuts 35 | *.lnk 36 | 37 | 38 | ### macOS ### 39 | *.DS_Store 40 | .AppleDouble 41 | .LSOverride 42 | 43 | # Icon must end with two \r 44 | Icon 45 | # Thumbnails 46 | ._* 47 | # Files that might appear in the root of a volume 48 | .DocumentRevisions-V100 49 | .fseventsd 50 | .Spotlight-V100 51 | .TemporaryItems 52 | .Trashes 53 | .VolumeIcon.icns 54 | .com.apple.timemachine.donotpresent 55 | # Directories potentially created on remote AFP share 56 | .AppleDB 57 | .AppleDesktop 58 | Network Trash Folder 59 | Temporary Items 60 | .apdisk 61 | 62 | 63 | ### Git ### 64 | *.orig 65 | 66 | 67 | ### Intellij+iml ### 68 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 69 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 70 | .idea 71 | 72 | ## File-based project format: 73 | *.iws 74 | 75 | ## Plugin-specific files: 76 | 77 | # IntelliJ 78 | /out/ 79 | 80 | # mpeltonen/sbt-idea plugin 81 | .idea_modules/ 82 | 83 | # JIRA plugin 84 | atlassian-ide-plugin.xml 85 | 86 | # Crashlytics plugin (for Android Studio and IntelliJ) 87 | com_crashlytics_export_strings.xml 88 | crashlytics.properties 89 | crashlytics-build.properties 90 | fabric.properties 91 | 92 | ### Intellij+iml Patch ### 93 | # Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 94 | 95 | *.iml 96 | modules.xml 97 | .idea/misc.xml 98 | *.ipr 99 | 100 | 101 | ### Eclipse ### 102 | 103 | .metadata 104 | bin/ 105 | tmp/ 106 | *.tmp 107 | *.bak 108 | *.swp 109 | *~.nib 110 | local.properties 111 | .settings/ 112 | .loadpath 113 | .recommenders 114 | 115 | # Eclipse Core 116 | .project 117 | 118 | # External tool builders 119 | .externalToolBuilders/ 120 | 121 | # Locally stored "Eclipse launch configurations" 122 | *.launch 123 | 124 | # PyDev specific (Python IDE for Eclipse) 125 | *.pydevproject 126 | 127 | # CDT-specific (C/C++ Development Tooling) 128 | .cproject 129 | 130 | # JDT-specific (Eclipse Java Development Tools) 131 | .classpath 132 | 133 | # Java annotation processor (APT) 134 | .factorypath 135 | 136 | # PDT-specific (PHP Development Tools) 137 | .buildpath 138 | 139 | # sbteclipse plugin 140 | .target 141 | 142 | # Tern plugin 143 | .tern-project 144 | 145 | # TeXlipse plugin 146 | .texlipse 147 | 148 | # STS (Spring Tool Suite) 149 | .springBeans 150 | 151 | # Code Recommenders 152 | .recommenders/ 153 | 154 | 155 | ### Linux ### 156 | 157 | # temporary files which can be created if a process still has a handle open of a deleted file 158 | .fuse_hidden* 159 | 160 | # KDE directory preferences 161 | .directory 162 | 163 | # Linux trash folder which might appear on any partition or disk 164 | .Trash-* 165 | 166 | # .nfs files are created when an open file is removed but is still being accessed 167 | .nfs* 168 | 169 | 170 | ### SublimeText ### 171 | # cache files for sublime text 172 | *.tmlanguage.cache 173 | *.tmPreferences.cache 174 | *.stTheme.cache 175 | 176 | # workspace files are user-specific 177 | *.sublime-workspace 178 | 179 | # project files should be checked into the repository, unless a significant 180 | # proportion of contributors will probably not be using SublimeText 181 | # *.sublime-project 182 | 183 | # sftp configuration file 184 | sftp-config.json 185 | 186 | # Package control specific files 187 | Package Control.last-run 188 | Package Control.ca-list 189 | Package Control.ca-bundle 190 | Package Control.system-ca-bundle 191 | Package Control.cache/ 192 | Package Control.ca-certs/ 193 | bh_unicode_properties.cache 194 | 195 | # Sublime-github package stores a github token in this file 196 | # https://packagecontrol.io/packages/sublime-github 197 | GitHub.sublime-settings 198 | 199 | 200 | ### VisualStudioCode ### 201 | .vscode/* 202 | !.vscode/settings.json 203 | !.vscode/tasks.json 204 | !.vscode/launch.json 205 | 206 | 207 | ### Android ### 208 | # Built application files 209 | *.apk 210 | *.ap_ 211 | 212 | # Files for the ART/Dalvik VM 213 | *.dex 214 | 215 | # Java class files 216 | *.class 217 | 218 | # Generated files 219 | gen/ 220 | out/ 221 | 222 | # Gradle files 223 | .gradle/ 224 | build/ 225 | 226 | # Local configuration file (sdk path, etc) 227 | 228 | # Proguard folder generated by Eclipse 229 | proguard/ 230 | 231 | # Log Files 232 | *.log 233 | 234 | # Android Studio Navigation editor temp files 235 | .navigation/ 236 | 237 | # Android Studio captures folder 238 | captures/ 239 | 240 | # Intellij 241 | 242 | # Keystore files 243 | *.jks 244 | 245 | # External native build folder generated in Android Studio 2.2 and later 246 | .externalNativeBuild 247 | 248 | ### Android Patch ### 249 | gen-external-apklibs 250 | 251 | 252 | ### Maven ### 253 | target/ 254 | pom.xml.tag 255 | pom.xml.releaseBackup 256 | pom.xml.versionsBackup 257 | pom.xml.next 258 | release.properties 259 | dependency-reduced-pom.xml 260 | buildNumber.properties 261 | .mvn/timing.properties 262 | 263 | 264 | ### Gradle ### 265 | .gradle 266 | /build/ 267 | 268 | # Ignore Gradle GUI config 269 | gradle-app.setting 270 | 271 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 272 | !gradle-wrapper.jar 273 | 274 | # Cache of project 275 | .gradletasknamecache 276 | 277 | # # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 278 | # gradle/wrapper/gradle-wrapper.properties -------------------------------------------------------------------------------- /gradle/plugins/LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, and 10 | distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by the copyright 13 | owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all other entities 16 | that control, are controlled by, or are under common control with that entity. 17 | For the purposes of this definition, "control" means (i) the power, direct or 18 | indirect, to cause the direction or management of such entity, whether by 19 | contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the 20 | outstanding shares, or (iii) beneficial ownership of such entity. 21 | 22 | "You" (or "Your") shall mean an individual or Legal Entity exercising 23 | permissions granted by this License. 24 | 25 | "Source" form shall mean the preferred form for making modifications, including 26 | but not limited to software source code, documentation source, and configuration 27 | files. 28 | 29 | "Object" form shall mean any form resulting from mechanical transformation or 30 | translation of a Source form, including but not limited to compiled object code, 31 | generated documentation, and conversions to other media types. 32 | 33 | "Work" shall mean the work of authorship, whether in Source or Object form, made 34 | available under the License, as indicated by a copyright notice that is included 35 | in or attached to the work (an example is provided in the Appendix below). 36 | 37 | "Derivative Works" shall mean any work, whether in Source or Object form, that 38 | is based on (or derived from) the Work and for which the editorial revisions, 39 | annotations, elaborations, or other modifications represent, as a whole, an 40 | original work of authorship. For the purposes of this License, Derivative Works 41 | shall not include works that remain separable from, or merely link (or bind by 42 | name) to the interfaces of, the Work and Derivative Works thereof. 43 | 44 | "Contribution" shall mean any work of authorship, including the original version 45 | of the Work and any modifications or additions to that Work or Derivative Works 46 | thereof, that is intentionally submitted to Licensor for inclusion in the Work 47 | by the copyright owner or by an individual or Legal Entity authorized to submit 48 | on behalf of the copyright owner. For the purposes of this definition, 49 | "submitted" means any form of electronic, verbal, or written communication sent 50 | to the Licensor or its representatives, including but not limited to 51 | communication on electronic mailing lists, source code control systems, and 52 | issue tracking systems that are managed by, or on behalf of, the Licensor for 53 | the purpose of discussing and improving the Work, but excluding communication 54 | that is conspicuously marked or otherwise designated in writing by the copyright 55 | owner as "Not a Contribution." 56 | 57 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf 58 | of whom a Contribution has been received by Licensor and subsequently 59 | incorporated within the Work. 60 | 61 | 2. Grant of Copyright License. 62 | 63 | Subject to the terms and conditions of this License, each Contributor hereby 64 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 65 | irrevocable copyright license to reproduce, prepare Derivative Works of, 66 | publicly display, publicly perform, sublicense, and distribute the Work and such 67 | Derivative Works in Source or Object form. 68 | 69 | 3. Grant of Patent License. 70 | 71 | Subject to the terms and conditions of this License, each Contributor hereby 72 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 73 | irrevocable (except as stated in this section) patent license to make, have 74 | made, use, offer to sell, sell, import, and otherwise transfer the Work, where 75 | such license applies only to those patent claims licensable by such Contributor 76 | that are necessarily infringed by their Contribution(s) alone or by combination 77 | of their Contribution(s) with the Work to which such Contribution(s) was 78 | submitted. If You institute patent litigation against any entity (including a 79 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a 80 | Contribution incorporated within the Work constitutes direct or contributory 81 | patent infringement, then any patent licenses granted to You under this License 82 | for that Work shall terminate as of the date such litigation is filed. 83 | 84 | 4. Redistribution. 85 | 86 | You may reproduce and distribute copies of the Work or Derivative Works thereof 87 | in any medium, with or without modifications, and in Source or Object form, 88 | provided that You meet the following conditions: 89 | 90 | You must give any other recipients of the Work or Derivative Works a copy of 91 | this License; and 92 | You must cause any modified files to carry prominent notices stating that You 93 | changed the files; and 94 | You must retain, in the Source form of any Derivative Works that You distribute, 95 | all copyright, patent, trademark, and attribution notices from the Source form 96 | of the Work, excluding those notices that do not pertain to any part of the 97 | Derivative Works; and 98 | If the Work includes a "NOTICE" text file as part of its distribution, then any 99 | Derivative Works that You distribute must include a readable copy of the 100 | attribution notices contained within such NOTICE file, excluding those notices 101 | that do not pertain to any part of the Derivative Works, in at least one of the 102 | following places: within a NOTICE text file distributed as part of the 103 | Derivative Works; within the Source form or documentation, if provided along 104 | with the Derivative Works; or, within a display generated by the Derivative 105 | Works, if and wherever such third-party notices normally appear. The contents of 106 | the NOTICE file are for informational purposes only and do not modify the 107 | License. You may add Your own attribution notices within Derivative Works that 108 | You distribute, alongside or as an addendum to the NOTICE text from the Work, 109 | provided that such additional attribution notices cannot be construed as 110 | modifying the License. 111 | You may add Your own copyright statement to Your modifications and may provide 112 | additional or different license terms and conditions for use, reproduction, or 113 | distribution of Your modifications, or for any such Derivative Works as a whole, 114 | provided Your use, reproduction, and distribution of the Work otherwise complies 115 | with the conditions stated in this License. 116 | 117 | 5. Submission of Contributions. 118 | 119 | Unless You explicitly state otherwise, any Contribution intentionally submitted 120 | for inclusion in the Work by You to the Licensor shall be under the terms and 121 | conditions of this License, without any additional terms or conditions. 122 | Notwithstanding the above, nothing herein shall supersede or modify the terms of 123 | any separate license agreement you may have executed with Licensor regarding 124 | such Contributions. 125 | 126 | 6. Trademarks. 127 | 128 | This License does not grant permission to use the trade names, trademarks, 129 | service marks, or product names of the Licensor, except as required for 130 | reasonable and customary use in describing the origin of the Work and 131 | reproducing the content of the NOTICE file. 132 | 133 | 7. Disclaimer of Warranty. 134 | 135 | Unless required by applicable law or agreed to in writing, Licensor provides the 136 | Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, 137 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, 138 | including, without limitation, any warranties or conditions of TITLE, 139 | NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are 140 | solely responsible for determining the appropriateness of using or 141 | redistributing the Work and assume any risks associated with Your exercise of 142 | permissions under this License. 143 | 144 | 8. Limitation of Liability. 145 | 146 | In no event and under no legal theory, whether in tort (including negligence), 147 | contract, or otherwise, unless required by applicable law (such as deliberate 148 | and grossly negligent acts) or agreed to in writing, shall any Contributor be 149 | liable to You for damages, including any direct, indirect, special, incidental, 150 | or consequential damages of any character arising as a result of this License or 151 | out of the use or inability to use the Work (including but not limited to 152 | damages for loss of goodwill, work stoppage, computer failure or malfunction, or 153 | any and all other commercial damages or losses), even if such Contributor has 154 | been advised of the possibility of such damages. 155 | 156 | 9. Accepting Warranty or Additional Liability. 157 | 158 | While redistributing the Work or Derivative Works thereof, You may choose to 159 | offer, and charge a fee for, acceptance of support, warranty, indemnity, or 160 | other liability obligations and/or rights consistent with this License. However, 161 | in accepting such obligations, You may act only on Your own behalf and on Your 162 | sole responsibility, not on behalf of any other Contributor, and only if You 163 | agree to indemnify, defend, and hold each Contributor harmless for any liability 164 | incurred by, or claims asserted against, such Contributor by reason of your 165 | accepting any such warranty or additional liability. 166 | 167 | END OF TERMS AND CONDITIONS 168 | 169 | APPENDIX: How to apply the Apache License to your work 170 | 171 | To apply the Apache License to your work, attach the following boilerplate 172 | notice, with the fields enclosed by brackets "[]" replaced with your own 173 | identifying information. (Don't include the brackets!) The text should be 174 | enclosed in the appropriate comment syntax for the file format. We also 175 | recommend that a file or class name and description of purpose be included on 176 | the same "printed page" as the copyright notice for easier identification within 177 | third-party archives. 178 | 179 | Copyright [yyyy] [name of copyright owner] 180 | 181 | Licensed under the Apache License, Version 2.0 (the "License"); 182 | you may not use this file except in compliance with the License. 183 | You may obtain a copy of the License at 184 | 185 | http://www.apache.org/licenses/LICENSE-2.0 186 | 187 | Unless required by applicable law or agreed to in writing, software 188 | distributed under the License is distributed on an "AS IS" BASIS, 189 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 190 | See the License for the specific language governing permissions and 191 | limitations under the License. 192 | -------------------------------------------------------------------------------- /gradle/plugins/android-bintray-push.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.github.dcendents.android-maven' 2 | apply plugin: 'com.jfrog.bintray' 3 | apply plugin: 'org.jetbrains.dokka-android' 4 | apply from: "${rootDir}/gradle/plugins/util.gradle" 5 | 6 | group = optProperty("POM_GROUP_ID") 7 | archivesBaseName = optProperty("POM_NAME") 8 | version = optProperty("POM_VERSION") 9 | 10 | configurations { 11 | archives { 12 | extendsFrom configurations.default 13 | } 14 | } 15 | 16 | install { 17 | repositories.mavenInstaller { 18 | configurePOM(pom) 19 | } 20 | } 21 | 22 | bintray { 23 | user = optProperty("BINTRAY_USER") 24 | key = optProperty("BINTRAY_API_KEY") 25 | configurations = ['archives'] 26 | dryRun = false //Whether to run this as dry-run, without deploying 27 | publish = true //If version should be auto published after an upload 28 | //Package configuration. The plugin will use the repo and name properties to check if the package already exists. In that case, there's no need to configure the other package properties (like userOrg, desc, etc). 29 | 30 | pkg { 31 | repo = "maven" 32 | name = "SnowdreamFramework" //optProperty("POM_GROUP_ID") +":"+ optProperty("POM_ARTIFACT_ID") 33 | userOrg = optProperty("BINTRAY_USER") 34 | websiteUrl = optProperty("POM_URL") 35 | issueTrackerUrl = optProperty("POM_ISSUE_MANAGEMENT_URL") 36 | vcsUrl = optProperty("POM_SCM_URL") 37 | licenses = ['Apache-2.0'] 38 | labels = [] 39 | version { 40 | name = optProperty("POM_VERSION") 41 | desc = optProperty("POM_DESCRIPTION") 42 | vcsTag = optProperty("POM_VERSION") 43 | publicDownloadNumbers = true 44 | //attributes = ['gradle-plugin': 'com.use.less:com.use.less.gradle:gradle-useless-plugin'] 45 | //Optional configuration for GPG signing 46 | gpg { 47 | sign = true //Determines whether to GPG sign the files. The default is false 48 | passphrase = optProperty("signing.password") //Optional. The passphrase for GPG signing' 49 | } 50 | //Optional configuration for Maven Central sync of the version 51 | mavenCentralSync { 52 | sync = true //Optional (true by default). Determines whether to sync the version to Maven Central. 53 | user = optProperty("MAVEN_DEPLOY_USERNAME") //OSS user token 54 | password = optProperty("MAVEN_DEPLOY_PASSWORD") //OSS user password 55 | close = '1' //Optional property. By default the staging repository is closed and artifacts are released to Maven Central. You can optionally turn this behaviour off (by puting 0 as value) and release the version manually. 56 | } 57 | } 58 | } 59 | } 60 | 61 | task androidReleaseJar(type: Jar,dependsOn: "assembleRelease") { 62 | from "$buildDir/intermediates/classes/release/" 63 | from "$buildDir/generated/source/kapt/release/ToyBricks.json" 64 | from "$buildDir/generated/source/apt/release/ToyBricks.json" 65 | exclude '**/BuildConfig.class' 66 | exclude '**/R.class' 67 | exclude '**/R$*.class' 68 | includeEmptyDirs false 69 | } 70 | 71 | task androidJavadocsJar(type: Jar) { 72 | classifier = 'javadoc' 73 | from "generateReleaseJavadoc.destinationDir" 74 | includeEmptyDirs false 75 | } 76 | 77 | task androidSourcesJar(type: Jar) { 78 | classifier = 'sources' 79 | from android.sourceSets.main.java.srcDirs 80 | from "$buildDir/generated/source/kapt/release/ToyBricks.json" 81 | from "$buildDir/generated/source/apt/release/ToyBricks.json" 82 | includeEmptyDirs false 83 | } 84 | 85 | task kotlinjavadocJar(type: Jar, dependsOn: dokka) { 86 | classifier 'javadoc' 87 | from "$buildDir/javadoc" 88 | } 89 | 90 | artifacts { 91 | archives androidReleaseJar 92 | archives androidSourcesJar 93 | archives androidJavadocsJar 94 | archives kotlinjavadocJar 95 | } 96 | 97 | private configurePOM(def pom) { 98 | pom.project { 99 | groupId optProperty("POM_GROUP_ID") 100 | artifactId optProperty("POM_ARTIFACT_ID") 101 | version optProperty("POM_VERSION") 102 | name optProperty("POM_NAME") 103 | packaging optProperty("POM_PACKAGING") 104 | description optProperty("POM_DESCRIPTION") 105 | url optProperty("POM_URL") 106 | inceptionYear optProperty("POM_INCEPTION_YEAR") 107 | 108 | scm { 109 | url optProperty("POM_SCM_URL") 110 | connection optProperty("POM_SCM_CONNECTION") 111 | developerConnection optProperty("POM_SCM_DEV_CONNECTION") 112 | } 113 | 114 | licenses { 115 | license { 116 | name optProperty("POM_LICENCE_NAME") 117 | url optProperty("POM_LICENCE_URL") 118 | distribution optProperty("POM_LICENCE_DIST") 119 | comments optProperty("POM_LICENCE_COMMENTS") 120 | } 121 | } 122 | 123 | developers { 124 | developer { 125 | id optProperty("POM_DEVELOPER_ID") 126 | name optProperty("POM_DEVELOPER_NAME") 127 | email optProperty("POM_DEVELOPER_EMAIL") 128 | url optProperty("POM_DEVELOPER_URL") 129 | } 130 | } 131 | 132 | issueManagement { 133 | system optProperty("POM_ISSUE_MANAGEMENT_SYSTEM") 134 | url optProperty("POM_ISSUE_MANAGEMENT_URL") 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /gradle/plugins/android-library.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply from: "${rootDir}/gradle/plugins/util.gradle" 3 | apply plugin: 'kotlin-android' 4 | apply plugin: 'kotlin-android-extensions' 5 | apply plugin: 'org.jetbrains.dokka-android' 6 | 7 | dependencies { 8 | compile fileTree(dir: 'libs', include: '*.jar') 9 | 10 | if (optProperty("POM_PACKAGING") == 'aar') { 11 | compile 'com.android.support:appcompat-v7:25.1.1' 12 | compile 'com.android.support:design:25.1.1' 13 | compile 'com.android.support:support-annotations:25.1.1' 14 | compile 'com.android.support:multidex:1.0.1' 15 | 16 | compile 'com.github.snowdream:annotation:0.7@aar' 17 | 18 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 19 | exclude group: 'com.android.support', module: 'support-annotations' 20 | }) 21 | } 22 | 23 | compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 24 | 25 | testCompile 'junit:junit:4.12' 26 | 27 | } 28 | 29 | android { 30 | compileSdkVersion Integer.parseInt(optProperty("COMPILE_SDK_VERSION")) 31 | buildToolsVersion optProperty("BUILD_TOOLS_VERSION") 32 | 33 | defaultConfig { 34 | versionCode Integer.parseInt(optProperty("VERSION_CODE")) 35 | versionName optProperty("VERSION_NAME") 36 | minSdkVersion Integer.parseInt(optProperty("MIN_SDK_VERSION")) 37 | targetSdkVersion Integer.parseInt(optProperty("TARGET_SDK_VERSION")) 38 | 39 | testApplicationId optProperty("PACKAGE_NAME") + ".test" 40 | testInstrumentationRunner "android.test.InstrumentationTestRunner" 41 | testHandleProfiling true 42 | testFunctionalTest true 43 | } 44 | 45 | compileOptions { 46 | sourceCompatibility JavaVersion.VERSION_1_7 47 | targetCompatibility JavaVersion.VERSION_1_7 48 | } 49 | 50 | signingConfigs { 51 | release { 52 | if (containsProperty("KEYSTORE")) { 53 | storeFile file(optProperty("KEYSTORE")) 54 | storePassword optProperty("KEYSTORE_PASSWORD") 55 | keyAlias optProperty("KEY_ALIAS") 56 | keyPassword optProperty("KEY_PASSWORD") 57 | } 58 | } 59 | } 60 | 61 | buildTypes { 62 | release { 63 | minifyEnabled false 64 | //shrinkResources true 65 | //proguardFile getDefaultProguardFile('proguard-android.txt') 66 | consumerProguardFiles 'proguard-rules.pro' 67 | signingConfig signingConfigs.release 68 | } 69 | } 70 | 71 | sourceSets { 72 | main.java.srcDirs += 'src/main/kotlin' 73 | test.java.srcDirs += 'src/test/kotlin' 74 | } 75 | 76 | packagingOptions { 77 | exclude 'META-INF/DEPENDENCIES' 78 | exclude 'META-INF/NOTICE' 79 | exclude 'META-INF/LICENSE' 80 | exclude 'META-INF/LICENSE.txt' 81 | exclude 'META-INF/NOTICE.txt' 82 | } 83 | 84 | lintOptions { 85 | abortOnError false 86 | } 87 | } 88 | 89 | android.libraryVariants.all { variant -> 90 | task("generate${variant.name}Javadoc", type: Javadoc) { 91 | title = "android lib - " + optProperty("PROJECT_NAME", project.name) + " v" + optProperty("VERSION_NAME") + " API" 92 | description "Generates Javadoc for $variant.name." 93 | source = variant.javaCompile.source 94 | ext.androidJar = 95 | optProperty("ANDROID_HOME") + "/platforms/android-" + optProperty("COMPILE_SDK_VERSION") + "/android.jar" 96 | classpath = files(variant.javaCompile.classpath.files) + files(ext.androidJar) 97 | options { 98 | locale = 'en_US' 99 | encoding = 'UTF-8' 100 | charSet = 'UTF-8' 101 | links("http://docs.oracle.com/javase/7/docs/api/"); 102 | linksOffline("http://d.android.com/reference", optProperty("ANDROID_HOME") + "/docs/reference"); 103 | } 104 | exclude '**/BuildConfig.java' 105 | exclude '**/R.java' 106 | } 107 | } 108 | 109 | dokka { 110 | moduleName = 'util' 111 | outputFormat = 'javadoc' 112 | outputDirectory = "$buildDir/javadoc" 113 | processConfigurations = ['compile', 'extra'] 114 | includes = ['packages.md', 'extra.md'] 115 | samples = ['samples/basic.kt', 'samples/advanced.kt'] 116 | linkMapping { 117 | dir = "src/main/kotlin" 118 | url = "https://github.com/snowdream/" 119 | suffix = "#L" 120 | } 121 | sourceDirs = files('src/main/kotlin') 122 | } 123 | -------------------------------------------------------------------------------- /gradle/plugins/android.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply from: "${rootDir}/gradle/plugins/util.gradle" 3 | apply plugin: 'kotlin-android' 4 | apply plugin: 'kotlin-android-extensions' 5 | 6 | dependencies { 7 | compile fileTree(dir: 'libs', include: '*.jar') 8 | compile 'com.android.support:appcompat-v7:25.1.1' 9 | compile 'com.android.support:design:25.1.1' 10 | compile 'com.android.support:support-annotations:25.1.1' 11 | compile 'com.android.support:multidex:1.0.1' 12 | compile 'com.github.snowdream:annotation:0.7@aar' 13 | 14 | compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 15 | 16 | testCompile 'junit:junit:4.12' 17 | 18 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 19 | exclude group: 'com.android.support', module: 'support-annotations' 20 | }) 21 | } 22 | 23 | android { 24 | compileSdkVersion Integer.parseInt(optProperty("COMPILE_SDK_VERSION")) 25 | buildToolsVersion optProperty("BUILD_TOOLS_VERSION") 26 | 27 | defaultConfig { 28 | versionCode Integer.parseInt(optProperty("VERSION_CODE")) 29 | versionName optProperty("VERSION_NAME") 30 | minSdkVersion Integer.parseInt(optProperty("MIN_SDK_VERSION")) 31 | targetSdkVersion Integer.parseInt(optProperty("TARGET_SDK_VERSION")) 32 | applicationId optProperty("PACKAGE_NAME") 33 | 34 | testApplicationId optProperty("PACKAGE_NAME")+".test" 35 | testInstrumentationRunner "android.test.InstrumentationTestRunner" 36 | testHandleProfiling true 37 | testFunctionalTest true 38 | } 39 | 40 | compileOptions { 41 | sourceCompatibility JavaVersion.VERSION_1_7 42 | targetCompatibility JavaVersion.VERSION_1_7 43 | } 44 | 45 | signingConfigs { 46 | release { 47 | if (containsProperty("KEYSTORE")) { 48 | storeFile file(optProperty("KEYSTORE")) 49 | storePassword optProperty("KEYSTORE_PASSWORD") 50 | keyAlias optProperty("KEY_ALIAS") 51 | keyPassword optProperty("KEY_PASSWORD") 52 | } 53 | } 54 | } 55 | 56 | buildTypes { 57 | release { 58 | minifyEnabled true 59 | shrinkResources true 60 | proguardFiles "${rootDir}/gradle/proguard/proguard-android-app-optimize.txt", 'proguard-rules.pro' 61 | signingConfig signingConfigs.release 62 | } 63 | } 64 | sourceSets { 65 | main.java.srcDirs += 'src/main/kotlin' 66 | test.java.srcDirs += 'src/test/kotlin' 67 | } 68 | 69 | packagingOptions { 70 | exclude 'META-INF/DEPENDENCIES' 71 | exclude 'META-INF/NOTICE' 72 | exclude 'META-INF/LICENSE' 73 | exclude 'META-INF/LICENSE.txt' 74 | exclude 'META-INF/NOTICE.txt' 75 | } 76 | 77 | lintOptions { 78 | abortOnError false 79 | } 80 | } 81 | 82 | android.applicationVariants.all { variant -> 83 | def apk = variant.outputs[0].outputFile; 84 | def newName = ""; 85 | 86 | newName = apk.name.replace(project.name, optProperty("PROJECT_NAME", project.name) + "-v" + android.defaultConfig.versionName); 87 | newName = newName.replace("-" + variant.buildType.name, ""); 88 | newName = newName.replace(".apk", "-" + variant.buildType.name.toLowerCase() + ".apk"); 89 | 90 | variant.outputs[0].outputFile = new File(apk.parentFile, newName); 91 | if (variant.outputs[0].zipAlign) { 92 | variant.outputs[0].zipAlign.outputFile = new File(apk.parentFile, newName.replace("-unaligned", "")); 93 | } 94 | } 95 | 96 | android.applicationVariants.all { variant -> 97 | 98 | task("generate${variant.name}Javadoc", type: Javadoc) { 99 | title = "android lib - "+ optProperty("PROJECT_NAME", project.name)+" v"+optProperty("VERSION_NAME")+" API" 100 | description "Generates Javadoc for $variant.name." 101 | source = variant.javaCompile.source 102 | ext.androidJar = 103 | optProperty("ANDROID_HOME")+"/platforms/android-"+ optProperty("COMPILE_SDK_VERSION")+"/android.jar" 104 | classpath = files(variant.javaCompile.classpath.files) + files(ext.androidJar) 105 | options { 106 | locale = 'en_US' 107 | encoding = 'UTF-8' 108 | charSet = 'UTF-8' 109 | links("http://docs.oracle.com/javase/7/docs/api/"); 110 | linksOffline("http://d.android.com/reference", optProperty("ANDROID_HOME")+"/docs/reference"); 111 | } 112 | exclude '**/BuildConfig.java' 113 | exclude '**/R.java' 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /gradle/plugins/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | maven { url 'file:///' + System.getenv("ANDROID_HOME")+ '/extras/android/m2repository/'} 4 | maven { url 'file:///' + new File(System.getProperty('user.home'), '.m2/repository').absolutePath} 5 | maven { url 'http://maven.aliyun.com/nexus/content/groups/public' } 6 | jcenter { url "http://jcenter.bintray.com/"} 7 | maven { url "http://repo1.maven.org/maven2"} 8 | maven { url "https://jitpack.io" } 9 | maven { url "http://oss.sonatype.org/content/repositories/snapshots" } 10 | } 11 | 12 | dependencies { 13 | classpath 'com.android.tools.build:gradle:2.2.2' 14 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' //for bintray_push.gradle 15 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.1'//for bintray_push.gradle 16 | } 17 | } 18 | 19 | allprojects { 20 | 21 | repositories { 22 | maven { url 'file:///' + System.getenv("ANDROID_HOME")+ '/extras/android/m2repository/'} 23 | maven { url 'file:///' + new File(System.getProperty('user.home'), '.m2/repository').absolutePath} 24 | maven { url 'http://maven.aliyun.com/nexus/content/groups/public' } 25 | jcenter { url "http://jcenter.bintray.com/"} 26 | maven { url "http://repo1.maven.org/maven2"} 27 | maven { url "https://jitpack.io" } 28 | maven { url "http://oss.sonatype.org/content/repositories/snapshots" } 29 | } 30 | 31 | tasks.withType(JavaCompile) { 32 | options.encoding = "UTF-8" 33 | } 34 | } 35 | 36 | 37 | task wrapper(type: Wrapper) { 38 | gradleVersion = '3.1' 39 | distributionUrl = "http://android-mirror.bugly.qq.com:8080/gradle/gradle-${gradleVersion}-bin.zip" 40 | } 41 | -------------------------------------------------------------------------------- /gradle/plugins/gradle.properties: -------------------------------------------------------------------------------- 1 | # from gradle.properties in project build dir. 2 | PROJECT_NAME=SnowdreamFramework 3 | PACKAGE_NAME=com.github.snowdream.android 4 | VERSION_NAME=0.1 5 | VERSION_CODE=1 6 | MIN_SDK_VERSION=9 7 | TARGET_SDK_VERSION=23 8 | COMPILE_SDK_VERSION=23 9 | BUILD_TOOLS_VERSION=23.0.2 10 | 11 | POM_GROUP_ID=com.github.snowdream 12 | POM_ARTIFACT_ID=android 13 | POM_VERSION=0.1 14 | POM_NAME=SnowdreamFramework 15 | POM_PACKAGING=pom 16 | POM_DESCRIPTION=SnowdreamFramework 17 | POM_URL=https://github.com/snowdream/SnowdreamFramework 18 | POM_INCEPTION_YEAR=2016 19 | 20 | POM_SCM_URL=git@github.com:snowdream/SnowdreamFramework.git 21 | POM_SCM_CONNECTION=scm:git:git@github.com:snowdream/SnowdreamFramework.git 22 | POM_SCM_DEV_CONNECTION=scm:git:git@github.com:snowdream/SnowdreamFramework.git 23 | 24 | POM_LICENCE_NAME=The Apache Software License, Version 2.0 25 | POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt 26 | POM_LICENCE_DIST=repo 27 | POM_LICENCE_COMMENTS=A business-friendly OSS license 28 | 29 | POM_DEVELOPER_ID=snowdream 30 | POM_DEVELOPER_NAME=YangHui 31 | POM_DEVELOPER_EMAIL=yanghui1986527@gmail.com 32 | POM_DEVELOPER_URL=http://snowdream.github.io 33 | 34 | POM_ISSUE_MANAGEMENT_SYSTEM=Github 35 | POM_ISSUE_MANAGEMENT_URL=https://github.com/snowdream/SnowdreamFramework/issues 36 | 37 | 38 | # gradle.properties in gradle user home. 39 | KEYSTORE=/home/snowdream/.snowdream/snowdream.keystore 40 | KEYSTORE_PASSWORD=12345678 41 | KEY_ALIAS=snowdream 42 | KEY_PASSWORD=12345678 43 | 44 | MAVEN_DEPLOY_URL=https://oss.sonatype.org/service/local/staging/deploy/maven2/ 45 | MAVEN_DEPLOY_SNAPSHOT_URL=https://oss.sonatype.org/content/repositories/snapshots/ 46 | MAVEN_DEPLOY_USERNAME=snowdream 47 | MAVEN_DEPLOY_PASSWORD=12345678 48 | 49 | BINTRAY_USER=snowdream 50 | BINTRAY_API_KEY=12345678 51 | 52 | signing.keyId=YYYYYYYY 53 | signing.password=12345678 54 | signing.secretKeyRingFile=/home/snowdream/.gnupg/secring.gpg 55 | -------------------------------------------------------------------------------- /gradle/plugins/init.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | from: https://docs.gradle.org/current/userguide/init_scripts.html 3 | 4 | 43.2. Using an init script 5 | There are several ways to use an init script: 6 | 7 | 1. Specify a file on the command line. The command line option is -I or --init-script followed by the path to the script. 8 | The command line option can appear more than once, each time adding another init script. 9 | 2. Put a file called init.gradle in the USER_HOME/.gradle/ directory. 10 | 3. Put a file that ends with .gradle in the USER_HOME/.gradle/init.d/ directory. 11 | 4. Put a file that ends with .gradle in the GRADLE_HOME/init.d/ directory, in the Gradle distribution. 12 | This allows you to package up a custom Gradle distribution containing some custom build logic and plugins. 13 | You can combine this with the Gradle wrapper as a way to make custom logic available to all builds in your enterprise. 14 | 15 | If more than one init script is found they will all be executed, in the order specified above. 16 | Scripts in a given directory are executed in alphabetical order. 17 | This allows, for example, a tool to specify an init script on the command line and the user to put one in their home directory for defining the environment 18 | and both scripts will run when Gradle is executed. 19 | */ 20 | 21 | allprojects{ 22 | repositories { 23 | all { ArtifactRepository repo -> 24 | if(repo instanceof MavenArtifactRepository){ 25 | def url = repo.url.toString() 26 | if (url.startsWith('https://repo1.maven.org/maven2') || url.startsWith('https://jcenter.bintray.com/')) { 27 | remove repo 28 | } 29 | } 30 | } 31 | 32 | maven { url 'file:///' + System.getenv("ANDROID_HOME")+ '/extras/android/m2repository/'} 33 | maven { url 'file:///' + new File(System.getProperty('user.home'), '.m2/repository').absolutePath} 34 | maven { url 'http://maven.aliyun.com/mvn/repository/' } 35 | jcenter { url "http://jcenter.bintray.com/"} 36 | maven { url "http://repo1.maven.org/maven2"} 37 | maven { url "https://jitpack.io" } 38 | maven { url "http://oss.sonatype.org/content/repositories/snapshots" } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /gradle/plugins/java-bintray-push.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'maven' 2 | apply plugin: 'com.jfrog.bintray' 3 | apply from: "${rootDir}/gradle/plugins/util.gradle" 4 | apply plugin: 'org.jetbrains.dokka' 5 | 6 | group = optProperty("POM_GROUP_ID") 7 | archivesBaseName = optProperty("POM_NAME") 8 | version = optProperty("POM_VERSION") 9 | 10 | configurations { 11 | archives { 12 | extendsFrom configurations.default 13 | } 14 | } 15 | 16 | install { 17 | repositories.mavenInstaller { 18 | configurePOM(pom) 19 | } 20 | } 21 | 22 | bintray { 23 | user = optProperty("BINTRAY_USER") 24 | key = optProperty("BINTRAY_API_KEY") 25 | configurations = ['archives'] 26 | dryRun = false //Whether to run this as dry-run, without deploying 27 | publish = true //If version should be auto published after an upload 28 | //Package configuration. The plugin will use the repo and name properties to check if the package already exists. In that case, there's no need to configure the other package properties (like userOrg, desc, etc). 29 | 30 | pkg { 31 | repo = "maven" 32 | name = "SnowdreamFramework" //optProperty("POM_GROUP_ID") +":"+ optProperty("POM_ARTIFACT_ID") 33 | userOrg = optProperty("BINTRAY_USER") 34 | websiteUrl = optProperty("POM_URL") 35 | issueTrackerUrl = optProperty("POM_ISSUE_MANAGEMENT_URL") 36 | vcsUrl = optProperty("POM_SCM_URL") 37 | licenses = ['Apache-2.0'] 38 | labels = [] 39 | version { 40 | name = optProperty("POM_VERSION") 41 | desc = optProperty("POM_DESCRIPTION") 42 | vcsTag = optProperty("POM_VERSION") 43 | publicDownloadNumbers = true 44 | //attributes = ['gradle-plugin': 'com.use.less:com.use.less.gradle:gradle-useless-plugin'] 45 | //Optional configuration for GPG signing 46 | gpg { 47 | sign = true //Determines whether to GPG sign the files. The default is false 48 | passphrase = optProperty("signing.password") //Optional. The passphrase for GPG signing' 49 | } 50 | //Optional configuration for Maven Central sync of the version 51 | mavenCentralSync { 52 | sync = true //Optional (true by default). Determines whether to sync the version to Maven Central. 53 | user = optProperty("MAVEN_DEPLOY_USERNAME") //OSS user token 54 | password = optProperty("MAVEN_DEPLOY_PASSWORD") //OSS user password 55 | close = '1' //Optional property. By default the staging repository is closed and artifacts are released to Maven Central. You can optionally turn this behaviour off (by puting 0 as value) and release the version manually. 56 | } 57 | } 58 | } 59 | } 60 | 61 | //from https://discuss.gradle.org/t/javadoc-and-jar-fails/7537/6 62 | task classJar(type: Jar, dependsOn: compileJava) { 63 | from sourceSets.main.output.classesDir 64 | from "$buildDir/generated/source/kapt/release/ToyBricks.json" 65 | from "$buildDir/generated/source/apt/release/ToyBricks.json" 66 | } 67 | 68 | task sourcesJar(type: Jar) { 69 | classifier 'sources' 70 | from sourceSets.main.allSource 71 | from "$buildDir/generated/source/kapt/release/ToyBricks.json" 72 | from "$buildDir/generated/source/apt/release/ToyBricks.json" 73 | includeEmptyDirs false 74 | } 75 | 76 | task javadocJar(type: Jar, dependsOn: javadoc) { 77 | classifier 'javadoc' 78 | from javadoc.destinationDir 79 | includeEmptyDirs false 80 | } 81 | 82 | task kotlinjavadocJar(type: Jar, dependsOn: dokka) { 83 | classifier 'javadoc' 84 | from "$buildDir/javadoc" 85 | includeEmptyDirs false 86 | } 87 | 88 | artifacts { 89 | archives classJar 90 | archives sourcesJar 91 | archives javadocJar 92 | archives kotlinjavadocJar 93 | } 94 | 95 | private configurePOM(def pom) { 96 | pom.project { 97 | groupId optProperty("POM_GROUP_ID") 98 | artifactId optProperty("POM_ARTIFACT_ID") 99 | version optProperty("POM_VERSION") 100 | name optProperty("POM_NAME") 101 | packaging optProperty("POM_PACKAGING") 102 | description optProperty("POM_DESCRIPTION") 103 | url optProperty("POM_URL") 104 | inceptionYear optProperty("POM_INCEPTION_YEAR") 105 | 106 | scm { 107 | url optProperty("POM_SCM_URL") 108 | connection optProperty("POM_SCM_CONNECTION") 109 | developerConnection optProperty("POM_SCM_DEV_CONNECTION") 110 | } 111 | 112 | licenses { 113 | license { 114 | name optProperty("POM_LICENCE_NAME") 115 | url optProperty("POM_LICENCE_URL") 116 | distribution optProperty("POM_LICENCE_DIST") 117 | comments optProperty("POM_LICENCE_COMMENTS") 118 | } 119 | } 120 | 121 | developers { 122 | developer { 123 | id optProperty("POM_DEVELOPER_ID") 124 | name optProperty("POM_DEVELOPER_NAME") 125 | email optProperty("POM_DEVELOPER_EMAIL") 126 | url optProperty("POM_DEVELOPER_URL") 127 | } 128 | } 129 | 130 | issueManagement { 131 | system optProperty("POM_ISSUE_MANAGEMENT_SYSTEM") 132 | url optProperty("POM_ISSUE_MANAGEMENT_URL") 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /gradle/plugins/java-groovy-library.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | apply plugin: 'groovy' 3 | apply from: "${rootDir}/gradle/plugins/java-bintray-push.gradle" 4 | apply from: "${rootDir}/gradle/plugins/util.gradle" 5 | 6 | compileGroovy { 7 | sourceCompatibility = JavaVersion.VERSION_1_7 8 | targetCompatibility = JavaVersion.VERSION_1_7 9 | options.encoding = "UTF-8" 10 | } 11 | 12 | dependencies { 13 | compile gradleApi() 14 | compile localGroovy() 15 | } 16 | 17 | sourceSets { 18 | main.java.srcDirs += {'src/main/groovy';'src/main/java'} 19 | test.java.srcDirs += {'src/test/groovy';'src/test/java'} 20 | } 21 | 22 | jar{ 23 | includeEmptyDirs = false 24 | } -------------------------------------------------------------------------------- /gradle/plugins/java-kotlin-library.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | apply plugin: 'kotlin' 3 | apply from: "${rootDir}/gradle/plugins/java-bintray-push.gradle" 4 | apply from: "${rootDir}/gradle/plugins/util.gradle" 5 | 6 | 7 | targetCompatibility = JavaVersion.VERSION_1_7 8 | sourceCompatibility = JavaVersion.VERSION_1_7 9 | 10 | dependencies { 11 | compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 12 | compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" 13 | } 14 | 15 | sourceSets { 16 | main.java.srcDirs += 'src/main/kotlin' 17 | test.java.srcDirs += 'src/test/kotlin' 18 | } 19 | 20 | dokka { 21 | moduleName = project.name 22 | outputFormat = 'javadoc' 23 | outputDirectory = "$buildDir/javadoc" 24 | processConfigurations = ['compile'/*, 'extra'*/] 25 | includes = ['packages.md', 'extra.md'] 26 | samples = ['samples/basic.kt', 'samples/advanced.kt'] 27 | linkMapping { 28 | dir = "src/main/kotlin" 29 | url = "https://github.com/snowdream/" 30 | suffix = "#L" 31 | } 32 | sourceDirs = files('src/main/kotlin') 33 | } 34 | 35 | jar{ 36 | includeEmptyDirs = false 37 | } -------------------------------------------------------------------------------- /gradle/plugins/maven-push.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'maven' 2 | apply plugin: 'signing' 3 | apply from: "${rootDir}/gradle/plugins/util.gradle" 4 | 5 | group = optProperty("POM_GROUP_ID") 6 | archivesBaseName = optProperty("POM_NAME") 7 | version = optProperty("POM_VERSION") 8 | 9 | configurations { 10 | archives { 11 | extendsFrom configurations.default 12 | } 13 | } 14 | 15 | ext.isReleaseVersion = !version.endsWith("SNAPSHOT") 16 | 17 | def mavenRepoUrl 18 | if (isReleaseVersion) { 19 | mavenRepoUrl = optProperty("MAVEN_DEPLOY_URL","https://oss.sonatype.org/service/local/staging/deploy/maven2/") 20 | 21 | } else { 22 | mavenRepoUrl = optProperty("MAVEN_DEPLOY_SNAPSHOT_URL","https://oss.sonatype.org/content/repositories/snapshots/") 23 | } 24 | 25 | afterEvaluate { project -> 26 | uploadArchives { 27 | repositories { 28 | mavenDeployer { 29 | configurePOM(pom) 30 | beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } 31 | 32 | repository(url: mavenRepoUrl) { 33 | authentication(userName: optProperty("MAVEN_DEPLOY_USERNAME"), password: optProperty("MAVEN_DEPLOY_PASSWORD")) 34 | } 35 | } 36 | } 37 | } 38 | 39 | signing { 40 | required { isReleaseVersion && gradle.taskGraph.hasTask("uploadArchives") } 41 | sign configurations.archives 42 | } 43 | 44 | task androidReleaseJar(type: Jar,dependsOn: "assembleRelease") { 45 | from "$buildDir/intermediates/classes/release/" 46 | exclude '**/BuildConfig.class' 47 | exclude '**/R.class' 48 | exclude '**/R$*.class' 49 | } 50 | 51 | task androidJavadocsJar(type: Jar) { 52 | classifier = 'javadoc' 53 | from "generateReleaseJavadoc.destinationDir" 54 | } 55 | 56 | task androidSourcesJar(type: Jar) { 57 | classifier = 'sources' 58 | from android.sourceSets.main.java.srcDirs 59 | } 60 | 61 | 62 | artifacts { 63 | archives androidReleaseJar 64 | archives androidSourcesJar 65 | archives androidJavadocsJar 66 | } 67 | } 68 | 69 | private configurePOM(def pom) { 70 | pom.project { 71 | groupId optProperty("POM_GROUP_ID") 72 | artifactId optProperty("POM_ARTIFACT_ID") 73 | version optProperty("POM_VERSION") 74 | name optProperty("POM_NAME") 75 | packaging optProperty("POM_PACKAGING") 76 | description optProperty("POM_DESCRIPTION") 77 | url optProperty("POM_URL") 78 | inceptionYear optProperty("POM_INCEPTION_YEAR") 79 | 80 | scm { 81 | url optProperty("POM_SCM_URL") 82 | connection optProperty("POM_SCM_CONNECTION") 83 | developerConnection optProperty("POM_SCM_DEV_CONNECTION") 84 | } 85 | 86 | licenses { 87 | license { 88 | name optProperty("POM_LICENCE_NAME") 89 | url optProperty("POM_LICENCE_URL") 90 | distribution optProperty("POM_LICENCE_DIST") 91 | comments optProperty("POM_LICENCE_COMMENTS") 92 | } 93 | } 94 | 95 | developers { 96 | developer { 97 | id optProperty("POM_DEVELOPER_ID") 98 | name optProperty("POM_DEVELOPER_NAME") 99 | email optProperty("POM_DEVELOPER_EMAIL") 100 | url optProperty("POM_DEVELOPER_URL") 101 | } 102 | } 103 | 104 | issueManagement { 105 | system optProperty("POM_ISSUE_MANAGEMENT_SYSTEM") 106 | url optProperty("POM_ISSUE_MANAGEMENT_URL") 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /gradle/plugins/util.gradle: -------------------------------------------------------------------------------- 1 | // util 2 | 3 | 4 | /** 5 | * opt property from system env, system.properties, project property 6 | * 7 | * Usage: 8 | * 9 | * apply from: "util.gradle" 10 | * 11 | * optProperty("GRADLE_HOME") 12 | * 13 | */ 14 | ext.optProperty = { propertyName , defaultPropertyValue = "" -> 15 | 16 | //system env 17 | if (System.getenv().containsKey(propertyName)) { 18 | return System.getenv(propertyName); 19 | } 20 | 21 | //system property 22 | if (System.properties.containsKey(propertyName)) { 23 | return System.properties[propertyName]; 24 | } 25 | 26 | //project property 27 | if (project.hasProperty(propertyName)) { 28 | return project.getProperty(propertyName); 29 | } 30 | 31 | return defaultPropertyValue; 32 | } 33 | 34 | /** 35 | * check property from system env, system.properties, project property 36 | * 37 | * Usage: 38 | * 39 | * apply from: "util.gradle" 40 | * 41 | * containsProperty("GRADLE_HOME") 42 | * 43 | */ 44 | ext.containsProperty = { propertyName -> 45 | return (System.getenv().containsKey(propertyName) || System.properties.containsKey(propertyName) || project.hasProperty(propertyName)); 46 | } 47 | -------------------------------------------------------------------------------- /gradle/proguard/proguard-android-all.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | # http://proguard.sourceforge.net/index.html#manual/usage.html 13 | # http://proguard.sourceforge.net/index.html#manual/examples.html 14 | 15 | # Add any project specific keep options here: 16 | 17 | # If your project uses WebView with JS, uncomment the following 18 | # and specify the fully qualified class name to the JavaScript interface 19 | # class: 20 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 21 | # public *; 22 | #} 23 | 24 | 25 | # Some important configuration is based on the annotations in the code. 26 | # We have to specify what the annotations mean to ProGuard. 27 | 28 | # General Options 29 | -verbose 30 | 31 | # Suppress duplicate warning for system classes; Blaze is passing android.jar 32 | # to proguard multiple times. 33 | -dontnote android.** 34 | -dontnote dalvik.** 35 | -dontnote com.android.** 36 | -dontnote google.** 37 | -dontnote com.google.** 38 | -dontnote java.** 39 | -dontnote javax.** 40 | -dontnote junit.** 41 | -dontnote org.apache.** 42 | -dontnote org.json.** 43 | -dontnote org.w3c.dom.** 44 | -dontnote org.xml.sax.** 45 | -dontnote org.xmlpull.v1.** 46 | 47 | 48 | # Stop warnings about missing unused classes 49 | -dontwarn android.** 50 | -dontwarn dalvik.** 51 | -dontwarn com.android.** 52 | -dontwarn google.** 53 | -dontwarn com.google.** 54 | -dontwarn java.** 55 | -dontwarn javax.** 56 | -dontwarn junit.** 57 | -dontwarn org.apache.** 58 | -dontwarn org.json.** 59 | -dontwarn org.w3c.dom.** 60 | -dontwarn org.xml.sax.** 61 | -dontwarn org.xmlpull.v1.** 62 | 63 | # Input/Output Options 64 | -dontskipnonpubliclibraryclasses 65 | -dontskipnonpubliclibraryclassmembers 66 | 67 | # Keep Options 68 | -keep public class * extends android.app.Activity 69 | -keep public class * extends android.app.Application 70 | -keep public class * extends android.app.Service 71 | -keep public class * extends android.content.BroadcastReceiver 72 | -keep public class * extends android.content.ContentProvider 73 | -keep public class * extends android.app.backup.BackupAgentHelper 74 | -keep public class * extends android.preference.Preference 75 | -keep public class com.google.vending.licensing.ILicensingService 76 | -keep public class com.android.vending.licensing.ILicensingService 77 | 78 | -keep public class * extends android.view.View { 79 | public (android.content.Context); 80 | public (android.content.Context, android.util.AttributeSet); 81 | public (android.content.Context, android.util.AttributeSet, int); 82 | public void set*(...); 83 | } 84 | 85 | -keepclasseswithmembers class * { 86 | public (android.content.Context, android.util.AttributeSet); 87 | } 88 | 89 | -keepclasseswithmembers class * { 90 | public (android.content.Context, android.util.AttributeSet, int); 91 | } 92 | 93 | -keepclassmembers class * extends android.content.Context { 94 | public void *(android.view.View); 95 | public void *(android.view.MenuItem); 96 | } 97 | 98 | -keepclassmembers class * implements android.os.Parcelable { 99 | static ** CREATOR; 100 | } 101 | 102 | -keepclassmembers class **.R$* { 103 | public static ; 104 | } 105 | 106 | -keepclassmembers class * { 107 | @android.webkit.JavascriptInterface ; 108 | } 109 | 110 | 111 | -keep public class * { 112 | public protected *; 113 | } 114 | 115 | -keepclassmembernames class * { 116 | java.lang.Class class$(java.lang.String); 117 | java.lang.Class class$(java.lang.String, boolean); 118 | } 119 | 120 | -keepclasseswithmembernames,includedescriptorclasses class * { 121 | native ; 122 | } 123 | 124 | -keepclassmembers,allowoptimization enum * { 125 | (...); 126 | public static **[] values(); 127 | public static ** valueOf(java.lang.String); 128 | } 129 | 130 | -keepclassmembers class * implements java.io.Serializable { 131 | static final long serialVersionUID; 132 | private static final java.io.ObjectStreamField[] serialPersistentFields; 133 | private void writeObject(java.io.ObjectOutputStream); 134 | private void readObject(java.io.ObjectInputStream); 135 | java.lang.Object writeReplace(); 136 | java.lang.Object readResolve(); 137 | } 138 | 139 | # Shrinking Options 140 | # -dontshrink 141 | 142 | 143 | # Optimization Options 144 | # -dontoptimize 145 | -optimizationpasses 5 146 | -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*,!code/allocation/variable,!class/unboxing/enum 147 | 148 | # In the optimization step, ProGuard will then remove calls to such methods, if it can determine that the return values aren't used. 149 | 150 | # -assumenosideeffects class android.util.Log { 151 | # public static boolean isLoggable(java.lang.String, int); 152 | # public static int v(...); 153 | # public static int i(...); 154 | # public static int w(...); 155 | # public static int d(...); 156 | # public static int e(...); 157 | # } 158 | 159 | #Specifies that the access modifiers of classes and class members may be broadened during processing. 160 | #Counter-indication: you probably shouldn't use this option when processing code that is to be used as a library, since classes and class members that weren't designed to be public in the API may become public. 161 | -allowaccessmodification 162 | 163 | 164 | # Obfuscation Options 165 | #-dontobfuscate 166 | -dontusemixedcaseclassnames 167 | 168 | #Counter-indication: classes that look for resource files in their package directories will no longer work properly if they are moved elsewhere. When in doubt, just leave the packaging untouched by not using this option. 169 | -repackageclasses '' 170 | 171 | #This option actually keeps trimmed versions of the debugging attributes LocalVariableTable and LocalVariableTypeTable. It can be useful when processing a library. 172 | -keepparameternames 173 | 174 | #For library 175 | -keepattributes Exceptions,InnerClasses,Signature,Deprecated, 176 | SourceFile,LineNumberTable,*Annotation*,EnclosingMethod,MethodParameters 177 | 178 | #For app 179 | #-keepattributes *Annotation* 180 | 181 | 182 | # Preverification Options 183 | # Preverification is irrelevant for the dex compiler and the Dalvik VM, so we can switch it off with the -dontpreverify option. 184 | -dontpreverify 185 | -------------------------------------------------------------------------------- /gradle/proguard/proguard-android-app-optimize.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | # http://proguard.sourceforge.net/index.html#manual/usage.html 13 | # http://proguard.sourceforge.net/index.html#manual/examples.html 14 | 15 | # Add any project specific keep options here: 16 | 17 | # If your project uses WebView with JS, uncomment the following 18 | # and specify the fully qualified class name to the JavaScript interface 19 | # class: 20 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 21 | # public *; 22 | #} 23 | 24 | 25 | # Some important configuration is based on the annotations in the code. 26 | # We have to specify what the annotations mean to ProGuard. 27 | 28 | # General Options 29 | -verbose 30 | 31 | # Suppress duplicate warning for system classes; Blaze is passing android.jar 32 | # to proguard multiple times. 33 | -dontnote android.** 34 | -dontnote dalvik.** 35 | -dontnote com.android.** 36 | -dontnote google.** 37 | -dontnote com.google.** 38 | -dontnote java.** 39 | -dontnote javax.** 40 | -dontnote junit.** 41 | -dontnote org.apache.** 42 | -dontnote org.json.** 43 | -dontnote org.w3c.dom.** 44 | -dontnote org.xml.sax.** 45 | -dontnote org.xmlpull.v1.** 46 | 47 | 48 | # Stop warnings about missing unused classes 49 | -dontwarn android.** 50 | -dontwarn dalvik.** 51 | -dontwarn com.android.** 52 | -dontwarn google.** 53 | -dontwarn com.google.** 54 | -dontwarn java.** 55 | -dontwarn javax.** 56 | -dontwarn junit.** 57 | -dontwarn org.apache.** 58 | -dontwarn org.json.** 59 | -dontwarn org.w3c.dom.** 60 | -dontwarn org.xml.sax.** 61 | -dontwarn org.xmlpull.v1.** 62 | 63 | # Input/Output Options 64 | -dontskipnonpubliclibraryclasses 65 | -dontskipnonpubliclibraryclassmembers 66 | 67 | # Keep Options 68 | -keep public class * extends android.app.Activity 69 | -keep public class * extends android.app.Application 70 | -keep public class * extends android.app.Service 71 | -keep public class * extends android.content.BroadcastReceiver 72 | -keep public class * extends android.content.ContentProvider 73 | -keep public class * extends android.app.backup.BackupAgentHelper 74 | -keep public class * extends android.preference.Preference 75 | -keep public class com.google.vending.licensing.ILicensingService 76 | -keep public class com.android.vending.licensing.ILicensingService 77 | 78 | -keep public class * extends android.view.View { 79 | public (android.content.Context); 80 | public (android.content.Context, android.util.AttributeSet); 81 | public (android.content.Context, android.util.AttributeSet, int); 82 | public void set*(...); 83 | } 84 | 85 | -keepclasseswithmembers class * { 86 | public (android.content.Context, android.util.AttributeSet); 87 | } 88 | 89 | -keepclasseswithmembers class * { 90 | public (android.content.Context, android.util.AttributeSet, int); 91 | } 92 | 93 | -keepclassmembers class * extends android.content.Context { 94 | public void *(android.view.View); 95 | public void *(android.view.MenuItem); 96 | } 97 | 98 | -keepclassmembers class * implements android.os.Parcelable { 99 | static ** CREATOR; 100 | } 101 | 102 | -keepclassmembers class **.R$* { 103 | public static ; 104 | } 105 | 106 | -keepclassmembers class * { 107 | @android.webkit.JavascriptInterface ; 108 | } 109 | -keepclassmembernames class * { 110 | java.lang.Class class$(java.lang.String); 111 | java.lang.Class class$(java.lang.String, boolean); 112 | } 113 | -keepclasseswithmembernames,includedescriptorclasses class * { 114 | native ; 115 | } 116 | 117 | -keepclassmembers,allowoptimization enum * { 118 | (...); 119 | public static **[] values(); 120 | public static ** valueOf(java.lang.String); 121 | } 122 | 123 | -keepclassmembers class * implements java.io.Serializable { 124 | static final long serialVersionUID; 125 | private static final java.io.ObjectStreamField[] serialPersistentFields; 126 | private void writeObject(java.io.ObjectOutputStream); 127 | private void readObject(java.io.ObjectInputStream); 128 | java.lang.Object writeReplace(); 129 | java.lang.Object readResolve(); 130 | } 131 | 132 | # Shrinking Options 133 | # -dontshrink 134 | 135 | # Optimization Options 136 | # -dontoptimize 137 | -optimizationpasses 5 138 | -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*,!code/allocation/variable,!class/unboxing/enum 139 | 140 | # In the optimization step, ProGuard will then remove calls to such methods, if it can determine that the return values aren't used. 141 | 142 | -assumenosideeffects class android.util.Log { 143 | public static boolean isLoggable(java.lang.String, int); 144 | public static int v(...); 145 | public static int i(...); 146 | public static int w(...); 147 | public static int d(...); 148 | public static int e(...); 149 | } 150 | 151 | #Specifies that the access modifiers of classes and class members may be broadened during processing. 152 | #Counter-indication: you probably shouldn't use this option when processing code that is to be used as a library, since classes and class members that weren't designed to be public in the API may become public. 153 | -allowaccessmodification 154 | 155 | # Obfuscation Options 156 | #-dontobfuscate 157 | -dontusemixedcaseclassnames 158 | 159 | #For app 160 | #-keepattributes *Annotation* 161 | 162 | # Preverification Options 163 | # Preverification is irrelevant for the dex compiler and the Dalvik VM, so we can switch it off with the -dontpreverify option. 164 | -dontpreverify 165 | -------------------------------------------------------------------------------- /gradle/proguard/proguard-android-app.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | # http://proguard.sourceforge.net/index.html#manual/usage.html 13 | # http://proguard.sourceforge.net/index.html#manual/examples.html 14 | 15 | # Add any project specific keep options here: 16 | 17 | # If your project uses WebView with JS, uncomment the following 18 | # and specify the fully qualified class name to the JavaScript interface 19 | # class: 20 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 21 | # public *; 22 | #} 23 | 24 | # Some important configuration is based on the annotations in the code. 25 | # We have to specify what the annotations mean to ProGuard. 26 | 27 | # General Options 28 | -verbose 29 | 30 | # Suppress duplicate warning for system classes; Blaze is passing android.jar 31 | # to proguard multiple times. 32 | -dontnote android.** 33 | -dontnote dalvik.** 34 | -dontnote com.android.** 35 | -dontnote google.** 36 | -dontnote com.google.** 37 | -dontnote java.** 38 | -dontnote javax.** 39 | -dontnote junit.** 40 | -dontnote org.apache.** 41 | -dontnote org.json.** 42 | -dontnote org.w3c.dom.** 43 | -dontnote org.xml.sax.** 44 | -dontnote org.xmlpull.v1.** 45 | 46 | 47 | # Stop warnings about missing unused classes 48 | -dontwarn android.** 49 | -dontwarn dalvik.** 50 | -dontwarn com.android.** 51 | -dontwarn google.** 52 | -dontwarn com.google.** 53 | -dontwarn java.** 54 | -dontwarn javax.** 55 | -dontwarn junit.** 56 | -dontwarn org.apache.** 57 | -dontwarn org.json.** 58 | -dontwarn org.w3c.dom.** 59 | -dontwarn org.xml.sax.** 60 | -dontwarn org.xmlpull.v1.** 61 | 62 | # Input/Output Options 63 | -dontskipnonpubliclibraryclasses 64 | -dontskipnonpubliclibraryclassmembers 65 | 66 | # Keep Options 67 | -keep public class * extends android.app.Activity 68 | -keep public class * extends android.app.Application 69 | -keep public class * extends android.app.Service 70 | -keep public class * extends android.content.BroadcastReceiver 71 | -keep public class * extends android.content.ContentProvider 72 | -keep public class * extends android.app.backup.BackupAgentHelper 73 | -keep public class * extends android.preference.Preference 74 | -keep public class com.google.vending.licensing.ILicensingService 75 | -keep public class com.android.vending.licensing.ILicensingService 76 | 77 | -keep public class * extends android.view.View { 78 | public (android.content.Context); 79 | public (android.content.Context, android.util.AttributeSet); 80 | public (android.content.Context, android.util.AttributeSet, int); 81 | public void set*(...); 82 | } 83 | 84 | -keepclasseswithmembers class * { 85 | public (android.content.Context, android.util.AttributeSet); 86 | } 87 | 88 | -keepclasseswithmembers class * { 89 | public (android.content.Context, android.util.AttributeSet, int); 90 | } 91 | 92 | -keepclassmembers class * extends android.content.Context { 93 | public void *(android.view.View); 94 | public void *(android.view.MenuItem); 95 | } 96 | 97 | -keepclassmembers class * implements android.os.Parcelable { 98 | static ** CREATOR; 99 | } 100 | 101 | -keepclassmembers class **.R$* { 102 | public static ; 103 | } 104 | 105 | -keepclassmembers class * { 106 | @android.webkit.JavascriptInterface ; 107 | } 108 | -keepclassmembernames class * { 109 | java.lang.Class class$(java.lang.String); 110 | java.lang.Class class$(java.lang.String, boolean); 111 | } 112 | -keepclasseswithmembernames,includedescriptorclasses class * { 113 | native ; 114 | } 115 | 116 | -keepclassmembers,allowoptimization enum * { 117 | (...); 118 | public static **[] values(); 119 | public static ** valueOf(java.lang.String); 120 | } 121 | 122 | -keepclassmembers class * implements java.io.Serializable { 123 | static final long serialVersionUID; 124 | private static final java.io.ObjectStreamField[] serialPersistentFields; 125 | private void writeObject(java.io.ObjectOutputStream); 126 | private void readObject(java.io.ObjectInputStream); 127 | java.lang.Object writeReplace(); 128 | java.lang.Object readResolve(); 129 | } 130 | 131 | # Shrinking Options 132 | # -dontshrink 133 | 134 | # Optimization Options 135 | -dontoptimize 136 | 137 | 138 | #Specifies that the access modifiers of classes and class members may be broadened during processing. 139 | #Counter-indication: you probably shouldn't use this option when processing code that is to be used as a library, since classes and class members that weren't designed to be public in the API may become public. 140 | -allowaccessmodification 141 | 142 | # Obfuscation Options 143 | #-dontobfuscate 144 | -dontusemixedcaseclassnames 145 | 146 | #For app 147 | #-keepattributes *Annotation* 148 | 149 | # Preverification Options 150 | # Preverification is irrelevant for the dex compiler and the Dalvik VM, so we can switch it off with the -dontpreverify option. 151 | -dontpreverify 152 | -------------------------------------------------------------------------------- /gradle/proguard/proguard-android-lib-optimize.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | # http://proguard.sourceforge.net/index.html#manual/usage.html 13 | # http://proguard.sourceforge.net/index.html#manual/examples.html 14 | 15 | # Add any project specific keep options here: 16 | 17 | # If your project uses WebView with JS, uncomment the following 18 | # and specify the fully qualified class name to the JavaScript interface 19 | # class: 20 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 21 | # public *; 22 | #} 23 | 24 | 25 | # Some important configuration is based on the annotations in the code. 26 | # We have to specify what the annotations mean to ProGuard. 27 | 28 | # General Options 29 | -verbose 30 | 31 | # Suppress duplicate warning for system classes; Blaze is passing android.jar 32 | # to proguard multiple times. 33 | -dontnote android.** 34 | -dontnote dalvik.** 35 | -dontnote com.android.** 36 | -dontnote google.** 37 | -dontnote com.google.** 38 | -dontnote java.** 39 | -dontnote javax.** 40 | -dontnote junit.** 41 | -dontnote org.apache.** 42 | -dontnote org.json.** 43 | -dontnote org.w3c.dom.** 44 | -dontnote org.xml.sax.** 45 | -dontnote org.xmlpull.v1.** 46 | 47 | 48 | # Stop warnings about missing unused classes 49 | -dontwarn android.** 50 | -dontwarn dalvik.** 51 | -dontwarn com.android.** 52 | -dontwarn google.** 53 | -dontwarn com.google.** 54 | -dontwarn java.** 55 | -dontwarn javax.** 56 | -dontwarn junit.** 57 | -dontwarn org.apache.** 58 | -dontwarn org.json.** 59 | -dontwarn org.w3c.dom.** 60 | -dontwarn org.xml.sax.** 61 | -dontwarn org.xmlpull.v1.** 62 | 63 | # Input/Output Options 64 | -dontskipnonpubliclibraryclasses 65 | -dontskipnonpubliclibraryclassmembers 66 | 67 | # Keep Options 68 | -keep public class * extends android.app.Activity 69 | -keep public class * extends android.app.Application 70 | -keep public class * extends android.app.Service 71 | -keep public class * extends android.content.BroadcastReceiver 72 | -keep public class * extends android.content.ContentProvider 73 | -keep public class * extends android.app.backup.BackupAgentHelper 74 | -keep public class * extends android.preference.Preference 75 | -keep public class com.google.vending.licensing.ILicensingService 76 | -keep public class com.android.vending.licensing.ILicensingService 77 | 78 | -keep public class * extends android.view.View { 79 | public (android.content.Context); 80 | public (android.content.Context, android.util.AttributeSet); 81 | public (android.content.Context, android.util.AttributeSet, int); 82 | public void set*(...); 83 | } 84 | 85 | -keepclasseswithmembers class * { 86 | public (android.content.Context, android.util.AttributeSet); 87 | } 88 | 89 | -keepclasseswithmembers class * { 90 | public (android.content.Context, android.util.AttributeSet, int); 91 | } 92 | 93 | -keepclassmembers class * extends android.content.Context { 94 | public void *(android.view.View); 95 | public void *(android.view.MenuItem); 96 | } 97 | 98 | -keepclassmembers class * implements android.os.Parcelable { 99 | static ** CREATOR; 100 | } 101 | 102 | -keepclassmembers class **.R$* { 103 | public static ; 104 | } 105 | 106 | -keepclassmembers class * { 107 | @android.webkit.JavascriptInterface ; 108 | } 109 | 110 | 111 | -keep public class * { 112 | public protected *; 113 | } 114 | 115 | -keepclassmembernames class * { 116 | java.lang.Class class$(java.lang.String); 117 | java.lang.Class class$(java.lang.String, boolean); 118 | } 119 | 120 | -keepclasseswithmembernames,includedescriptorclasses class * { 121 | native ; 122 | } 123 | 124 | -keepclassmembers,allowoptimization enum * { 125 | (...); 126 | public static **[] values(); 127 | public static ** valueOf(java.lang.String); 128 | } 129 | 130 | -keepclassmembers class * implements java.io.Serializable { 131 | static final long serialVersionUID; 132 | private static final java.io.ObjectStreamField[] serialPersistentFields; 133 | private void writeObject(java.io.ObjectOutputStream); 134 | private void readObject(java.io.ObjectInputStream); 135 | java.lang.Object writeReplace(); 136 | java.lang.Object readResolve(); 137 | } 138 | 139 | # Shrinking Options 140 | # -dontshrink 141 | # Optimization Options 142 | # -dontoptimize 143 | -optimizationpasses 5 144 | -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*,!code/allocation/variable,!class/unboxing/enum 145 | 146 | # In the optimization step, ProGuard will then remove calls to such methods, if it can determine that the return values aren't used. 147 | 148 | -assumenosideeffects class android.util.Log { 149 | public static boolean isLoggable(java.lang.String, int); 150 | public static int v(...); 151 | public static int i(...); 152 | public static int w(...); 153 | public static int d(...); 154 | public static int e(...); 155 | } 156 | 157 | # Obfuscation Options 158 | #-dontobfuscate 159 | -dontusemixedcaseclassnames 160 | 161 | #This option actually keeps trimmed versions of the debugging attributes LocalVariableTable and LocalVariableTypeTable. It can be useful when processing a library. 162 | -keepparameternames 163 | 164 | #For library 165 | -keepattributes Exceptions,InnerClasses,Signature,Deprecated, 166 | SourceFile,LineNumberTable,*Annotation*,EnclosingMethod,MethodParameters 167 | 168 | # Preverification Options 169 | # Preverification is irrelevant for the dex compiler and the Dalvik VM, so we can switch it off with the -dontpreverify option. 170 | -dontpreverify 171 | -------------------------------------------------------------------------------- /gradle/proguard/proguard-android-lib.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | # http://proguard.sourceforge.net/index.html#manual/usage.html 13 | # http://proguard.sourceforge.net/index.html#manual/examples.html 14 | 15 | # Add any project specific keep options here: 16 | 17 | # If your project uses WebView with JS, uncomment the following 18 | # and specify the fully qualified class name to the JavaScript interface 19 | # class: 20 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 21 | # public *; 22 | #} 23 | 24 | 25 | # Some important configuration is based on the annotations in the code. 26 | # We have to specify what the annotations mean to ProGuard. 27 | 28 | # General Options 29 | -verbose 30 | 31 | # Suppress duplicate warning for system classes; Blaze is passing android.jar 32 | # to proguard multiple times. 33 | -dontnote android.** 34 | -dontnote dalvik.** 35 | -dontnote com.android.** 36 | -dontnote google.** 37 | -dontnote com.google.** 38 | -dontnote java.** 39 | -dontnote javax.** 40 | -dontnote junit.** 41 | -dontnote org.apache.** 42 | -dontnote org.json.** 43 | -dontnote org.w3c.dom.** 44 | -dontnote org.xml.sax.** 45 | -dontnote org.xmlpull.v1.** 46 | 47 | 48 | # Stop warnings about missing unused classes 49 | -dontwarn android.** 50 | -dontwarn dalvik.** 51 | -dontwarn com.android.** 52 | -dontwarn google.** 53 | -dontwarn com.google.** 54 | -dontwarn java.** 55 | -dontwarn javax.** 56 | -dontwarn junit.** 57 | -dontwarn org.apache.** 58 | -dontwarn org.json.** 59 | -dontwarn org.w3c.dom.** 60 | -dontwarn org.xml.sax.** 61 | -dontwarn org.xmlpull.v1.** 62 | 63 | # Input/Output Options 64 | -dontskipnonpubliclibraryclasses 65 | -dontskipnonpubliclibraryclassmembers 66 | 67 | # Keep Options 68 | -keep public class * extends android.app.Activity 69 | -keep public class * extends android.app.Application 70 | -keep public class * extends android.app.Service 71 | -keep public class * extends android.content.BroadcastReceiver 72 | -keep public class * extends android.content.ContentProvider 73 | -keep public class * extends android.app.backup.BackupAgentHelper 74 | -keep public class * extends android.preference.Preference 75 | -keep public class com.google.vending.licensing.ILicensingService 76 | -keep public class com.android.vending.licensing.ILicensingService 77 | 78 | -keep public class * extends android.view.View { 79 | public (android.content.Context); 80 | public (android.content.Context, android.util.AttributeSet); 81 | public (android.content.Context, android.util.AttributeSet, int); 82 | public void set*(...); 83 | } 84 | 85 | -keepclasseswithmembers class * { 86 | public (android.content.Context, android.util.AttributeSet); 87 | } 88 | 89 | -keepclasseswithmembers class * { 90 | public (android.content.Context, android.util.AttributeSet, int); 91 | } 92 | 93 | -keepclassmembers class * extends android.content.Context { 94 | public void *(android.view.View); 95 | public void *(android.view.MenuItem); 96 | } 97 | 98 | -keepclassmembers class * implements android.os.Parcelable { 99 | static ** CREATOR; 100 | } 101 | 102 | -keepclassmembers class **.R$* { 103 | public static ; 104 | } 105 | 106 | -keepclassmembers class * { 107 | @android.webkit.JavascriptInterface ; 108 | } 109 | 110 | 111 | -keep public class * { 112 | public protected *; 113 | } 114 | 115 | -keepclassmembernames class * { 116 | java.lang.Class class$(java.lang.String); 117 | java.lang.Class class$(java.lang.String, boolean); 118 | } 119 | 120 | -keepclasseswithmembernames,includedescriptorclasses class * { 121 | native ; 122 | } 123 | 124 | -keepclassmembers,allowoptimization enum * { 125 | (...); 126 | public static **[] values(); 127 | public static ** valueOf(java.lang.String); 128 | } 129 | 130 | -keepclassmembers class * implements java.io.Serializable { 131 | static final long serialVersionUID; 132 | private static final java.io.ObjectStreamField[] serialPersistentFields; 133 | private void writeObject(java.io.ObjectOutputStream); 134 | private void readObject(java.io.ObjectInputStream); 135 | java.lang.Object writeReplace(); 136 | java.lang.Object readResolve(); 137 | } 138 | 139 | # Shrinking Options 140 | # -dontshrink 141 | 142 | # Optimization Options 143 | -dontoptimize 144 | # Obfuscation Options 145 | #-dontobfuscate 146 | -dontusemixedcaseclassnames 147 | 148 | #This option actually keeps trimmed versions of the debugging attributes LocalVariableTable and LocalVariableTypeTable. It can be useful when processing a library. 149 | -keepparameternames 150 | 151 | #For library 152 | -keepattributes Exceptions,InnerClasses,Signature,Deprecated, 153 | SourceFile,LineNumberTable,*Annotation*,EnclosingMethod,MethodParameters 154 | 155 | # Preverification Options 156 | # Preverification is irrelevant for the dex compiler and the Dalvik VM, so we can switch it off with the -dontpreverify option. 157 | -dontpreverify 158 | -------------------------------------------------------------------------------- /gradle/proguard/proguard-android-optimize.txt: -------------------------------------------------------------------------------- 1 | # This is a configuration file for ProGuard. 2 | # http://proguard.sourceforge.net/index.html#manual/usage.html 3 | 4 | # Optimizations: If you don't want to optimize, use the 5 | # proguard-android.txt configuration file instead of this one, which 6 | # turns off the optimization flags. Adding optimization introduces 7 | # certain risks, since for example not all optimizations performed by 8 | # ProGuard works on all versions of Dalvik. The following flags turn 9 | # off various optimizations known to have issues, but the list may not 10 | # be complete or up to date. (The "arithmetic" optimization can be 11 | # used if you are only targeting Android 2.0 or later.) Make sure you 12 | # test thoroughly if you go this route. 13 | -optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/* 14 | -optimizationpasses 5 15 | -allowaccessmodification 16 | -dontpreverify 17 | 18 | # The remainder of this file is identical to the non-optimized version 19 | # of the Proguard configuration file (except that the other file has 20 | # flags to turn off optimization). 21 | 22 | -dontusemixedcaseclassnames 23 | -dontskipnonpubliclibraryclasses 24 | -verbose 25 | 26 | -keepattributes *Annotation* 27 | -keep public class com.google.vending.licensing.ILicensingService 28 | -keep public class com.android.vending.licensing.ILicensingService 29 | 30 | # For native methods, see http://proguard.sourceforge.net/manual/examples.html#native 31 | -keepclasseswithmembernames class * { 32 | native ; 33 | } 34 | 35 | # keep setters in Views so that animations can still work. 36 | # see http://proguard.sourceforge.net/manual/examples.html#beans 37 | -keepclassmembers public class * extends android.view.View { 38 | void set*(***); 39 | *** get*(); 40 | } 41 | 42 | # We want to keep methods in Activity that could be used in the XML attribute onClick 43 | -keepclassmembers class * extends android.app.Activity { 44 | public void *(android.view.View); 45 | } 46 | 47 | # For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations 48 | -keepclassmembers enum * { 49 | public static **[] values(); 50 | public static ** valueOf(java.lang.String); 51 | } 52 | 53 | -keepclassmembers class * implements android.os.Parcelable { 54 | public static final android.os.Parcelable$Creator CREATOR; 55 | } 56 | 57 | -keepclassmembers class **.R$* { 58 | public static ; 59 | } 60 | 61 | # The support library contains references to newer platform versions. 62 | # Don't warn about those in case this app is linking against an older 63 | # platform version. We know about them, and they are safe. 64 | -dontwarn android.support.** 65 | 66 | # Understand the @Keep support annotation. 67 | -keep class android.support.annotation.Keep 68 | 69 | -keep @android.support.annotation.Keep class * {*;} 70 | 71 | -keepclasseswithmembers class * { 72 | @android.support.annotation.Keep ; 73 | } 74 | 75 | -keepclasseswithmembers class * { 76 | @android.support.annotation.Keep ; 77 | } 78 | 79 | -keepclasseswithmembers class * { 80 | @android.support.annotation.Keep (...); 81 | } 82 | 83 | # Some important configuration is based on the annotations in the code. 84 | # We have to specify what the annotations mean to ProGuard. 85 | -------------------------------------------------------------------------------- /gradle/proguard/proguard-android.txt: -------------------------------------------------------------------------------- 1 | # This is a configuration file for ProGuard. 2 | # http://proguard.sourceforge.net/index.html#manual/usage.html 3 | 4 | -dontusemixedcaseclassnames 5 | -dontskipnonpubliclibraryclasses 6 | -verbose 7 | 8 | # Optimization is turned off by default. Dex does not like code run 9 | # through the ProGuard optimize and preverify steps (and performs some 10 | # of these optimizations on its own). 11 | -dontoptimize 12 | -dontpreverify 13 | # Note that if you want to enable optimization, you cannot just 14 | # include optimization flags in your own project configuration file; 15 | # instead you will need to point to the 16 | # "proguard-android-optimize.txt" file instead of this one from your 17 | # project.properties file. 18 | 19 | -keepattributes *Annotation* 20 | -keep public class com.google.vending.licensing.ILicensingService 21 | -keep public class com.android.vending.licensing.ILicensingService 22 | 23 | # For native methods, see http://proguard.sourceforge.net/manual/examples.html#native 24 | -keepclasseswithmembernames class * { 25 | native ; 26 | } 27 | 28 | # keep setters in Views so that animations can still work. 29 | # see http://proguard.sourceforge.net/manual/examples.html#beans 30 | -keepclassmembers public class * extends android.view.View { 31 | void set*(***); 32 | *** get*(); 33 | } 34 | 35 | # We want to keep methods in Activity that could be used in the XML attribute onClick 36 | -keepclassmembers class * extends android.app.Activity { 37 | public void *(android.view.View); 38 | } 39 | 40 | # For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations 41 | -keepclassmembers enum * { 42 | public static **[] values(); 43 | public static ** valueOf(java.lang.String); 44 | } 45 | 46 | -keepclassmembers class * implements android.os.Parcelable { 47 | public static final android.os.Parcelable$Creator CREATOR; 48 | } 49 | 50 | -keepclassmembers class **.R$* { 51 | public static ; 52 | } 53 | 54 | # The support library contains references to newer platform versions. 55 | # Don't warn about those in case this app is linking against an older 56 | # platform version. We know about them, and they are safe. 57 | -dontwarn android.support.** 58 | 59 | # Understand the @Keep support annotation. 60 | -keep class android.support.annotation.Keep 61 | 62 | -keep @android.support.annotation.Keep class * {*;} 63 | 64 | -keepclasseswithmembers class * { 65 | @android.support.annotation.Keep ; 66 | } 67 | 68 | -keepclasseswithmembers class * { 69 | @android.support.annotation.Keep ; 70 | } 71 | 72 | -keepclasseswithmembers class * { 73 | @android.support.annotation.Keep (...); 74 | } 75 | 76 | # Some important configuration is based on the annotations in the code. 77 | # We have to specify what the annotations mean to ProGuard. 78 | -------------------------------------------------------------------------------- /gradle/proguard/proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | 22 | # Some important configuration is based on the annotations in the code. 23 | # We have to specify what the annotations mean to ProGuard. 24 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SnowdreamFramework/ToyBricks/4691bf6def006ef0bf191ec239058c7f53722de9/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Dec 28 10:00:20 PST 2015 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /lib/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /lib/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'eclipse' 2 | apply plugin: 'idea' 3 | apply from: "${rootDir}/gradle/plugins/android-library.gradle" 4 | apply from: "${rootDir}/gradle/plugins/android-bintray-push.gradle" 5 | 6 | kapt { 7 | generateStubs = true 8 | } 9 | 10 | dependencies { 11 | compile "com.github.snowdream.toybricks:annotation:0.9.10" 12 | 13 | kapt "com.github.snowdream.toybricks:processor:0.9.10" 14 | //annotationProcessor "com.github.snowdream.toybricks:processor:0.9.10" 15 | } 16 | 17 | apply plugin: 'com.github.snowdream.toybricks' -------------------------------------------------------------------------------- /lib/gradle.properties: -------------------------------------------------------------------------------- 1 | PACKAGE_NAME=com.github.snowdream.toybricks 2 | POM_GROUP_ID=com.github.snowdream 3 | POM_ARTIFACT_ID=toybricks 4 | POM_NAME=toybricks 5 | POM_PACKAGING=aar 6 | -------------------------------------------------------------------------------- /lib/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/snowdream/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | 20 | #保留InterfaceLoader及其子类不被混淆 21 | -keep class * implements com.github.snowdream.toybricks.annotation.InterfaceLoader{*;} 22 | 23 | # @Interface and @Implementation specifies not to shrink, optimize, or obfuscate the annotated class 24 | # or class member as an entry point. 25 | -dontwarn org.jetbrains.annotations.** 26 | -dontwarn com.github.snowdream.toybricks.annotation.** 27 | -keep class com.github.snowdream.toybricks.annotation.** 28 | -keep @com.github.snowdream.toybricks.annotation.Interface class * 29 | -keep @com.github.snowdream.toybricks.annotation.Implementation class * 30 | -------------------------------------------------------------------------------- /lib/src/androidTest/java/com/github/snowdream/toybricks/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.github.snowdream.toybricks; 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 | * Instrumentation 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() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.github.snowdream.toybricks.test", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /lib/src/main/kotlin/com/github/snowdream/toybricks/ToyBricks.kt: -------------------------------------------------------------------------------- 1 | package com.github.snowdream.toybricks 2 | 3 | import com.github.snowdream.toybricks.annotation.InterfaceLoader 4 | import com.github.snowdream.toybricks.annotation.impl.DefaultInterfaceLoader 5 | 6 | /** 7 | * Created by snowdream on 17/2/10. 8 | */ 9 | class ToyBricks { 10 | 11 | companion object{ 12 | //Default InterfaceLoader 13 | @JvmField var sDefaultInterfaceLoader: InterfaceLoader = DefaultInterfaceLoader() 14 | 15 | //NewI InterfaceLoader 16 | @JvmField var sNewInterfaceLoader: InterfaceLoader ?= sDefaultInterfaceLoader.getImplementation(InterfaceLoader::class.java) 17 | 18 | @JvmStatic @Synchronized fun getImplementation(clazz: Class): T { 19 | var implementation: T? 20 | 21 | implementation = sNewInterfaceLoader?.getImplementation(clazz) 22 | 23 | if (implementation == null) { 24 | implementation = sDefaultInterfaceLoader.getImplementation(clazz) 25 | } 26 | 27 | return implementation!! 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /lib/src/main/kotlin/com/github/snowdream/toybricks/annotation/impl/DefaultInterfaceLoader.kt: -------------------------------------------------------------------------------- 1 | package com.github.snowdream.toybricks.annotation.impl 2 | 3 | import com.github.snowdream.toybricks.annotation.InterfaceLoader 4 | 5 | /** 6 | * Created by snowdream on 17/2/10. 7 | */ 8 | class DefaultInterfaceLoader : InterfaceLoader { 9 | 10 | @Suppress("UNCHECKED_CAST") 11 | override fun getImplementation(clazz: Class): T? { 12 | var implementation: T? = null 13 | 14 | val implClass: Class 15 | 16 | val pn = clazz.`package`.name 17 | val sn = clazz.simpleName 18 | 19 | val className: String 20 | if (sn.startsWith("Interface")) { 21 | className = pn + ".impl." + sn + "Impl" 22 | } else { 23 | className = pn + ".impl." + upperName(sn.substring(1)) + "Impl" 24 | } 25 | 26 | try { 27 | implClass = Class.forName(className) as Class 28 | 29 | implementation = implClass.newInstance() as T 30 | } catch (e: ClassNotFoundException) { 31 | e.printStackTrace() 32 | } catch (e: IllegalAccessException) { 33 | e.printStackTrace() 34 | } catch (e: InstantiationException) { 35 | e.printStackTrace() 36 | } 37 | 38 | return implementation 39 | } 40 | 41 | /** 42 | * change the first character to UpperCase 43 | */ 44 | private fun upperName(name: String): String { 45 | val upperName = name.substring(0, 1).toUpperCase() + name.substring(1) 46 | return upperName 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /lib/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Lib 3 | 4 | -------------------------------------------------------------------------------- /lib/src/test/java/com/github/snowdream/toybricks/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.github.snowdream.toybricks; 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() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /plugin/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'eclipse' 2 | apply plugin: 'idea' 3 | apply from: "${rootDir}/gradle/plugins/java-groovy-library.gradle" 4 | 5 | buildscript { 6 | repositories { 7 | maven { url 'http://maven.aliyun.com/nexus/content/groups/public' } 8 | jcenter { url "http://jcenter.bintray.com/"} 9 | maven { url "http://repo1.maven.org/maven2"} 10 | } 11 | } 12 | 13 | dependencies { 14 | compile "com.github.snowdream.toybricks:annotation:0.9.10" 15 | 16 | compile 'com.squareup:javapoet:1.8.0' 17 | } -------------------------------------------------------------------------------- /plugin/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_GROUP_ID=com.github.snowdream.toybricks 2 | POM_ARTIFACT_ID=android-toybricks-gradle-plugin 3 | POM_NAME=android-toybricks-gradle-plugin 4 | POM_PACKAGING=jar 5 | -------------------------------------------------------------------------------- /plugin/src/main/groovy/com/github/snowdream/toybricks/plugin/ToyBricksJsonEntity.groovy: -------------------------------------------------------------------------------- 1 | package com.github.snowdream.toybricks.plugin 2 | 3 | 4 | /** 5 | * Created by snowdream on 17/3/12. 6 | * @author snowdream 7 | * @date 2017/03/12 8 | */ 9 | class ToyBricksJsonEntity { 10 | public File library 11 | 12 | public List interfaceList 13 | 14 | public Map globalImplementation 15 | 16 | public Map defaultImplementation 17 | 18 | public List singletonImplementation 19 | 20 | } 21 | -------------------------------------------------------------------------------- /plugin/src/main/groovy/com/github/snowdream/toybricks/plugin/ToybricksPlugin.groovy: -------------------------------------------------------------------------------- 1 | package com.github.snowdream.toybricks.plugin 2 | 3 | import org.gradle.api.Plugin 4 | import org.gradle.api.Project 5 | import org.gradle.api.Task 6 | import org.gradle.api.tasks.Copy 7 | import org.gradle.api.tasks.StopExecutionException 8 | import org.gradle.api.tasks.compile.JavaCompile 9 | 10 | /** 11 | * Created by snowdream on 17/3/8. 12 | * @author snowdream 13 | * @date 2017/03/08 14 | */ 15 | class ToybricksPlugin implements Plugin { 16 | private static final String PLUGIN_ANDROID_APP = "com.android.application" 17 | private static final String PLUGIN_ANDROID_LIBRARY = "com.android.library" 18 | private static final String PLUGIN_ANDROID_KOTLIN = "kotlin-android" 19 | 20 | private static final int CONFIGURATION_TYPE_APT = 0 //java 21 | private static final int CONFIGURATION_TYPE_KAPT = 1 //kotlin 22 | 23 | 24 | private Project project 25 | 26 | private int type = CONFIGURATION_TYPE_APT 27 | 28 | void apply(Project project) { 29 | this.project = project 30 | 31 | checkEnvironment() 32 | 33 | checkConfigurationType() 34 | 35 | if (hasPlugin(PLUGIN_ANDROID_APP)){ 36 | createAndroidAppTasks() 37 | } 38 | 39 | if (hasPlugin(PLUGIN_ANDROID_LIBRARY)) { 40 | createAndroidLibraryTasks() 41 | } 42 | } 43 | 44 | /** 45 | * check environment 46 | */ 47 | def checkEnvironment() { 48 | if (!hasPlugin(PLUGIN_ANDROID_APP) && !hasPlugin(PLUGIN_ANDROID_LIBRARY) ) { 49 | throw new StopExecutionException( 50 | "Must be applied after 'com.android.application' or 'com.android.library' plugin.") 51 | } 52 | } 53 | 54 | /** 55 | * check configuration type 56 | */ 57 | def checkConfigurationType() { 58 | if (!project.configurations.annotationProcessor.isEmpty()){ 59 | type = CONFIGURATION_TYPE_APT 60 | }else if (!project.configurations.kapt.isEmpty()){ 61 | type = CONFIGURATION_TYPE_KAPT 62 | }else { 63 | type = CONFIGURATION_TYPE_APT 64 | } 65 | } 66 | 67 | /** 68 | * hasPlugin 69 | * 70 | * @param name plugin name 71 | * @return 72 | */ 73 | private boolean hasPlugin(String name) { 74 | return project.plugins.hasPlugin(name) 75 | } 76 | 77 | /** 78 | * create tasks for android app 79 | * 80 | * @param project 81 | * @return 82 | */ 83 | def createAndroidAppTasks() { 84 | project.android.applicationVariants.all { variant -> 85 | def variantCapitalizeName = "${variant.name}".capitalize() 86 | 87 | //see: https://bitbucket.org/qbusict/android-gradle-scripts/src/60394ba8f5efa64badb17c9388f38b89f09c5d9a/annotations.groovy 88 | def aptOutputDir 89 | if (type == CONFIGURATION_TYPE_KAPT) { 90 | aptOutputDir = project.file(new File("${project.buildDir}", "generated/source/kapt/${variant.name}")) 91 | }else{ 92 | aptOutputDir = project.file(new File("${project.buildDir}", "generated/source/apt/${variant.dirName}")) 93 | } 94 | 95 | project.android.sourceSets["${variant.name}"].java.srcDirs += aptOutputDir.getPath() 96 | 97 | project.task("process${variantCapitalizeName}ToyBricksJsonFile", type: ToybricksTask) { 98 | description "Merge ToyBricks.json from dependencies into one, Then generate java source file: InterfaceLoaderImpl.java." 99 | 100 | dependencies = project.configurations.compile 101 | 102 | isKotlinAndroidProject = hasPlugin(PLUGIN_ANDROID_KOTLIN) 103 | 104 | if (type == CONFIGURATION_TYPE_KAPT) { 105 | outputDirs = project.files(new File("${project.buildDir}", "generated/source/kapt/${variant.name}")) 106 | }else{ 107 | outputDirs = project.files(new File("${project.buildDir}", "generated/source/apt/${variant.dirName}")) 108 | } 109 | } 110 | 111 | project.tasks["process${variantCapitalizeName}ToyBricksJsonFile"].dependsOn(project.tasks["compile${variantCapitalizeName}JavaWithJavac"]) 112 | project.tasks["compile${variantCapitalizeName}JavaWithJavac"].finalizedBy(project.tasks["process${variantCapitalizeName}ToyBricksJsonFile"]) 113 | 114 | Task task = project.tasks["compile${variantCapitalizeName}JavaWithJavac"] 115 | if (task != null && task instanceof JavaCompile) { 116 | JavaCompile javaCompileTask = task as JavaCompile 117 | 118 | project.task("compile${variantCapitalizeName}ToyBricksGeneratedSources", type: JavaCompile) { 119 | destinationDir javaCompileTask.getDestinationDir() 120 | sourceCompatibility javaCompileTask.getSourceCompatibility() 121 | targetCompatibility javaCompileTask.getTargetCompatibility() 122 | classpath = variant.javaCompile.classpath 123 | classpath += javaCompileTask.getOutputs().getFiles() 124 | dependencyCacheDir javaCompileTask.getDependencyCacheDir() 125 | //options = javaCompileTask.getOptions() 126 | toolChain = javaCompileTask.getToolChain() 127 | includes = javaCompileTask.getIncludes() 128 | excludes = javaCompileTask.getExcludes() 129 | //source = variant.javaCompile.source 130 | source = aptOutputDir.getPath() 131 | } 132 | 133 | project.tasks["compile${variantCapitalizeName}ToyBricksGeneratedSources"].dependsOn(project.tasks["process${variantCapitalizeName}ToyBricksJsonFile"]) 134 | project.tasks["process${variantCapitalizeName}ToyBricksJsonFile"].finalizedBy(project.tasks["compile${variantCapitalizeName}ToyBricksGeneratedSources"]) 135 | 136 | project.tasks["transformClassesWithDexFor${variantCapitalizeName}"].dependsOn(project.tasks["compile${variantCapitalizeName}ToyBricksGeneratedSources"]) 137 | } 138 | 139 | // def isKotlinAndroidProject = hasPlugin(PLUGIN_ANDROID_KOTLIN) 140 | // if (isKotlinAndroidProject){ 141 | // project.tasks["compile${variantCapitalizeName}Kotlin"].dependsOn(project.tasks["process${variantCapitalizeName}ToyBricksJsonFile"]) 142 | // }else{ 143 | // project.tasks["compile${variantCapitalizeName}Java"].dependsOn(project.tasks["process${variantCapitalizeName}ToyBricksJsonFile"]) 144 | // } 145 | } 146 | } 147 | 148 | /** 149 | * create tasks for android library 150 | * 151 | * @param project 152 | * @return 153 | */ 154 | def createAndroidLibraryTasks() { 155 | project.android.libraryVariants.all { variant -> 156 | def variantCapitalizeName = "${variant.name}".capitalize() 157 | 158 | project.task("copy${variantCapitalizeName}ToyBricksJsonFile", type: Copy) { 159 | if (type == CONFIGURATION_TYPE_KAPT){ 160 | from "${project.buildDir}/generated/source/kapt/${variant.name}" 161 | }else { 162 | from "${project.buildDir}/generated/source/apt/${variant.name}" 163 | } 164 | into "${project.buildDir}/intermediates/bundles/${variant.dirName}" 165 | } 166 | project.tasks["bundle${variantCapitalizeName}"].dependsOn(project.tasks["copy${variantCapitalizeName}ToyBricksJsonFile"]) 167 | project.tasks["copy${variantCapitalizeName}ToyBricksJsonFile"].dependsOn(project.tasks["transformClassesAndResourcesWithSyncLibJarsFor${variantCapitalizeName}"]) 168 | project.tasks["transformClassesAndResourcesWithSyncLibJarsFor${variantCapitalizeName}"].finalizedBy(project.tasks["copy${variantCapitalizeName}ToyBricksJsonFile"]) 169 | } 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /plugin/src/main/groovy/com/github/snowdream/toybricks/plugin/ToybricksTask.groovy: -------------------------------------------------------------------------------- 1 | package com.github.snowdream.toybricks.plugin 2 | 3 | import com.github.snowdream.toybricks.annotation.Implementation 4 | import com.squareup.javapoet.* 5 | import groovy.json.JsonException 6 | import groovy.json.JsonSlurper 7 | import org.gradle.api.DefaultTask 8 | import org.gradle.api.file.FileCollection 9 | import org.gradle.api.tasks.Input 10 | import org.gradle.api.tasks.InputFiles 11 | import org.gradle.api.tasks.OutputDirectories 12 | import org.gradle.api.tasks.OutputDirectory 13 | import org.gradle.api.tasks.SkipWhenEmpty 14 | import org.gradle.api.tasks.TaskAction 15 | import org.gradle.api.tasks.StopExecutionException 16 | 17 | import com.github.snowdream.toybricks.annotation.InterfaceLoader 18 | 19 | import javax.lang.model.element.Modifier 20 | import java.util.zip.ZipFile 21 | 22 | /** 23 | * Created by snowdream on 17/3/8. 24 | * @author snowdream 25 | * @date 2017/03/08 26 | */ 27 | class ToybricksTask extends DefaultTask { 28 | private static final String ToyBricksJsonFileName = "ToyBricks.json" 29 | 30 | @Input 31 | boolean isKotlinAndroidProject 32 | 33 | /** 34 | * The input dependencies. 35 | */ 36 | @InputFiles 37 | @SkipWhenEmpty 38 | FileCollection dependencies 39 | 40 | /** 41 | * The output directory. 42 | */ 43 | @OutputDirectories 44 | FileCollection outputDirs 45 | 46 | List list = new ArrayList<>() 47 | 48 | ToyBricksJsonEntity merged = new ToyBricksJsonEntity() 49 | 50 | @TaskAction 51 | main() { 52 | initMergedToyBricksJson() 53 | parseToyBricksJson() 54 | checkToyBricksJson() 55 | mergeToyBricksJson() 56 | generateJavaFile() 57 | } 58 | 59 | def initMergedToyBricksJson() { 60 | merged.interfaceList = new ArrayList<>() 61 | merged.singletonImplementation = new ArrayList<>() 62 | merged.globalImplementation = new HashMap<>() 63 | merged.defaultImplementation = new HashMap<>() 64 | } 65 | 66 | def parseToyBricksJson() { 67 | //parse current project ToyBricks.json 68 | def jsonSlurper = new JsonSlurper() 69 | 70 | def currentEntity 71 | outputDirs.each { File outputDir -> 72 | if (currentEntity == null) { 73 | def currentToyBricksJson = new File(outputDir, "ToyBricks.json") 74 | 75 | if (currentToyBricksJson.exists() && currentToyBricksJson.canRead()) { 76 | currentEntity = jsonSlurper.parse(currentToyBricksJson) as ToyBricksJsonEntity 77 | } 78 | } 79 | } 80 | 81 | if (currentEntity != null){ 82 | list.add(currentEntity) 83 | }else{ 84 | println "There is no ToyBricks.json in the current project." 85 | } 86 | 87 | //parse dependencies ToyBricks.json 88 | dependencies.each { File file -> 89 | String content = getToyBricksJsonContentFromZip(file) 90 | //println content 91 | 92 | if (content != null && !content.isEmpty()) { 93 | try { 94 | def entity = jsonSlurper.parseText(content) as ToyBricksJsonEntity 95 | entity.library = file 96 | list.add(entity) 97 | } catch (JsonException exception) { 98 | exception.printStackTrace() 99 | } 100 | } 101 | } 102 | 103 | //merge interface 104 | if (!list.isEmpty()){ 105 | for(ToyBricksJsonEntity entity : list){ 106 | for (String interfaceName: entity.interfaceList){ 107 | if (interfaceName == null || interfaceName == "") { 108 | continue 109 | } 110 | 111 | if (merged.interfaceList.contains(interfaceName)){ 112 | continue 113 | } 114 | 115 | merged.interfaceList.add(interfaceName) 116 | } 117 | } 118 | } 119 | } 120 | 121 | def checkToyBricksJson(){ 122 | def interfaceList = merged.interfaceList 123 | 124 | if (interfaceList.isEmpty()){ 125 | return 126 | } 127 | 128 | for (String interfaceName : interfaceList){ 129 | def hasImplementation = false 130 | def hasGlobalImplementation = false 131 | def globalImplementation 132 | def hasDefaultImplementation = false 133 | def defaultImplementation 134 | 135 | for(ToyBricksJsonEntity entity : list){ 136 | 137 | for (Map.Entry entry : entity.globalImplementation.entrySet()) { 138 | def _interfaceName = entry.key 139 | def _implementation = entry.value 140 | 141 | if (interfaceName.equalsIgnoreCase(_interfaceName) && _implementation != null && _implementation != ""){ 142 | if (hasGlobalImplementation){ 143 | throw new StopExecutionException( 144 | "Conflict: The class ${_implementation} is annotated with @${Implementation.class.simpleName} with interface ${interfaceName}, but ${globalImplementation} already uses the same interface") 145 | }else{ 146 | hasImplementation = true 147 | hasGlobalImplementation = true 148 | globalImplementation = _implementation 149 | } 150 | } 151 | } 152 | 153 | for (Map.Entry entry : entity.defaultImplementation.entrySet()) { 154 | def _interfaceName = entry.key 155 | def _implementation = entry.value 156 | 157 | if (interfaceName.equalsIgnoreCase(_interfaceName) && _implementation != null && _implementation != ""){ 158 | if (hasDefaultImplementation){ 159 | throw new StopExecutionException( 160 | "Conflict: The class ${_implementation} is annotated with @${Implementation.class.simpleName} with interface ${interfaceName}, but ${defaultImplementation} already uses the same interface") 161 | }else{ 162 | hasImplementation = true 163 | hasDefaultImplementation = true 164 | defaultImplementation = _implementation 165 | } 166 | } 167 | } 168 | } 169 | 170 | if (!hasImplementation){ 171 | throw new StopExecutionException( 172 | "Error: The interface ${interfaceName} has no Implementation.") 173 | } 174 | } 175 | } 176 | 177 | 178 | def mergeToyBricksJson() { 179 | for(ToyBricksJsonEntity entity : list){ 180 | merged.globalImplementation.putAll(entity.globalImplementation) 181 | merged.defaultImplementation.putAll(entity.defaultImplementation) 182 | merged.singletonImplementation.addAll(entity.singletonImplementation) 183 | } 184 | } 185 | 186 | /** 187 | * generate java file 188 | */ 189 | def generateJavaFile() { 190 | def interfaceList = merged.interfaceList 191 | def globalImplementationMap = merged.globalImplementation 192 | def defaultImplementationMap = merged.defaultImplementation 193 | def singletonImplementationList = merged.singletonImplementation 194 | 195 | if (interfaceList.isEmpty() && 196 | globalImplementationMap.isEmpty() && 197 | defaultImplementationMap.isEmpty()) { 198 | return 199 | } 200 | 201 | def clazz = InterfaceLoader.class 202 | def pn =clazz.package.name 203 | def sn = clazz.simpleName 204 | 205 | def packageName = pn + ".impl" 206 | def className = sn + "Impl" 207 | 208 | try { 209 | //private static HashMap sSingletonMap = new HashMap(); 210 | def classTypeVariableName = TypeVariableName.get("Class") 211 | def objectTypeVariableName = TypeVariableName.get("Object") 212 | def hashMapClzName = ClassName.get(HashMap.class) 213 | 214 | 215 | def singletonMapParameterizedTypeName = ParameterizedTypeName.get(hashMapClzName, classTypeVariableName, objectTypeVariableName) 216 | 217 | def singletonMap = FieldSpec.builder(singletonMapParameterizedTypeName, "sSingletonMap") 218 | .addModifiers(Modifier.PRIVATE, Modifier.STATIC) 219 | .initializer("new \$T()", singletonMapParameterizedTypeName) 220 | .build() 221 | 222 | // private static HashMap sGlobalMap= new HashMap<>(); 223 | def implementationParameterizedTypeName = ParameterizedTypeName.get(hashMapClzName, classTypeVariableName, classTypeVariableName) 224 | 225 | def globalMap = FieldSpec.builder(implementationParameterizedTypeName, "sGlobalMap") 226 | .addModifiers(Modifier.PRIVATE, Modifier.STATIC) 227 | .initializer("new \$T()", implementationParameterizedTypeName) 228 | .build() 229 | 230 | // private static HashMap sDefaultMap= new HashMap<>(); 231 | def defaultMap = FieldSpec.builder(implementationParameterizedTypeName, "sDefaultMap") 232 | .addModifiers(Modifier.PRIVATE, Modifier.STATIC) 233 | .initializer("new \$T()", implementationParameterizedTypeName) 234 | .build() 235 | 236 | // public NewInterfaceLoader() 237 | def constructorMethodSpec = MethodSpec.constructorBuilder() 238 | .addModifiers(Modifier.PUBLIC) 239 | .addStatement("addGlobalMap()") 240 | .addStatement("addDefaultMap()") 241 | .addStatement("addSingletonMap()") 242 | .build() 243 | 244 | // private void addGlobalMap() 245 | def globalMapMethodSpecBuilder = MethodSpec.methodBuilder("addGlobalMap") 246 | .addModifiers(Modifier.PRIVATE) 247 | 248 | for (Map.Entry entry : globalImplementationMap.entrySet()) { 249 | def interfaceName = entry.key 250 | def qualifiedName = entry.value 251 | 252 | globalMapMethodSpecBuilder.addStatement("sGlobalMap.put(\$L.class,\$L.class)", interfaceName, qualifiedName) 253 | } 254 | 255 | 256 | def globalMapMethodSpec = globalMapMethodSpecBuilder.build() 257 | 258 | // private void addDefaultMap() 259 | def defaultMapMethodSpecBuilder = MethodSpec.methodBuilder("addDefaultMap") 260 | .addModifiers(Modifier.PRIVATE) 261 | 262 | for (Map.Entry entry : defaultImplementationMap.entrySet()) { 263 | def interfaceName = entry.key 264 | def qualifiedName = entry.value 265 | 266 | defaultMapMethodSpecBuilder.addStatement("sDefaultMap.put(\$L.class,\$L.class)", interfaceName, qualifiedName) 267 | } 268 | 269 | def defaultMapMethodSpec = defaultMapMethodSpecBuilder.build() 270 | 271 | // private void addSingletonMap() 272 | def singletonMapMethodSpecBuilder = MethodSpec.methodBuilder("addSingletonMap") 273 | .addModifiers(Modifier.PRIVATE) 274 | 275 | for (String qualifiedName : singletonImplementationList){ 276 | singletonMapMethodSpecBuilder.addStatement("sSingletonMap.put(\$L.class,null)", qualifiedName) 277 | } 278 | 279 | def singletonMapMethodSpec = singletonMapMethodSpecBuilder.build() 280 | 281 | //public T getImplementation(Class clazz) 282 | def typeVariableName = TypeVariableName.get("T") 283 | def classClzName = ClassName.get(Class.class) 284 | 285 | def parameterizedTypeName = ParameterizedTypeName.get(classClzName, typeVariableName) 286 | def getImplementationMethodSpec = MethodSpec.methodBuilder("getImplementation") 287 | .addAnnotation(Override.class) 288 | .addModifiers(Modifier.PUBLIC) 289 | .returns(typeVariableName) 290 | .addTypeVariable(typeVariableName) 291 | .addParameter(parameterizedTypeName, "clazz") 292 | .addStatement("T implementation = null") 293 | .addCode("\n") 294 | .addStatement("boolean isSingleton = false") 295 | .addCode("\n") 296 | .addStatement("Class implClass") 297 | .addCode("\n") 298 | .addStatement("implClass = sGlobalMap.get(clazz)") 299 | .addCode("\n") 300 | .addCode(CodeBlock.builder() 301 | .beginControlFlow("if (implClass == null)") 302 | .addStatement("implClass = sDefaultMap.get(clazz)") 303 | .endControlFlow() 304 | .build()) 305 | .addCode("\n") 306 | .addCode(CodeBlock.builder() 307 | .beginControlFlow("if (implClass != null)") 308 | .addStatement("isSingleton = sSingletonMap.containsKey(implClass)") 309 | .add("\n") 310 | .add(CodeBlock.builder() 311 | .beginControlFlow("if (isSingleton)") 312 | .addStatement("implementation = (T) sSingletonMap.get(implClass)") 313 | .add(CodeBlock.builder() 314 | .beginControlFlow("if (implementation != null)") 315 | .addStatement("return implementation") 316 | .endControlFlow() 317 | .build()) 318 | .endControlFlow() 319 | .build()) 320 | .add("\n") 321 | .add(CodeBlock.builder() 322 | .beginControlFlow("try") 323 | .addStatement("implementation = (T) implClass.newInstance()") 324 | .nextControlFlow("catch (InstantiationException e)") 325 | .addStatement("e.printStackTrace()") 326 | .nextControlFlow("catch (IllegalAccessException e)") 327 | .addStatement("e.printStackTrace()") 328 | .endControlFlow() 329 | .build() 330 | ) 331 | .add("\n") 332 | .add(CodeBlock.builder() 333 | .beginControlFlow("if (isSingleton && implementation != null)") 334 | .addStatement("sSingletonMap.put(implClass, implementation)") 335 | .endControlFlow() 336 | .build() 337 | ) 338 | .endControlFlow() 339 | .build()) 340 | .addCode("\n") 341 | .addStatement("return implementation") 342 | .build() 343 | 344 | def typeSpec = TypeSpec.classBuilder(className)//HelloWorld是类名 345 | .addJavadoc("\n") 346 | .addJavadoc("Created by snowdream") 347 | .addJavadoc("\n") 348 | .addJavadoc("\n") 349 | .addJavadoc("This file is automatically generated by apt(Annotation Processing Tool)") 350 | .addJavadoc("\n") 351 | .addJavadoc("Do not modify this file -- YOUR CHANGES WILL BE ERASED!") 352 | .addJavadoc("\n") 353 | .addJavadoc("\n") 354 | .addJavadoc("This file should *NOT* be checked into Version Control Systems,") 355 | .addJavadoc("\n") 356 | .addJavadoc("as it contains information specific to your local configuration.") 357 | .addJavadoc("\n") 358 | .addModifiers(Modifier.FINAL) 359 | .addSuperinterface(InterfaceLoader.class) 360 | .addField(singletonMap) 361 | .addField(globalMap) 362 | .addField(defaultMap) 363 | .addMethod(constructorMethodSpec) 364 | .addMethod(globalMapMethodSpec) 365 | .addMethod(defaultMapMethodSpec) 366 | .addMethod(singletonMapMethodSpec) 367 | .addMethod(getImplementationMethodSpec) 368 | .build() 369 | 370 | def javaFile = JavaFile.builder(packageName, typeSpec) 371 | .build() 372 | 373 | outputDirs.each { File outputDir -> 374 | javaFile.writeTo(outputDir) 375 | println "${typeSpec.name}.java has been generated in ${outputDir}." 376 | } 377 | } catch (IOException e) { 378 | e.printStackTrace() 379 | } 380 | } 381 | 382 | /** 383 | * get ToyBricksJson Content From AAR or JAR 384 | * 385 | * @param file 386 | * @return 387 | */ 388 | static String getToyBricksJsonContentFromZip(File file) { 389 | //println file.absolutePath 390 | 391 | def content = "" 392 | 393 | if (file.exists() && file.canRead()){ 394 | def zipFile = new ZipFile(file) 395 | 396 | zipFile.entries().findAll { ToyBricksJsonFileName.equalsIgnoreCase(it.name) }.each { 397 | content = zipFile.getInputStream(it).text 398 | } 399 | } 400 | return content 401 | } 402 | } -------------------------------------------------------------------------------- /plugin/src/main/resources/META-INF/gradle-plugins/com.github.snowdream.toybricks.properties: -------------------------------------------------------------------------------- 1 | implementation-class=com.github.snowdream.toybricks.plugin.ToybricksPlugin 2 | -------------------------------------------------------------------------------- /processor/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'eclipse' 2 | apply plugin: 'idea' 3 | apply from: "${rootDir}/gradle/plugins/java-kotlin-library.gradle" 4 | 5 | 6 | dependencies { 7 | compile "com.github.snowdream.toybricks:annotation:0.9.10" 8 | 9 | compile "com.fasterxml.jackson.module:jackson-module-kotlin:2.8.7" 10 | compile 'com.squareup:javapoet:1.8.0' 11 | kapt 'com.google.auto.service:auto-service:1.0-rc2' 12 | compile 'com.google.auto.service:auto-service:1.0-rc2' 13 | } 14 | -------------------------------------------------------------------------------- /processor/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_GROUP_ID=com.github.snowdream.toybricks 2 | POM_ARTIFACT_ID=processor 3 | POM_NAME=processor 4 | POM_PACKAGING=jar 5 | -------------------------------------------------------------------------------- /processor/src/main/kotlin/com/github/snowdream/toybricks/processor/BaseAnnotatedClass.kt: -------------------------------------------------------------------------------- 1 | package com.github.snowdream.toybricks.processor 2 | 3 | import javax.lang.model.element.TypeElement 4 | 5 | /** 6 | * Created by snowdream on 17/2/12. 7 | */ 8 | abstract class BaseAnnotatedClass { 9 | 10 | protected lateinit var annotatedClassElement: TypeElement 11 | 12 | /** 13 | 14 | */ 15 | @Throws(ProcessingException::class) 16 | abstract fun checkValid(processorManager: ProcessorManager) 17 | } 18 | -------------------------------------------------------------------------------- /processor/src/main/kotlin/com/github/snowdream/toybricks/processor/BaseContainerHandler.kt: -------------------------------------------------------------------------------- 1 | package com.github.snowdream.toybricks.processor 2 | 3 | /** 4 | * Created by snowdream on 17/2/12. 5 | */ 6 | abstract class BaseContainerHandler : Handler 7 | -------------------------------------------------------------------------------- /processor/src/main/kotlin/com/github/snowdream/toybricks/processor/Handler.kt: -------------------------------------------------------------------------------- 1 | package com.github.snowdream.toybricks.processor 2 | 3 | /** 4 | * Created by snowdream on 17/2/12. 5 | */ 6 | 7 | import javax.annotation.processing.RoundEnvironment 8 | 9 | /** 10 | * Description: The main base-level handler for performing some action 11 | */ 12 | internal interface Handler { 13 | 14 | /** 15 | * Called when the process of the [ToyBricksProcessor] is called 16 | 17 | * @param processorManager The manager that holds processing information 18 | * * * 19 | * * 20 | * @param roundEnvironment The round environment 21 | */ 22 | fun handle(processorManager: ProcessorManager, roundEnvironment: RoundEnvironment) 23 | } -------------------------------------------------------------------------------- /processor/src/main/kotlin/com/github/snowdream/toybricks/processor/ImplementationAnnotatedClass.kt: -------------------------------------------------------------------------------- 1 | package com.github.snowdream.toybricks.processor 2 | 3 | import com.github.snowdream.toybricks.annotation.Implementation 4 | 5 | import javax.lang.model.element.* 6 | import javax.lang.model.type.DeclaredType 7 | import javax.lang.model.type.MirroredTypeException 8 | import javax.lang.model.type.TypeKind 9 | import javax.lang.model.type.TypeMirror 10 | import javax.lang.model.util.Elements 11 | import javax.lang.model.util.Types 12 | 13 | /** 14 | * Created by snowdream on 17/2/12. 15 | */ 16 | class ImplementationAnnotatedClass @Throws(ProcessingException::class) 17 | constructor(classElement: TypeElement) : BaseAnnotatedClass() { 18 | 19 | /** 20 | * Get the full qualified name of the type specified in [Implementation.value]. 21 | 22 | * @return qualified name 23 | */ 24 | var qualifiedInterfaceClassName: String? = null 25 | private set 26 | /** 27 | * Get the simple name of the type specified in [Implementation.value]. 28 | 29 | * @return qualified name 30 | */ 31 | var simpleInterfaceName: String? = null 32 | private set 33 | 34 | var isGolbal = false 35 | var isSingleton = false 36 | 37 | init { 38 | this.annotatedClassElement = classElement 39 | val annotation = classElement.getAnnotation(Implementation::class.java) 40 | 41 | 42 | isGolbal = annotation.global 43 | 44 | isSingleton = annotation.singleton 45 | 46 | // Get the full QualifiedTypeName 47 | try { 48 | val interfaceClass = annotation.value 49 | qualifiedInterfaceClassName = interfaceClass.qualifiedName 50 | simpleInterfaceName = interfaceClass.simpleName 51 | } catch (mte: MirroredTypeException) { 52 | val classTypeMirror = mte.typeMirror as DeclaredType 53 | val classTypeElement = classTypeMirror.asElement() as TypeElement 54 | qualifiedInterfaceClassName = classTypeElement.qualifiedName.toString() 55 | simpleInterfaceName = classTypeElement.simpleName.toString() 56 | } 57 | 58 | } 59 | 60 | /** 61 | * The original element that was annotated with @Implementation 62 | */ 63 | val typeElement: TypeElement 64 | get() = annotatedClassElement 65 | 66 | @Throws(ProcessingException::class) 67 | override fun checkValid(processorManager: ProcessorManager) { 68 | val typeUtils = processorManager.typeUtils 69 | val elementUtils = processorManager.elementUtils 70 | 71 | // Cast to TypeElement, has more type specific methods 72 | val classElement = annotatedClassElement 73 | 74 | if (!classElement.modifiers.contains(Modifier.PUBLIC)) { 75 | throw ProcessingException(classElement, "The class %s is not public.", 76 | classElement.qualifiedName.toString()) 77 | } 78 | 79 | // Check if it's an abstract class 80 | if (classElement.modifiers.contains(Modifier.ABSTRACT)) { 81 | throw ProcessingException(classElement, 82 | "The class %s is abstract. You can't annotate abstract classes with @%s", 83 | classElement.qualifiedName.toString(), Implementation::class.java.simpleName) 84 | } 85 | 86 | // Check inheritance: Class must be childclass as specified in @Factory.type(); 87 | val superClassElement = elementUtils.getTypeElement(qualifiedInterfaceClassName) 88 | if (superClassElement.kind == ElementKind.INTERFACE) { 89 | // Check interface implemented 90 | var isImplemented = false 91 | 92 | for (classElementInterface in classElement.interfaces){ 93 | if (classElementInterface.toString().equals(superClassElement.asType().toString())){ 94 | isImplemented = true 95 | break 96 | } 97 | } 98 | 99 | if (!isImplemented) { 100 | throw ProcessingException(classElement, 101 | "The class %s annotated with @%s must implement the interface %s", 102 | classElement.qualifiedName.toString(), Implementation::class.java.simpleName, 103 | qualifiedInterfaceClassName) 104 | } 105 | } else { 106 | // Check subclassing 107 | var currentClass = classElement 108 | while (true) { 109 | val superClassType = currentClass.superclass 110 | 111 | if (superClassType.kind == TypeKind.NONE) { 112 | // Basis class (java.lang.Object) reached, so exit 113 | throw ProcessingException(classElement, 114 | "The class %s annotated with @%s must inherit from %s", 115 | classElement.qualifiedName.toString(), Implementation::class.java.simpleName, 116 | qualifiedInterfaceClassName) 117 | } 118 | 119 | if (superClassType.toString() == qualifiedInterfaceClassName) { 120 | // Required super class found 121 | break 122 | } 123 | 124 | // Moving up in inheritance tree 125 | currentClass = typeUtils.asElement(superClassType) as TypeElement 126 | } 127 | } 128 | 129 | // Check if an empty public constructor is given 130 | for (enclosed in classElement.enclosedElements) { 131 | if (enclosed.kind == ElementKind.CONSTRUCTOR) { 132 | val constructorElement = enclosed as ExecutableElement 133 | if (constructorElement.parameters.size == 0 && constructorElement.modifiers 134 | .contains(Modifier.PUBLIC)) { 135 | // Found an empty constructor 136 | return 137 | } 138 | } 139 | } 140 | 141 | // No empty constructor found 142 | throw ProcessingException(classElement, 143 | "The class %s must provide an public empty default constructor", 144 | classElement.qualifiedName.toString()) 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /processor/src/main/kotlin/com/github/snowdream/toybricks/processor/InterfaceAnnotatedClass.kt: -------------------------------------------------------------------------------- 1 | package com.github.snowdream.toybricks.processor 2 | 3 | import javax.lang.model.element.Modifier 4 | import javax.lang.model.element.TypeElement 5 | 6 | /** 7 | * Created by snowdream on 17/2/12. 8 | */ 9 | class InterfaceAnnotatedClass @Throws(ProcessingException::class) 10 | constructor(classElement: TypeElement) : BaseAnnotatedClass() { 11 | 12 | init { 13 | this.annotatedClassElement = classElement 14 | } 15 | 16 | /** 17 | * The original element that was annotated with @Implementation 18 | */ 19 | val typeElement: TypeElement 20 | get() = annotatedClassElement 21 | 22 | @Throws(ProcessingException::class) 23 | override fun checkValid(processorManager: ProcessorManager) { 24 | 25 | // Cast to TypeElement, has more type specific methods 26 | val classElement = annotatedClassElement 27 | 28 | if (!classElement.modifiers.contains(Modifier.PUBLIC)) { 29 | throw ProcessingException(classElement, "The class %s is not public.", 30 | classElement.qualifiedName.toString()) 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /processor/src/main/kotlin/com/github/snowdream/toybricks/processor/InterfaceImplementationHandler.kt: -------------------------------------------------------------------------------- 1 | package com.github.snowdream.toybricks.processor 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper 4 | import com.fasterxml.jackson.module.kotlin.KotlinModule 5 | import com.github.snowdream.toybricks.annotation.Implementation 6 | import com.github.snowdream.toybricks.annotation.Interface 7 | import com.github.snowdream.toybricks.annotation.InterfaceLoader 8 | import com.squareup.javapoet.* 9 | import java.io.BufferedWriter 10 | import java.io.IOException 11 | import java.util.* 12 | import javax.annotation.processing.RoundEnvironment 13 | import javax.lang.model.element.ElementKind 14 | import javax.lang.model.element.Modifier 15 | import javax.lang.model.element.TypeElement 16 | import javax.tools.StandardLocation 17 | 18 | 19 | /** 20 | * Created by snowdream on 17/2/12. 21 | */ 22 | class InterfaceImplementationHandler : BaseContainerHandler() { 23 | private val interfaceMap = mutableMapOf() 24 | 25 | private val globalImplementationMap = mutableMapOf() 26 | 27 | private val defaultImplementationMap = mutableMapOf() 28 | 29 | private val singletonImplementationSet = mutableSetOf() 30 | 31 | private lateinit var processorManager: ProcessorManager 32 | 33 | override fun handle(processorManager: ProcessorManager, roundEnvironment: RoundEnvironment) { 34 | this.processorManager = processorManager 35 | 36 | interfaceMap.clear() 37 | globalImplementationMap.clear() 38 | defaultImplementationMap.clear() 39 | singletonImplementationSet.clear() 40 | 41 | handleInterfaceAnnotation(roundEnvironment) 42 | handleImplementationAnnotation(roundEnvironment) 43 | 44 | checkInterfaceImplementation() 45 | //generateJavaFile() 46 | generateJsonFile() 47 | } 48 | 49 | /** 50 | * handle Annotation @Interface 51 | */ 52 | private fun handleInterfaceAnnotation(roundEnv: RoundEnvironment) { 53 | try { 54 | // Scan classes 55 | for (annotatedElement in roundEnv.getElementsAnnotatedWith(Interface::class.java)) { 56 | 57 | // Check if a class has been annotated with @Interface 58 | if (annotatedElement.kind != ElementKind.INTERFACE) { 59 | throw ProcessingException(annotatedElement, "Only Interface can be annotated with @%s", 60 | Interface::class.java.simpleName) 61 | } 62 | 63 | // We can cast it, because we know that it of ElementKind.INTERFACE 64 | val typeElement = annotatedElement as TypeElement 65 | 66 | val annotatedClass = InterfaceAnnotatedClass(typeElement) 67 | 68 | annotatedClass.checkValid(processorManager) 69 | 70 | if (!interfaceMap.containsKey(annotatedClass.typeElement.qualifiedName.toString())) { 71 | interfaceMap.put(annotatedClass.typeElement.qualifiedName.toString(), annotatedClass) 72 | 73 | processorManager.info(annotatedClass.typeElement, "Found interface " + 74 | annotatedClass.typeElement.qualifiedName.toString() + 75 | ", annotated with @" + Interface::class.java.simpleName) 76 | } 77 | } 78 | } catch (e: ProcessingException) { 79 | processorManager.error(e.element, e.message as String) 80 | } 81 | 82 | } 83 | 84 | /** 85 | * handle Annotation @Implementation 86 | */ 87 | private fun handleImplementationAnnotation(roundEnv: RoundEnvironment) = try { 88 | // Scan classes 89 | for (annotatedElement in roundEnv.getElementsAnnotatedWith(Implementation::class.java)) { 90 | 91 | // Check if a class has been annotated with @Factory 92 | if (annotatedElement.kind != ElementKind.CLASS) { 93 | throw ProcessingException(annotatedElement, "Only classes can be annotated with @%s", 94 | Implementation::class.java.simpleName) 95 | } 96 | 97 | // We can cast it, because we know that it of ElementKind.CLASS 98 | val typeElement = annotatedElement as TypeElement 99 | 100 | val annotatedClass = ImplementationAnnotatedClass(typeElement) 101 | 102 | annotatedClass.checkValid(processorManager) 103 | 104 | val interfaceName = annotatedClass.qualifiedInterfaceClassName 105 | 106 | //fix: when interface is in module a,but Implementation is in module b 107 | //it will not work. 108 | if (interfaceName == null || interfaceName == ""){ 109 | continue 110 | } 111 | 112 | if (!interfaceMap.containsKey(interfaceName)) { 113 | interfaceMap.put(interfaceName, null) 114 | 115 | processorManager.info(null,"Found interface " + 116 | interfaceName + 117 | ", annotated with @" + Interface::class.java.simpleName) 118 | } 119 | 120 | if (annotatedClass.isGolbal) { 121 | if (globalImplementationMap.containsKey(interfaceName)) { 122 | val implementationAnnotatedClass = globalImplementationMap[interfaceName] 123 | 124 | // Alredy existing 125 | throw ProcessingException(annotatedClass.typeElement, 126 | "Conflict: The class %s is annotated with @%s with interface %s, but %s already uses the same interface", 127 | annotatedClass.typeElement.qualifiedName.toString(), Implementation::class.java.simpleName, 128 | interfaceName, implementationAnnotatedClass?.typeElement?.qualifiedName.toString()) 129 | } else { 130 | globalImplementationMap.put(interfaceName as String, annotatedClass) 131 | 132 | if (annotatedClass.isSingleton) { 133 | singletonImplementationSet.add(annotatedClass) 134 | } 135 | 136 | processorManager.info(annotatedClass.typeElement, "Found Global Implementation " + 137 | annotatedClass.typeElement.qualifiedName.toString() + 138 | ", annotated with @" + Implementation::class.java.simpleName) 139 | } 140 | } else { 141 | if (defaultImplementationMap.containsKey(interfaceName)) { 142 | val implementationAnnotatedClass = defaultImplementationMap[interfaceName] 143 | 144 | // Alredy existing 145 | throw ProcessingException(annotatedClass.typeElement, 146 | "Conflict: The class %s is annotated with @%s with interface %s, but %s already uses the same interface", 147 | annotatedClass.typeElement.qualifiedName.toString(), Implementation::class.java.simpleName, 148 | interfaceName, implementationAnnotatedClass?.typeElement?.qualifiedName.toString()) 149 | } else { 150 | defaultImplementationMap.put(interfaceName as String, annotatedClass) 151 | 152 | if (annotatedClass.isSingleton) { 153 | singletonImplementationSet.add(annotatedClass) 154 | } 155 | 156 | processorManager.info(annotatedClass.typeElement, "Found Default Implementation " + 157 | annotatedClass.typeElement.qualifiedName.toString() + 158 | ", annotated with @" + Implementation::class.java.simpleName) 159 | } 160 | } 161 | } 162 | } catch (e: ProcessingException) { 163 | processorManager.error(e.element, e.message as String) 164 | } 165 | 166 | /** 167 | * check whether interface has implementation. 168 | */ 169 | private fun checkInterfaceImplementation() { 170 | if (interfaceMap.isEmpty()) { 171 | return 172 | } 173 | 174 | //lib with only interface,skip the implementation check 175 | if (globalImplementationMap.isEmpty() && defaultImplementationMap.isEmpty()){ 176 | return 177 | } 178 | 179 | val iterator = interfaceMap.entries.iterator() 180 | while (iterator.hasNext()) { 181 | val entry = iterator.next() 182 | val interfaceName = entry.key 183 | val annotatedClass = entry.value 184 | 185 | var hasImplementation: Boolean 186 | 187 | if (!globalImplementationMap.isEmpty()) { 188 | hasImplementation = globalImplementationMap[interfaceName] != null 189 | 190 | if (hasImplementation) continue 191 | } 192 | 193 | if (!defaultImplementationMap.isEmpty()) { 194 | hasImplementation = defaultImplementationMap[interfaceName] != null 195 | 196 | if (hasImplementation) continue 197 | } 198 | 199 | if (annotatedClass == null){ 200 | processorManager.error(null, "Error: The interface " + 201 | interfaceName + 202 | " has no Implementation.") 203 | }else{ 204 | processorManager.error(annotatedClass.typeElement, "Error: The interface " + 205 | annotatedClass.typeElement.getQualifiedName().toString() + 206 | " has no Implementation.") 207 | } 208 | } 209 | } 210 | 211 | 212 | /** 213 | * generate java file 214 | */ 215 | private fun generateJavaFile() { 216 | if (interfaceMap.isEmpty() && 217 | globalImplementationMap.isEmpty() && 218 | defaultImplementationMap.isEmpty()) { 219 | return 220 | } 221 | 222 | 223 | //val elementUtils = processorManager.elementUtils 224 | val filer = processorManager.filer 225 | 226 | val clazz = InterfaceLoader::class.java 227 | 228 | val pn = clazz.`package`.name 229 | val sn = clazz.simpleName 230 | 231 | val packageName = pn + ".impl" 232 | val className = sn + "Impl" 233 | 234 | try { 235 | //private static HashMap sSingletonMap = new HashMap(); 236 | val classTypeVariableName = TypeVariableName.get("Class") 237 | val objectTypeVariableName = TypeVariableName.get("Object") 238 | val hashMapClzName = ClassName.get(HashMap::class.java) 239 | 240 | 241 | val singletonMapParameterizedTypeName = ParameterizedTypeName.get(hashMapClzName, classTypeVariableName, objectTypeVariableName) 242 | 243 | val singletonMap = FieldSpec.builder(singletonMapParameterizedTypeName, "sSingletonMap") 244 | .addModifiers(Modifier.PRIVATE, Modifier.STATIC) 245 | .initializer("new \$T()", singletonMapParameterizedTypeName) 246 | .build() 247 | 248 | // private static HashMap sGlobalMap= new HashMap<>(); 249 | val implementationParameterizedTypeName = ParameterizedTypeName.get(hashMapClzName, classTypeVariableName, classTypeVariableName) 250 | 251 | val globalMap = FieldSpec.builder(implementationParameterizedTypeName, "sGlobalMap") 252 | .addModifiers(Modifier.PRIVATE, Modifier.STATIC) 253 | .initializer("new \$T()", implementationParameterizedTypeName) 254 | .build() 255 | 256 | // private static HashMap sDefaultMap= new HashMap<>(); 257 | val defaultMap = FieldSpec.builder(implementationParameterizedTypeName, "sDefaultMap") 258 | .addModifiers(Modifier.PRIVATE, Modifier.STATIC) 259 | .initializer("new \$T()", implementationParameterizedTypeName) 260 | .build() 261 | 262 | 263 | // public NewInterfaceLoader() 264 | val constructorMethodSpec = MethodSpec.constructorBuilder() 265 | .addModifiers(Modifier.PUBLIC) 266 | .addStatement("addGlobalMap()") 267 | .addStatement("addDefaultMap()") 268 | .addStatement("addSingletonMap()") 269 | .build() 270 | 271 | // private void addGlobalMap() 272 | val globalMapMethodSpecBuilder = MethodSpec.methodBuilder("addGlobalMap") 273 | .addModifiers(Modifier.PRIVATE) 274 | 275 | var iterator = globalImplementationMap.entries.iterator() 276 | while (iterator.hasNext()) { 277 | val entry = iterator.next() 278 | val interfaceName = entry.key 279 | val annotatedClass = entry.value 280 | 281 | globalMapMethodSpecBuilder.addStatement("sGlobalMap.put(\$L.class,\$L.class)", interfaceName, annotatedClass.typeElement.getQualifiedName()) 282 | } 283 | 284 | val globalMapMethodSpec = globalMapMethodSpecBuilder.build() 285 | 286 | // private void addDefaultMap() 287 | val defaultMapMethodSpecBuilder = MethodSpec.methodBuilder("addDefaultMap") 288 | .addModifiers(Modifier.PRIVATE) 289 | 290 | iterator = defaultImplementationMap.entries.iterator() 291 | while (iterator.hasNext()) { 292 | val entry = iterator.next() 293 | val interfaceName = entry.key 294 | val annotatedClass = entry.value 295 | 296 | defaultMapMethodSpecBuilder.addStatement("sDefaultMap.put(\$L.class,\$L.class)", interfaceName, annotatedClass.typeElement.getQualifiedName()) 297 | } 298 | 299 | val defaultMapMethodSpec = defaultMapMethodSpecBuilder.build() 300 | 301 | 302 | // private void addSingletonMap() 303 | val singletonMapMethodSpecBuilder = MethodSpec.methodBuilder("addSingletonMap") 304 | .addModifiers(Modifier.PRIVATE) 305 | 306 | val it = singletonImplementationSet.iterator() 307 | while (it.hasNext()) { 308 | val annotatedClass = it.next() 309 | 310 | singletonMapMethodSpecBuilder.addStatement("sSingletonMap.put(\$L.class,null)", annotatedClass.typeElement.qualifiedName) 311 | } 312 | 313 | val singletonMapMethodSpec = singletonMapMethodSpecBuilder.build() 314 | 315 | //public T getImplementation(Class clazz) 316 | val typeVariableName = TypeVariableName.get("T") 317 | val classClzName = ClassName.get(Class::class.java) 318 | 319 | val parameterizedTypeName = ParameterizedTypeName.get(classClzName, typeVariableName) 320 | val getImplementationMethodSpec = MethodSpec.methodBuilder("getImplementation") 321 | .addAnnotation(Override::class.java) 322 | .addModifiers(Modifier.PUBLIC) 323 | .returns(typeVariableName) 324 | .addTypeVariable(typeVariableName) 325 | .addParameter(parameterizedTypeName, "clazz") 326 | .addStatement("T implementation = null") 327 | .addCode("\n") 328 | .addStatement("boolean isSingleton = false") 329 | .addCode("\n") 330 | .addStatement("Class implClass") 331 | .addCode("\n") 332 | .addStatement("implClass = sGlobalMap.get(clazz)") 333 | .addCode("\n") 334 | .addCode(CodeBlock.builder() 335 | .beginControlFlow("if (implClass == null)") 336 | .addStatement("implClass = sDefaultMap.get(clazz)") 337 | .endControlFlow() 338 | .build()) 339 | .addCode("\n") 340 | .addCode(CodeBlock.builder() 341 | .beginControlFlow("if (implClass != null)") 342 | .addStatement("isSingleton = sSingletonMap.containsKey(implClass)") 343 | .add("\n") 344 | .add(CodeBlock.builder() 345 | .beginControlFlow("if (isSingleton)") 346 | .addStatement("implementation = (T) sSingletonMap.get(implClass)") 347 | .add(CodeBlock.builder() 348 | .beginControlFlow("if (implementation != null)") 349 | .addStatement("return implementation") 350 | .endControlFlow() 351 | .build()) 352 | .endControlFlow() 353 | .build()) 354 | .add("\n") 355 | .add(CodeBlock.builder() 356 | .beginControlFlow("try") 357 | .addStatement("implementation = (T) implClass.newInstance()") 358 | .nextControlFlow("catch (InstantiationException e)") 359 | .addStatement("e.printStackTrace()") 360 | .nextControlFlow("catch (IllegalAccessException e)") 361 | .addStatement("e.printStackTrace()") 362 | .endControlFlow() 363 | .build() 364 | ) 365 | .add("\n") 366 | .add(CodeBlock.builder() 367 | .beginControlFlow("if (isSingleton && implementation != null)") 368 | .addStatement("sSingletonMap.put(implClass, implementation)") 369 | .endControlFlow() 370 | .build() 371 | ) 372 | .endControlFlow() 373 | .build()) 374 | .addCode("\n") 375 | .addStatement("return implementation") 376 | .build() 377 | 378 | val typeSpec = TypeSpec.classBuilder(className)//HelloWorld是类名 379 | .addJavadoc("\n") 380 | .addJavadoc("Created by snowdream") 381 | .addJavadoc("\n") 382 | .addJavadoc("\n") 383 | .addJavadoc("This file is automatically generated by apt(Annotation Processing Tool)") 384 | .addJavadoc("\n") 385 | .addJavadoc("Do not modify this file -- YOUR CHANGES WILL BE ERASED!") 386 | .addJavadoc("\n") 387 | .addJavadoc("\n") 388 | .addJavadoc("This file should *NOT* be checked into Version Control Systems,") 389 | .addJavadoc("\n") 390 | .addJavadoc("as it contains information specific to your local configuration.") 391 | .addJavadoc("\n") 392 | .addModifiers(Modifier.FINAL) 393 | .addSuperinterface(InterfaceLoader::class.java) 394 | .addField(singletonMap) 395 | .addField(globalMap) 396 | .addField(defaultMap) 397 | .addMethod(constructorMethodSpec) 398 | .addMethod(globalMapMethodSpec) 399 | .addMethod(defaultMapMethodSpec) 400 | .addMethod(singletonMapMethodSpec) 401 | .addMethod(getImplementationMethodSpec) 402 | .build() 403 | 404 | val javaFile = JavaFile.builder(packageName, typeSpec) 405 | .build() 406 | javaFile.writeTo(filer) 407 | } catch (e: IOException) { 408 | e.printStackTrace() 409 | processorManager.error(null, e.message as String) 410 | } 411 | 412 | } 413 | 414 | 415 | /** 416 | * generate json file 417 | */ 418 | private fun generateJsonFile() { 419 | if (interfaceMap.isEmpty()) { 420 | return 421 | } 422 | 423 | //val elementUtils = processorManager.elementUtils 424 | val filer = processorManager.filer 425 | val resource = filer.createResource(StandardLocation.SOURCE_OUTPUT, "", "ToyBricks.json") 426 | val writter = BufferedWriter(resource.openWriter()) 427 | 428 | //deal interfaceMap 429 | val interfaceList = mutableListOf() 430 | if (!interfaceMap.isEmpty()) { 431 | val iterator = interfaceMap.entries.iterator() 432 | while (iterator.hasNext()) { 433 | val entry = iterator.next() 434 | val interfaceName = entry.key 435 | //val annotatedClass = entry.value 436 | 437 | interfaceList.add(interfaceName) 438 | } 439 | } 440 | 441 | //deal globalImplementationMap 442 | val globalImplementation = mutableMapOf() 443 | if (!globalImplementationMap.isEmpty()) { 444 | val iterator = globalImplementationMap.entries.iterator() 445 | while (iterator.hasNext()) { 446 | val entry = iterator.next() 447 | val interfaceName = entry.key 448 | val annotatedClass = entry.value 449 | 450 | globalImplementation.put(interfaceName,annotatedClass.typeElement.getQualifiedName().toString()) 451 | } 452 | } 453 | 454 | //deal defaultImplementationMap 455 | val defaultImplementation = mutableMapOf() 456 | if (!defaultImplementationMap.isEmpty()) { 457 | val iterator = defaultImplementationMap.entries.iterator() 458 | while (iterator.hasNext()) { 459 | val entry = iterator.next() 460 | val interfaceName = entry.key 461 | val annotatedClass = entry.value 462 | 463 | defaultImplementation.put(interfaceName,annotatedClass.typeElement.getQualifiedName().toString()) 464 | } 465 | } 466 | 467 | 468 | //deal singletonImplementationSet 469 | val singletonImplementation = mutableListOf() 470 | if (!singletonImplementationSet.isEmpty()) { 471 | val iterator = singletonImplementationSet.iterator() 472 | while (iterator.hasNext()) { 473 | val annotatedClass = iterator.next() 474 | 475 | singletonImplementation.add(annotatedClass.typeElement.qualifiedName.toString()) 476 | } 477 | } 478 | 479 | 480 | val entity = ToyBricksJsonEntity(interfaceList, globalImplementation,defaultImplementation,singletonImplementation) 481 | 482 | val mapper = ObjectMapper().registerModule(KotlinModule()) 483 | val json = mapper 484 | .writerWithDefaultPrettyPrinter() 485 | .writeValueAsString(entity) 486 | 487 | writter.write(json) 488 | writter.flush() 489 | writter.close() 490 | } 491 | } 492 | -------------------------------------------------------------------------------- /processor/src/main/kotlin/com/github/snowdream/toybricks/processor/ProcessingException.kt: -------------------------------------------------------------------------------- 1 | package com.github.snowdream.toybricks.processor 2 | 3 | import javax.lang.model.element.Element 4 | 5 | /** 6 | * Created by snowdream on 17/2/12. 7 | */ 8 | class ProcessingException(element: Element, msg: String, vararg args: String?) : Exception(String.format(msg, *args)) { 9 | 10 | var element: Element 11 | internal set 12 | 13 | init { 14 | this.element = element 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /processor/src/main/kotlin/com/github/snowdream/toybricks/processor/ProcessorManager.kt: -------------------------------------------------------------------------------- 1 | package com.github.snowdream.toybricks.processor 2 | 3 | import javax.annotation.processing.Filer 4 | import javax.annotation.processing.Messager 5 | import javax.annotation.processing.ProcessingEnvironment 6 | import javax.annotation.processing.RoundEnvironment 7 | import javax.lang.model.element.Element 8 | import javax.lang.model.util.Elements 9 | import javax.lang.model.util.Types 10 | import javax.tools.Diagnostic 11 | import java.util.ArrayList 12 | 13 | /** 14 | * Created by snowdream on 17/2/12. 15 | */ 16 | class ProcessorManager internal constructor(private val mProcessingEnvironment: ProcessingEnvironment) : Handler { 17 | private var mHandlers: MutableList? = null 18 | 19 | val typeUtils: Types 20 | val elementUtils: Elements 21 | val filer: Filer 22 | val messager: Messager 23 | 24 | 25 | init { 26 | 27 | typeUtils = mProcessingEnvironment.typeUtils 28 | elementUtils = mProcessingEnvironment.elementUtils 29 | filer = mProcessingEnvironment.filer 30 | messager = mProcessingEnvironment.messager 31 | } 32 | 33 | internal fun addHandlers(vararg containerHandlers: BaseContainerHandler) { 34 | if (containerHandlers.isEmpty()) { 35 | return 36 | } 37 | 38 | for (handler in containerHandlers) { 39 | 40 | if (mHandlers == null) { 41 | mHandlers = ArrayList() 42 | } 43 | 44 | if (!mHandlers!!.contains(handler)) { 45 | mHandlers!!.add(handler) 46 | } 47 | } 48 | } 49 | 50 | override fun handle(processorManager: ProcessorManager, roundEnvironment: RoundEnvironment) { 51 | if (mHandlers != null) { 52 | for (handler in mHandlers!!) { 53 | handler.handle(processorManager, roundEnvironment) 54 | } 55 | } 56 | 57 | } 58 | 59 | /** 60 | * Prints an error message 61 | 62 | * @param e The element which has caused the error. Can be null 63 | * * 64 | * @param msg The error message 65 | */ 66 | fun error(e: Element?, msg: String) { 67 | messager.printMessage(Diagnostic.Kind.ERROR, msg, e) 68 | } 69 | 70 | /** 71 | * Prints an info message 72 | 73 | * @param e The element which has caused the error. Can be null 74 | * * 75 | * @param msg The error message 76 | */ 77 | fun info(e: Element?, msg: String) { 78 | messager.printMessage(Diagnostic.Kind.NOTE, msg, e) 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /processor/src/main/kotlin/com/github/snowdream/toybricks/processor/ToyBricksJsonEntity.kt: -------------------------------------------------------------------------------- 1 | package com.github.snowdream.toybricks.processor 2 | 3 | /** 4 | * Created by snowdream on 17/3/11. 5 | * @author snowdream 6 | * @date 2017/03/11 7 | */ 8 | data class ToyBricksJsonEntity(val interfaceList: MutableList, val globalImplementation: MutableMap 9 | , val defaultImplementation: MutableMap, val singletonImplementation: MutableList) 10 | -------------------------------------------------------------------------------- /processor/src/main/kotlin/com/github/snowdream/toybricks/processor/ToyBricksProcessor.kt: -------------------------------------------------------------------------------- 1 | package com.github.snowdream.toybricks.processor 2 | 3 | import com.github.snowdream.toybricks.annotation.Implementation 4 | import com.github.snowdream.toybricks.annotation.Interface 5 | import com.google.auto.service.AutoService 6 | 7 | import javax.annotation.processing.AbstractProcessor 8 | import javax.annotation.processing.ProcessingEnvironment 9 | import javax.annotation.processing.Processor 10 | import javax.annotation.processing.RoundEnvironment 11 | import javax.lang.model.SourceVersion 12 | import javax.lang.model.element.TypeElement 13 | import java.util.LinkedHashSet 14 | 15 | /** 16 | * Created by snowdream on 17/2/11. 17 | */ 18 | @AutoService(Processor::class) 19 | class ToyBricksProcessor : AbstractProcessor() { 20 | 21 | private lateinit var manager: ProcessorManager 22 | 23 | /** 24 | * If the processor class is annotated with [ ], return an unmodifiable set with the 25 | * same set of strings as the annotation. If the class is not so 26 | * annotated, an empty set is returned. 27 | 28 | * @return the names of the annotation types supported by this 29 | * * processor, or an empty set if none 30 | */ 31 | override fun getSupportedAnnotationTypes(): Set { 32 | val supportedTypes = LinkedHashSet() 33 | supportedTypes.add(Interface::class.java.canonicalName) 34 | supportedTypes.add(Implementation::class.java.canonicalName) 35 | return supportedTypes 36 | } 37 | 38 | /** 39 | * If the processor class is annotated with [ ], return the source version in the 40 | * annotation. If the class is not so annotated, [ ][SourceVersion.RELEASE_6] is returned. 41 | 42 | * @return the latest source version supported by this processor 43 | */ 44 | override fun getSupportedSourceVersion(): SourceVersion { 45 | return SourceVersion.latestSupported() 46 | } 47 | 48 | @Synchronized override fun init(processingEnv: ProcessingEnvironment) { 49 | super.init(processingEnv) 50 | manager = ProcessorManager(processingEnv) 51 | manager.addHandlers( 52 | InterfaceImplementationHandler() 53 | ) 54 | } 55 | 56 | override fun process(annotations: Set, roundEnv: RoundEnvironment): Boolean { 57 | 58 | manager.handle(manager, roundEnv) 59 | 60 | // return true if we successfully processed the Annotation. 61 | return true 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | include 'annotation' 3 | include 'processor' 4 | include 'lib' 5 | include 'plugin' 6 | 7 | --------------------------------------------------------------------------------