diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000000..750e8ac81a --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/donate.png diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE/bug_report.md similarity index 77% rename from .github/ISSUE_TEMPLATE.md rename to .github/ISSUE_TEMPLATE/bug_report.md index daea781567..e29c2e45b6 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,8 +1,16 @@ +--- +name: Bug report +about: Make AndroidUtilCode more perfect! +labels: bug +assignees: Blankj + +--- + ## Describe the bug A clear and concise description of what the bug is. -- The version of utilcode: +- The version of AndroidUtilCode: - The device: - The version of device: @@ -39,6 +47,6 @@ put the stack of crash here If applicable, add screenshots to help explain your problem. -Please delete the current line and the followings. +## Please delete the current line and the following. -Thank you for supporting [AndroidUtilCode](https://github.com/Blankj/AndroidUtilCode). \ No newline at end of file +Thank you for supporting [AndroidUtilCode](https://github.com/Blankj/AndroidUtilCode). diff --git a/.github/ISSUE_TEMPLATE/bug_report_cn.md b/.github/ISSUE_TEMPLATE/bug_report_cn.md new file mode 100644 index 0000000000..02ea0223e3 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report_cn.md @@ -0,0 +1,52 @@ +--- +name: 提交 Bug +about: 让工具类更完美! +labels: bug +assignees: Blankj + +--- + +## 描述 Bug + +简洁地描述下 Bug。 + +- AndroidUtilCode 的版本: +- 出现 Bug 的设备型号: +- 设备的 Android 版本: + +## 相关代码 + + +``` +put your code here +``` + +## 异常堆栈 + + + +``` +put the stack of crash here +``` + +## 截图 + +如果有的话请添加屏幕截图以帮助解释问题。 + + +## 请删除当前行及以下内容 + +感谢支持 [AndroidUtilCode](https://github.com/Blankj/AndroidUtilCode). diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md new file mode 100644 index 0000000000..90a0fe1993 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -0,0 +1,21 @@ +--- +name: Feature request +about: Make AndroidUtilCode more perfect! +labels: help wanted +assignees: Blankj + +--- + +## Describe the feature + +A clear and concise description of what the feature is. + + +## Reference + +Hope to give some reference articles, links, code, if any. + + +## Please delete the current line and the following + +Thank you for supporting [AndroidUtilCode](https://github.com/Blankj/AndroidUtilCode). diff --git a/.github/ISSUE_TEMPLATE/feature-request_cn.md b/.github/ISSUE_TEMPLATE/feature-request_cn.md new file mode 100644 index 0000000000..20862d047b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature-request_cn.md @@ -0,0 +1,21 @@ +--- +name: 提交需求 +about: 让工具类更健全! +labels: help wanted +assignees: Blankj + +--- + +## 描述需求 + +简洁地描述下需求。 + + +## 可借鉴的 + +如果有的话,可以给出一些参考文章、链接、代码 + + +## 请删除当前行及以下内容 + +感谢支持 [AndroidUtilCode](https://github.com/Blankj/AndroidUtilCode). diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml new file mode 100644 index 0000000000..311fc1deaa --- /dev/null +++ b/.github/workflows/android.yml @@ -0,0 +1,17 @@ +name: Android CI + +on: [push] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Build with Gradle + run: ./gradlew build aR diff --git a/.gitignore b/.gitignore index 9bf2876a4e..9d11f56a24 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,15 @@ *.iml +__api__.json +__bus__.json .gradle -/local.properties +local.properties .idea .DS_Store /build /captures .externalNativeBuild /apk -/maven -__bus__.json \ No newline at end of file +*.phrof +/mavenLocal +/reports +*/reports \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b4e77e194d..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,24 +0,0 @@ -language: android -jdk: oraclejdk8 -sudo: false - -android: - components: - - tools - - platform-tools - - build-tools-27.0.2 - - android-27 - - add-on - - extra - - licenses: - - 'android-sdk-license-.+' - - notifications: - email: false - -before_install: - - yes | $ANDROID_HOME/tools/bin/sdkmanager "build-tools;26.0.2" - -script: - - ./gradlew build connectedCheck --info diff --git a/CHANGELOG.md b/CHANGELOG.md index 0012fe5ae7..73e8145bf1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,140 @@ +* `22/10/15` [add] Fix some issue. Publish v1.31.1 +* `21/12/06` [add] Publish v1.31.0 +* `21/05/13` [add] Support publish mavenCentral. +* `21/02/22` [add] Fix ToastUtils rtl bug. Publish v1.30.6. +* `20/11/16` [add] Add ImageUtils#save2Album support param of dirName. +* `20/11/13` [add] Fix MessengerUtils ANR. Add NetworkUtils#getWifiScanResult, [add|remove]OnWifiChangedConsumer. Publish v1.30.5. +* `20/10/29` [add] Fix MessengerUtils startService IllegalStateException. Publish v1.30.4. +* `20/10/28` [add] Fix BusUtils ConcurrentModificationException. Publish v1.30.3. +* `20/10/27` [add] Fix AppUtils#getAppSignatures. Add DeviceUtils#isDevelopmentSettingsEnabled. Publish v1.30.2. +* `20/10/26` [add] Fix AppUtils#isAppForeground. Publish v1.30.1. +* `20/10/24` [add] Publish v1.30.0. +* `20/10/23` [fix] LanguageUtils crash on some device. +* `20/10/21` [add] LogUtils.Config#setOnConsoleOutputListener, setOnFileOutputListener, addFileExtraHead. LogUtils.getCurrentLogFilePath. +* `20/10/20` [opt] ToastUtils. +* `20/10/12` [add] PermissionUtils#explain. +* `20/10/10` [add] ClipboardUtils. +* `20/10/08` [add] VolumeUtils. +* `20/09/06` [add] DebouncingUtils#isValid. +* `20/09/04` [fix] ToastUtils adapt SDK 30. +* `20/05/28` [fix] IntentUtils#getInstallAppIntent file exist wrong. Publish v1.29.0. +* `20/05/23` [fix] BusUtils#postSticky times not right. Publish v1.28.6. +* `20/05/22` [add] IntentUtils#getInstallAppIntent support Uri param. +* `20/05/21` [add] Publish bus plugin v2.6. Publish api plugin v1.4. Publish. Publish v1.28.5. +* `20/05/19` [fix] FileUtils#copyOrMoveDird NPE. +* `20/05/18` [add] IntentUtils#getLaunchAppDetailsSettingsIntent support isNewTask. +* `20/05/17` [add] ImageUtils#save2Album, NetworkUtils#getSSID, UtilsTransActivity4MainProcess. +* `20/05/03` [add] Publish bus plugin v2.5. Publish api plugin v1.3. Publish. Publish v1.28.4. +* `20/04/30` [add] BaseItem support partialUpdate. +* `20/04/29` [add] Publish plugin lib com.blankj:base-transform:1.0. +* `20/04/28` [fix] LanguageUtils#applyLanguage. +* `20/04/27` [fix] BarUtils#isNavBarVisible. +* `20/04/26` [fix] Utils#init fit tinker. Publish v1.28.3. +* `20/04/25` [fix] UriUtils#uri2File Unknown URI. Publish 1.28.2. +* `20/04/24` [add] SnackbarUtils support show on the top; UriUtils#uri2InputStream. +* `20/04/23` [fix] UriUtils#uri2File not support HW; TransActivity crash below 21. +* `20/04/23` [fix] PhoneUtils#getSerial, PhoneUtils#getSerial crash on Android 10. +* `20/04/20` [fix] ImageUtils#isImage. +* `20/04/18` [fix] PermissionUtils#callback. Publish v1.28.1. +* `20/04/17` [fix] ImageUtils#view2Bitmap, ImageUtils.getBitmap(InputStream). +* `20/04/16` [add] ConvertUtils#int2HexString, hexString2Int. +* `20/04/15` [add] UiMessageUtils' demo. +* `20/04/13` [add] NumberUtils. Publish v1.28.0. +* `20/04/12` [opt] TimeUtils#SDF_THREAD_LOCAL. +* `20/04/11` [add] SDCardUtils#getXxTotalSize, SDCardUtils#getXxAvailableSize. FileUtils#getFsTotalSize, FileUtils#getFsAvailableSize. +* `20/04/10` [fix] FileUtils#isFileExists; FragmentUtils#getTop bug. Publish v1.27.6. +* `20/04/09` [add] UriUtils#res2Uri, UriUtils#uri2File support QQBrowser; ThreadUtils#getMainHandler; PathUtils#getxxPathExternalFirst. +* `20/04/08` [fix] ActivityUtils#finish bug. Publish v1.27.5. +* `20/04/08` [fix] CleanUtils clean dir not work. FileUtils#isFileExists. Publish v1.27.4. +* `20/04/08` [fix] CrashUtils DefaultUncaughtExceptionHandler is wrong; LogUtils write file failed; Utils#getApp failed run on remote process. Publish v1.27.3. +* `20/04/07` [mdf] GsonUtils#getGson() method public. +* `20/04/04` [fix] ShadowUtils bug running on lower version devices. Publish v1.27.2. +* `20/04/03` [fix] UtilsActivityLifecycleImpl#HashMap#remove IllegalStateException bug. +* `20/04/02` [fix] PathUtils sdcard enable state is wrong; ActivityUtils finish activity wrong; Publish v1.27.1. +* `20/03/31` [add] Publish v1.27.0. +* `20/03/30` [add] BatteryUtils in subutil. +* `20/03/27` [add] publish.gradle. +* `20/03/24` [add] UtilsBridge to clean the utils. +* `20/03/22` [upd] GsonUtils support custom gson. +* `20/03/20` [add] ActivityUtils#addActivityLifecycleCallbacks, ActivityUtils#removeActivityLifecycleCallbacks. +* `20/01/17` [upd] Leak Canary to v2.1. +* `20/01/06` [add] ClickUtils#expandClickArea, ClickUtils#back2HomeFriendly +* `19/11/30` [add] Publish bus plugin v2.4. Publish api plugin v1.2. +* `19/11/28` [add] Publish v1.26.0. +* `19/11/27` [add] Shadow demo. +* `19/11/26` [add] MVP demo. +* `19/11/22` [fix] Adapt the project for Gradle version of 6.0. +* `19/10/30` [add] Publish bus plugin v2.3. Publish api plugin v1.1. +* `19/10/24` [upd] Demo's UI. +* `19/10/22` [add] NotificationUtils and demo. +* `19/10/20` [add] UiMessageUtils. +* `19/09/20` [add] ShadowUtils. +* `19/08/27` [add] DebugUtils. +* `19/08/26` [fix] PermissionUtils NPE. +* `19/08/25` [upd] ImageUtils#getImageType. [add] LogUtils#getLogFiles. Publish v1.25.9. +* `19/08/24` [fix] PhoneUtils#getIMEI crash on SDK 29. +* `19/08/23` [add] ViewUtils#isLayoutRtl. +* `19/08/22` [add] LogUtils#getLogFiles. +* `19/08/13` [add] MapUtils and MapUtilsTest. Publish v1.25.8. +* `19/08/12` [add] CollectionUtils and CollectionUtilsTest. +* `19/08/11` [add] ArrayUtils and ArrayUtilsTest. +* `19/08/09` [fix] https://www.virustotal.com/gui/home/upload with ESET-NOD32. Publish v1.25.7. +* `19/08/08` [add] BusUtils#post tag support one-to-many. Publish v1.25.6. +* `19/08/04` [add] ThreadUtils#Task support timeout. +* `19/08/01` [upd] EncryptUtils#rsa. +* `19/07/31` [add] DeviceUtils#getUniqueDeviceId, DeviceUtils#isSameDevice. Publish v1.25.5. +* `19/07/30` [fix] ThreadUtils's task can only be executed once. PhoneUtils#getIMEI wrong. +* `19/07/29` [fix] BusUtils post father class useless. KeyboardUtils#hideSoft bug. Publish v1.25.4. +* `19/07/28` [add] NetworkUtils#(un)registerNetworkStatusChangedListener. Publish v1.25.3. +* `19/07/27` [fix] ThreadUtils memory leak. +* `19/07/26` [add] ContainerUtils. Publish v1.25.2. +* `19/07/25` [fix] PermissionUtils' NullPointException. +* `19/07/24` [fix] ZipUtils#unzipFile. +* `19/07/23` [fix] ThreadUtils of cache pool. Publish v1.25.1. +* `19/07/18` [add] README of ApiUtils and BusUtils. +* `19/07/15` [add] Publish v1.25.0. +* `19/07/14` [upd] Bus plugin for use BusUtils. Publish bus plugin v2.0. +* `19/07/13` [add] Api plugin for use ApiUtils. Publish api plugin v1.0. +* `19/07/09` [upd] The frame of project. +* `19/07/06` [upd] BusUtils which behave same as EventBus. +* `19/07/03` [add] ApiUtils which decoupling modules. +* `19/06/30` [add] LanguageUtils support activity's class name. +* `19/06/29` [add] ClickUtils#OnMultiClickListener, and remove dangerous function. Publish v1.24.6. +* `19/06/28` [add] LanguageUtils. Publish v1.24.5. +* `19/06/20` [fix] BusUtils' permission. Publish v1.24.4. +* `19/06/19` [fix] UriUtils. Publish v1.24.3. +* `19/06/18` [add] ClickUtils, ViewUtils. +* `19/06/07` [fix] LogUtils file name contains ':'. Publish v1.24.2. +* `19/06/06` [fix] LogUtils write to file. Publish v1.24.1. +* `19/06/03` [fix] Refactoring framework. Publish v1.24.0. +* `19/04/25` [fix] LogUtils delete due log. +* `19/04/24` [upd] The swipe panel. +* `19/03/17` [fix] The ugly UI. +* `19/03/14` [fix] AdaptScreenUtils didn't work on some HaWei tablet. +* `19/03/09` [fix] UriUtils#uri2File. +* `19/03/08` [add] LogUtils support multi process. Publish v1.23.7. +* `19/03/02` [fix] LogUtils#file. +* `19/02/28` [fix] ImageUtils#calculateInSampleSize. Publish v1.23.6. +* `19/02/26` [fix] UriUtils#uri2File. Publish v1.23.5. +* `19/01/31` [add] HttpUtils. +* `19/01/30` [add] RomUtils. Publish v1.23.4. +* `19/01/29` [fix] LogUtils format json when json not start with '{'. Publish v1.23.3. +* `19/01/28` [fix] KeyboardUtils#fixSoftInputLeaks don't work on the device of HuaWei. +* `19/01/26` [fix] NetworkUtils#getNetworkType. +* `19/01/25` [add] CloneUtils, PermissionUtils support request permission of WRITE_SETTINGS and DRAW_OVERLAYS. Publish v1.23.2. +* `19/01/24` [add] BrightnessUtils and FlashlightUtils. +* `19/01/23` [add] Modify the demo of utilcode use kotlin. Publish v1.23.1. +* `19/01/22` [fix] AppUtils#installApp. +* `19/01/17` [fix] Publish v1.23.0. +* `19/01/16` [fix] BarUtils get Activity from view and delete the function of set status bar alpha. +* `19/01/15` [add] ColorUtils. +* `19/01/04` [add] CacheDiskStaticUtils, CacheDoubleStaticUtils, CacheMemoryStaticUtils. +* `19/01/03` [add] SPStaticUtils. +* `19/01/02` [fix] LogUtils log object. Publish v1.22.10. +* `19/01/01` [add] GsonUtils. +* `18/12/29` [add] AntiShakeUtils and VibrateUtils. Publish v1.22.9. +* `18/12/28` [fix] ToastUtils show behind the dialog when close notification. +* `18/12/27` [fix] LogUtils print StringBuilder failed. * `18/12/24` [fix] Utils$ActivityLifecycleImpl.consumeOnActivityDestroyedListener ConcurrentModificationException. Publish v1.22.7. * `18/12/22` [fix] AdaptScreenUtils#pt2px don't work when start webview. Publish v1.22.6. * `18/12/21` [add] LogUtils support print Map, Collection and Object to String. diff --git a/README-CN.md b/README-CN.md index 09c5ba26c1..5c85dca1fe 100644 --- a/README-CN.md +++ b/README-CN.md @@ -1,6 +1,8 @@ -![logo][logo] +[![logo][logo]](https://github.com/Blankj/AndroidUtilCode) -[![auc][aucSvg]][auc] [![api][apiSvg]][api] [![build][buildSvg]][build] [![License][licenseSvg]][license] +[![frame][frame]](https://github.com/Blankj/AucFrameTemplate) + +[![auc][aucSvg]][auc] [![result][apiSvg]][result] [![build][buildSvg]][build] [![License][licenseSvg]][license] ## [README of English][readme] @@ -38,14 +40,20 @@ ## [Change Log][changeLog.md] +## 打个小广告 + +欢迎加入我的小专栏「**[基你太美](https://xiaozhuanlan.com/Blankj)**」一起学习。 + [logo]: https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/logo.png -[aucSvg]: https://img.shields.io/badge/AndroidUtilCode-v1.22.7-brightgreen.svg +[frame]: https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/auc_frame_cn.png + +[aucSvg]: https://github.com/Blankj/AndroidUtilCode/workflows/Android%20CI/badge.svg?branch=master [auc]: https://github.com/Blankj/AndroidUtilCode [apiSvg]: https://img.shields.io/badge/API-14+-brightgreen.svg -[api]: https://android-arsenal.com/api?level=14 +[result]: https://android-arsenal.com/result?level=14 [buildSvg]: https://travis-ci.org/Blankj/AndroidUtilCode.svg?branch=master [build]: https://travis-ci.org/Blankj/AndroidUtilCode @@ -56,11 +64,11 @@ [readme]: https://github.com/Blankj/AndroidUtilCode [readme-cn]: https://github.com/Blankj/AndroidUtilCode/blob/master/README-CN.md -[utilcode]: https://github.com/Blankj/AndroidUtilCode/blob/master/utilcode/README.md -[utilcode-cn]: https://github.com/Blankj/AndroidUtilCode/blob/master/utilcode/README-CN.md +[utilcode]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/README.md +[utilcode-cn]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/README-CN.md -[subutil]: https://github.com/Blankj/AndroidUtilCode/blob/master/subutil/README.md -[subutil-cn]: https://github.com/Blankj/AndroidUtilCode/blob/master/subutil/README-CN.md +[subutil]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/subutil/README.md +[subutil-cn]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/subutil/README-CN.md [changeLog.md]: https://github.com/Blankj/AndroidUtilCode/blob/master/CHANGELOG.md diff --git a/README.md b/README.md index ad4d21a999..9ae668e26e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ -![logo][logo] +[![logo][logo]](https://github.com/Blankj/AndroidUtilCode) -[![auc][aucSvg]][auc] [![api][apiSvg]][api] [![build][buildSvg]][build] [![License][licenseSvg]][license] +[![frame][frame]](https://github.com/Blankj/AucFrameTemplate) + +[![auc][aucSvg]][auc] [![result][apiSvg]][result] [![build][buildSvg]][build] [![License][licenseSvg]][license] ## [README of Chinese][readme-cn] @@ -38,14 +40,20 @@ If this project helps you a lot and you want to support the project's developmen ## [Change Log][changeLog.md] +## 打个小广告 + +欢迎加入我的小专栏「**[基你太美](https://xiaozhuanlan.com/Blankj)**」一起学习。 + [logo]: https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/logo.png -[aucSvg]: https://img.shields.io/badge/AndroidUtilCode-v1.22.7-brightgreen.svg +[frame]: https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/auc_frame.png + +[aucSvg]: https://github.com/Blankj/AndroidUtilCode/workflows/Android%20CI/badge.svg?branch=master [auc]: https://github.com/Blankj/AndroidUtilCode [apiSvg]: https://img.shields.io/badge/API-14+-brightgreen.svg -[api]: https://android-arsenal.com/api?level=14 +[result]: https://android-arsenal.com/result?level=14 [buildSvg]: https://travis-ci.org/Blankj/AndroidUtilCode.svg?branch=master [build]: https://travis-ci.org/Blankj/AndroidUtilCode @@ -56,11 +64,11 @@ If this project helps you a lot and you want to support the project's developmen [readme]: https://github.com/Blankj/AndroidUtilCode [readme-cn]: https://github.com/Blankj/AndroidUtilCode/blob/master/README-CN.md -[utilcode]: https://github.com/Blankj/AndroidUtilCode/blob/master/utilcode/README.md -[utilcode-cn]: https://github.com/Blankj/AndroidUtilCode/blob/master/utilcode/README-CN.md +[utilcode]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/README.md +[utilcode-cn]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/README-CN.md -[subutil]: https://github.com/Blankj/AndroidUtilCode/blob/master/subutil/README.md -[subutil-cn]: https://github.com/Blankj/AndroidUtilCode/blob/master/subutil/README-CN.md +[subutil]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/subutil/README.md +[subutil-cn]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/subutil/README-CN.md [changeLog.md]: https://github.com/Blankj/AndroidUtilCode/blob/master/CHANGELOG.md diff --git a/art/auc_frame.png b/art/auc_frame.png new file mode 100644 index 0000000000..68c92d37b1 Binary files /dev/null and b/art/auc_frame.png differ diff --git a/art/auc_frame_cn.png b/art/auc_frame_cn.png new file mode 100644 index 0000000000..2382c03197 Binary files /dev/null and b/art/auc_frame_cn.png differ diff --git a/art/busutil_vs_eventbus.png b/art/busutil_vs_eventbus.png new file mode 100644 index 0000000000..1a2272b808 Binary files /dev/null and b/art/busutil_vs_eventbus.png differ diff --git a/art/communication.png b/art/communication.png new file mode 100644 index 0000000000..f3d68d0b10 Binary files /dev/null and b/art/communication.png differ diff --git a/art/logo_static_bus.png b/art/logo_static_bus.png deleted file mode 100755 index 4f5308a13a..0000000000 Binary files a/art/logo_static_bus.png and /dev/null differ diff --git a/build.gradle b/build.gradle index 6a8c9055e5..e0f0f36c87 100644 --- a/build.gradle +++ b/build.gradle @@ -1,26 +1,26 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - apply from: 'config.gradle' + ConfigUtils.init(gradle) repositories { - if (bus.isDebug) { - maven() { - url uri(new File(project.rootDir, "maven")) - } - } + mavenLocal() google() + mavenCentral() jcenter() } dependencies { - for (plugin in dep.plugin) { - classpath plugin + for (def entrySet : ConfigUtils.getApplyPlugins().entrySet()) { + classpath entrySet.value.path } } } allprojects { repositories { + mavenLocal() + maven { url "https://jitpack.io/" } google() + mavenCentral() jcenter() } @@ -28,9 +28,9 @@ allprojects { resolutionStrategy.cacheChangingModulesFor 0, 'seconds' resolutionStrategy.eachDependency { - if (it.requested.group == 'com.android.support' - && !it.requested.name.contains('multidex')) { - it.useVersion support_version + if (it.requested.group == 'com.android.support' && !it.requested.name.contains( + 'multidex')) { + it.useVersion Config.supportVersion } } } @@ -38,4 +38,4 @@ allprojects { task clean(type: Delete) { delete rootProject.buildDir -} +} \ No newline at end of file diff --git a/buildApp.gradle b/buildApp.gradle new file mode 100644 index 0000000000..93f0b9b1d4 --- /dev/null +++ b/buildApp.gradle @@ -0,0 +1,131 @@ +apply plugin: "com.android.application" + +apply { + from "${rootDir.path}/buildCommon.gradle" + from "${rootDir.path}/config/flavor.gradle" + if (Config.plugins.plugin_api.isApply) { + plugin Config.plugins.plugin_api.id + } + if (Config.plugins.plugin_bus.isApply) { + plugin Config.plugins.plugin_bus.id + } +} + +configSigning() +configApkName() + +//if (PluginConfig.plugin_bus.isApply) { +// bus { +// onlyScanLibRegex = '^([:]|(com\\.blankj)).+$' +// } +//} +// +//if (PluginConfig.plugin_api.isApply) { +// api { +// onlyScanLibRegex = '^([:]|(com\\.blankj)).+$' +// } +//} + +android { + defaultConfig { + applicationId Config.applicationId + suffix + targetSdkVersion Config.targetSdkVersion + multiDexEnabled true + } + + buildTypes { + debug {} + + release { + minifyEnabled true + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + + packagingOptions { + exclude 'META-INF/*' + } + + dexOptions { + preDexLibraries true + javaMaxHeapSize "8g" + maxProcessCount 8 + dexInProcess = true + } + + productFlavors { + dev { + applicationIdSuffix ".dev" + versionNameSuffix "-dev" + resValue "string", "app_name", Config.appName + suffix + "-dev" + } + + production { + resValue "string", "app_name", Config.appName + suffix + } + } +} + +dependencies { + // LeakCanary + debugImplementation Config.libs.leakcanary.path + + debugImplementation Config.modules.lib_utildebug.dep + releaseImplementation Config.modules.lib_utildebug_no_op.dep + + // 根据 Config.pkgConfig 来依赖所有 pkg + for (def entrySet : ConfigUtils.getApplyPkgs().entrySet()) { + api entrySet.value.dep + } + + if (Config.modules.feature_mock.isApply) { + api ModuleConfig.modules.feature_mock.dep + } +} + +def getSuffix() { + if (project.name == "feature_launcher_app") return "" + return "." + project. + name. + substring("feature_".length(), project.name.length() - "_app".length()) +} + +def configSigning() { + + File signPropertiesFile = file("${rootDir.path}/sign/keystore.properties") + if (!signPropertiesFile.exists()) return + + GLog.d("${project.toString()} sign start...") + project.android { + Properties properties = new Properties() + properties.load(new FileInputStream(signPropertiesFile)) + signingConfigs { + release { + storeFile new File(signPropertiesFile.getParent(), properties['keystore']) + storePassword properties['storePassword'] + keyAlias properties['keyAlias'] + keyPassword properties['keyPassword'] + } + } + buildTypes.release.signingConfig signingConfigs.release + } + GLog.d("${project.toString()} sign end...") +} + +def configApkName() { + project.android.applicationVariants.all { variant -> + if (variant.buildType.name != "debug") { + def artifact = variant.getPackageApplicationProvider().get() + artifact.outputDirectory = new File("${rootDir.path}/apk") + variant.outputs.each { + it.outputFileName = "util" + suffix + + (variant.flavorName == "" ? "" : ("_" + variant.flavorName)) + + "_" + + variant.versionName.replace(".", "_") + + "_" + + variant.buildType.name + + ".apk" + } + } + } +} \ No newline at end of file diff --git a/config_lib.gradle b/buildCommon.gradle similarity index 50% rename from config_lib.gradle rename to buildCommon.gradle index 355a3ac0ee..2cba3ffea2 100644 --- a/config_lib.gradle +++ b/buildCommon.gradle @@ -1,31 +1,30 @@ apply { - plugin "com.android.library" plugin "kotlin-android" plugin "kotlin-android-extensions" } android { - compileSdkVersion rootProject.compileSdkVersion + compileSdkVersion Config.compileSdkVersion defaultConfig { - minSdkVersion rootProject.minSdkVersion - versionCode rootProject.versionCode - versionName rootProject.versionName + minSdkVersion Config.minSdkVersion + versionCode Config.versionCode + versionName Config.versionName consumerProguardFiles 'proguard-rules.pro' } buildTypes { release { - minifyEnabled false + minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + lintOptions { abortOnError false } -} - -afterEvaluate { - generateReleaseBuildConfig.enabled = false - generateDebugBuildConfig.enabled = false -} +} \ No newline at end of file diff --git a/buildLib.gradle b/buildLib.gradle new file mode 100644 index 0000000000..aed207cbee --- /dev/null +++ b/buildLib.gradle @@ -0,0 +1,13 @@ +apply plugin: "com.android.library" +apply from: "${rootDir.path}/buildCommon.gradle" + +dependencies { + if (project.name.endsWith("_pkg") || project.name.endsWith("_mock")) { + // if module's name equals 'pkg', api all of export + for (def entrySet : ConfigUtils.getApplyExports().entrySet()) { + api entrySet.value.dep + } + } else if (project.name.endsWith("_export")) { + api Config.modules.lib_common.dep + } +} \ No newline at end of file diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index eaa0a0fc0d..349aed4fec 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -1,23 +1,37 @@ -plugins { - id 'groovy' - id 'java-gradle-plugin' +repositories { + google() + jcenter() +} + +apply { + plugin 'groovy' + plugin 'java-gradle-plugin' } gradlePlugin { plugins { readmeCore { id = 'readme-core' - implementationClass = 'com.blankj.plugin.ReadmeCorePlugin' + implementationClass = 'com.blankj.plugin.readme.ReadmeCorePlugin' } readmeSub { id = 'readme-sub' - implementationClass = 'com.blankj.plugin.ReadmeSubPlugin' + implementationClass = 'com.blankj.plugin.readme.ReadmeSubPlugin' } } } dependencies { - compile gradleApi() - compile localGroovy() + implementation gradleApi() + implementation localGroovy() + implementation "commons-io:commons-io:2.6" } + +sourceSets { + main { + groovy { + srcDirs += 'src/main/java' + } + } +} \ No newline at end of file diff --git a/buildSrc/settings.gradle b/buildSrc/settings.gradle new file mode 100644 index 0000000000..8a313c3b99 --- /dev/null +++ b/buildSrc/settings.gradle @@ -0,0 +1,8 @@ +//dependencyResolutionManagement { +// repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) +// repositories { +// google() +// mavenCentral() +// jcenter() // Warning: this repository is going to shut down soon +// } +//} \ No newline at end of file diff --git a/buildSrc/src/main/groovy/Config.groovy b/buildSrc/src/main/groovy/Config.groovy new file mode 100644 index 0000000000..9a8d69d659 --- /dev/null +++ b/buildSrc/src/main/groovy/Config.groovy @@ -0,0 +1,89 @@ +class Config { + + static applicationId = 'com.blankj.androidutilcode' + static appName = 'Util' + + static compileSdkVersion = 29 + static minSdkVersion = 14 + static targetSdkVersion = 29 + static versionCode = 1_031_001 + static versionName = '1.31.1'// E.g. 1.9.72 => 1,009,072 + + // lib version + static gradlePluginVersion = '4.1.0' + static kotlinVersion = '1.3.72' + static androidxVersion = '1.0.0' + + static modules = [ + /*Don't delete this line*/ + /*Generated by "module_config.json"*/ + plugin_api_gradle_plugin : new ModuleConfig(isApply: true , useLocal: true , localPath: "./plugin/api-gradle-plugin"), + plugin_bus_gradle_plugin : new ModuleConfig(isApply: true , useLocal: true , localPath: "./plugin/bus-gradle-plugin"), + plugin_lib_base_transform : new ModuleConfig(isApply: true , useLocal: true , localPath: "./plugin/lib/base-transform", remotePath: "com.blankj:base-transform:1.0"), + plugin_buildSrc_plugin : new ModuleConfig(isApply: true , useLocal: true , localPath: "./plugin/buildSrc-plugin"), + feature_mock : new ModuleConfig(isApply: false, useLocal: true , localPath: "./feature/mock"), + feature_launcher_app : new ModuleConfig(isApply: true , useLocal: true , localPath: "./feature/launcher/app"), + feature_main_app : new ModuleConfig(isApply: false, useLocal: true , localPath: "./feature/main/app"), + feature_main_pkg : new ModuleConfig(isApply: true , useLocal: true , localPath: "./feature/main/pkg"), + feature_subutil_app : new ModuleConfig(isApply: false, useLocal: true , localPath: "./feature/subutil/app"), + feature_subutil_pkg : new ModuleConfig(isApply: true , useLocal: true , localPath: "./feature/subutil/pkg"), + feature_subutil_export : new ModuleConfig(isApply: true , useLocal: true , localPath: "./feature/subutil/export"), + feature_utilcode_app : new ModuleConfig(isApply: false, useLocal: true , localPath: "./feature/utilcode/app"), + feature_utilcode_pkg : new ModuleConfig(isApply: true , useLocal: true , localPath: "./feature/utilcode/pkg"), + feature_utilcode_export : new ModuleConfig(isApply: true , useLocal: true , localPath: "./feature/utilcode/export", remotePath: "com.blankj:utilcode-export:1.1"), + lib_base : new ModuleConfig(isApply: true , useLocal: true , localPath: "./lib/base"), + lib_common : new ModuleConfig(isApply: true , useLocal: true , localPath: "./lib/common"), + lib_subutil : new ModuleConfig(isApply: true , useLocal: true , localPath: "./lib/subutil"), + lib_utilcode : new ModuleConfig(isApply: true , useLocal: true , localPath: "./lib/utilcode", remotePath: "com.blankj:utilcodex:$Config.versionName"), + lib_utildebug : new ModuleConfig(isApply: true , useLocal: true , localPath: "./lib/utildebug"), + lib_utildebug_no_op : new ModuleConfig(isApply: true , useLocal: true , localPath: "./lib/utildebug-no-op"), + /*Don't delete this line*/ + ] + + static plugins = [ + plugin_gradle : new PluginConfig(path: "com.android.tools.build:gradle:$gradlePluginVersion"), + plugin_kotlin : new PluginConfig(path: "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"), + // 上传到 maven + plugin_maven : new PluginConfig(path: "com.github.dcendents:android-maven-gradle-plugin:2.1", id: "com.github.dcendents.android-maven"), + + // 上传新版本插件更新 path 中的版本号,并设置 isApply = false + // 通过 mavenLocal 上传本地版本,设置 isApply = true 即可应用插件来调试,最后通过 bintrayUpload 来发布插件 + plugin_api : new PluginConfig(isApply: true, useLocal: false, path: "com.blankj:api-gradle-plugin:1.5", id: "com.blankj.api"), + //./gradlew clean :plugin_api-gradle-plugin:mavenLocal // 上传到本地 mavenLocal + //./gradlew clean :plugin_api-gradle-plugin:bintrayUpload // 上传到 jcenter + plugin_bus : new PluginConfig(isApply: true, useLocal: false, path: "com.blankj:bus-gradle-plugin:2.6", id: "com.blankj.bus"), + //./gradlew clean :plugin_bus-gradle-plugin:mavenLocal // 上传到本地 mavenLocal + //./gradlew clean :plugin_bus-gradle-plugin:bintrayUpload // 上传到 jcenter + plugin_buildSrc: new PluginConfig(isApply: false, useLocal: false, path: "com.blankj:buildSrc-plugin:1.0", id: "com.blankj.buildSrc"), + //./gradlew clean :plugin_bus-gradle-plugin:mavenLocal // 上传到本地 mavenLocal + //./gradlew clean :plugin_bus-gradle-plugin:bintrayUpload // 上传到 jcenter + ] + + static libs = [ + androidx_appcompat : new LibConfig(path: "androidx.appcompat:appcompat:$androidxVersion"), + androidx_material : new LibConfig(path: "com.google.android.material:material:$androidxVersion"), + androidx_multidex : new LibConfig(path: "androidx.multidex:multidex:2.0.0"), + androidx_constraint: new LibConfig(path: "androidx.constraintlayout:constraintlayout:1.1.3"), + + kotlin : new LibConfig(path: "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion"), + + leakcanary : new LibConfig(path: "com.squareup.leakcanary:leakcanary-android:2.1"), + + free_proguard : new LibConfig(path: "com.blankj:free-proguard:1.0.2"), + swipe_panel : new LibConfig(path: "com.blankj:swipe-panel:1.2"), + + gson : new LibConfig(path: "com.google.code.gson:gson:2.8.5"), + glide : new LibConfig(path: "com.github.bumptech.glide:glide:4.7.1"), + retrofit : new LibConfig(path: "com.squareup.retrofit2:retrofit:2.4.0"), + commons_io : new LibConfig(path: "commons-io:commons-io:2.6"), + + eventbus_lib : new LibConfig(path: "org.greenrobot:eventbus:3.1.1"), + eventbus_processor : new LibConfig(path: "org.greenrobot:eventbus-annotation-processor:3.0.1"), + + photo_view : new LibConfig(path: "com.github.chrisbanes:PhotoView:2.0.0"), + + test_junit : new LibConfig(path: "junit:junit:4.12"), + test_robolectric : new LibConfig(path: "org.robolectric:robolectric:4.3.1"), + ] +} +//./gradlew clean :lib_utilcode:bintrayUpload \ No newline at end of file diff --git a/buildSrc/src/main/groovy/ConfigUtils.groovy b/buildSrc/src/main/groovy/ConfigUtils.groovy new file mode 100644 index 0000000000..6a09d2f2d9 --- /dev/null +++ b/buildSrc/src/main/groovy/ConfigUtils.groovy @@ -0,0 +1,99 @@ +import org.gradle.api.Project +import org.gradle.api.ProjectEvaluationListener +import org.gradle.api.ProjectState +import org.gradle.api.invocation.Gradle + +/** + *
+ *     author: blankj
+ *     blog  : http://blankj.com
+ *     time  : 2019/07/13
+ *     desc  :
+ * 
+ */ +class ConfigUtils { + + static init(Gradle gradle) { + generateDep(gradle) + addCommonGradle(gradle) + TaskDurationUtils.init(gradle) + } + + /** + * 根据 depConfig 生成 dep + */ + private static void generateDep(Gradle gradle) { + def configs = [:] + for (Map.Entry entry : Config.modules.entrySet()) { + def (name, config) = [entry.key, entry.value] + if (config.useLocal) { + config.dep = gradle.rootProject.findProject(name) + } else { + config.dep = config.remotePath + } + configs.put(name, config) + } + GLog.l("generateDep = ${GLog.object2String(configs)}") + } + + private static addCommonGradle(Gradle gradle) { + gradle.addProjectEvaluationListener(new ProjectEvaluationListener() { + @Override + void beforeEvaluate(Project project) { + // 在 project 的 build.gradle 前 do sth. + if (project.name.contains("plugin")) { + return + } + if (project.name.endsWith("_app")) { + GLog.l(project.toString() + " applies buildApp.gradle") + project.apply { + from "${project.rootDir.path}/buildApp.gradle" + } + } else { + GLog.l(project.toString() + " applies buildLib.gradle") + project.apply { + from "${project.rootDir.path}/buildLib.gradle" + } + } + } + + @Override + void afterEvaluate(Project project, ProjectState state) { + // 在 project 的 build.gradle 末 do sth. + } + }) + } + + static getApplyPlugins() { + def plugins = [:] + for (Map.Entry entry : Config.plugins.entrySet()) { + if (entry.value.isApply) { + plugins.put(entry.key, entry.value) + } + } + GLog.d("getApplyPlugins = ${GLog.object2String(plugins)}") + return plugins + } + + static getApplyPkgs() { + def pkgs = [:] + for (Map.Entry entry : Config.modules.entrySet()) { + if (entry.value.isApply && entry.key.endsWith("_pkg")) { + pkgs.put(entry.key, entry.value) + } + } + GLog.d("getApplyPkgs = ${GLog.object2String(pkgs)}") + return pkgs + } + + static getApplyExports() { + def exports = [:] + for (Map.Entry entry : Config.modules.entrySet()) { + if (entry.value.isApply && entry.key.endsWith("_export")) { + exports.put(entry.key, entry.value) + } + } + GLog.d("getApplyExports = ${GLog.object2String(exports)}") + return exports + } +} diff --git a/buildSrc/src/main/groovy/GLog.groovy b/buildSrc/src/main/groovy/GLog.groovy new file mode 100644 index 0000000000..6a5554fc46 --- /dev/null +++ b/buildSrc/src/main/groovy/GLog.groovy @@ -0,0 +1,208 @@ +/** + *
+ *     author: blankj
+ *     blog  : http://blankj.com
+ *     time  : 2019/07/13
+ *     desc  :
+ * 
+ */ +class GLog { + + def static debugSwitch = true + + static d(Object... contents) { + if (!debugSwitch) return contents + return l(contents) + } + + static l(Object... contents) { + StringBuilder sb = new StringBuilder() + sb.append(LogConst.BORDER_TOP) + sb.append(borderMsg(processContents(contents))) + sb.append(LogConst.BORDER_BTM) + print sb.toString() + return contents + } + + private static borderMsg(String msg) { + StringBuilder sb = new StringBuilder() + object2String(msg).split(LogConst.LINE_SEP).each { line -> + sb.append(LogConst.BORDER_LFT).append(line).append(LogConst.LINE_SEP) + } + return sb + } + + private static processContents(final Object... contents) { + String body = LogConst.NULL + if (contents != null) { + if (contents.length == 1) { + body = object2String(contents[0]) + } else { + StringBuilder sb = new StringBuilder() + int i = 0 + for (int len = contents.length; i < len; ++i) { + Object content = contents[i] + sb.append("args[$i] = ") + .append(object2String(content)) + .append(LogConst.LINE_SEP) + } + body = sb.toString() + } + } + return body.length() == 0 ? LogConst.NOTHING : body + } + + static String object2String(Object object) { + if (object == null) return "null"; + if (object.getClass().isArray()) return LogFormatter.array2String(object); + if (object instanceof List) return LogFormatter.list2String(object); + if (object instanceof Map) return LogFormatter.map2String(object); + if (object instanceof Throwable) return LogFormatter.throwable2String(object); + return object.toString(); + } + + static class LogFormatter { + + private static array2String(Object object) { + if (object instanceof Object[]) { + return Arrays.deepToString((Object[]) object); + } else if (object instanceof boolean[]) { + return Arrays.toString((boolean[]) object); + } else if (object instanceof byte[]) { + return Arrays.toString((byte[]) object); + } else if (object instanceof char[]) { + return Arrays.toString((char[]) object); + } else if (object instanceof double[]) { + return Arrays.toString((double[]) object); + } else if (object instanceof float[]) { + return Arrays.toString((float[]) object); + } else if (object instanceof int[]) { + return Arrays.toString((int[]) object); + } else if (object instanceof long[]) { + return Arrays.toString((long[]) object); + } else if (object instanceof short[]) { + return Arrays.toString((short[]) object); + } + throw new IllegalArgumentException("Array has incompatible type: " + object.getClass()); + } + + private static list2String(List list) { + StringBuilder sb = new StringBuilder() + sb.append("[") + list.each { v -> + if (v instanceof Map || v instanceof List) { + sb.append(String.format("$LogConst.LINE_SEP%${deep++ * 8}s${object2String(v)},", "")) + deep-- + } else { + sb.append(String.format("$LogConst.LINE_SEP%${deep * 8}s$v,", "")) + } + } + sb.deleteCharAt(sb.length() - 1) + if (deep - 1 == 0) { + sb.append("$LogConst.LINE_SEP]") + } else { + sb.append(String.format("$LogConst.LINE_SEP%${(deep - 1) * 8}s]", "")) + } + return sb.toString() + } + + private static deep = 1; + + private static map2String(Map map) { + StringBuilder sb = new StringBuilder() + sb.append("[") + map.each { k, v -> + if (v instanceof Map || v instanceof List) { + sb.append(String.format("$LogConst.LINE_SEP%${deep++ * 8}s%-26s: ${object2String(v)},", "", k)) + deep-- + } else { + sb.append(String.format("$LogConst.LINE_SEP%${deep * 8}s%-26s: $v,", "", k)) + } + } + sb.deleteCharAt(sb.length() - 1) + if (deep - 1 == 0) { + sb.append("$LogConst.LINE_SEP]") + } else { + sb.append(String.format("$LogConst.LINE_SEP%${(deep - 1) * 8}s]", "")) + } + return sb.toString() + } + + private static throwable2String(Throwable throwable) { + final List throwableList = new ArrayList<>(); + while (throwable != null && !throwableList.contains(throwable)) { + throwableList.add(throwable); + throwable = throwable.getCause(); + } + final int size = throwableList.size(); + final List frames = new ArrayList<>(); + List nextTrace = getStackFrameList(throwableList.get(size - 1)); + for (int i = size; --i >= 0;) { + final List trace = nextTrace; + if (i != 0) { + nextTrace = getStackFrameList(throwableList.get(i - 1)); + removeCommonFrames(trace, nextTrace); + } + if (i == size - 1) { + frames.add(throwableList.get(i).toString()); + } else { + frames.add(" Caused by: " + throwableList.get(i).toString()); + } + frames.addAll(trace); + } + StringBuilder sb = new StringBuilder(); + for (final String element : frames) { + sb.append(element).append(LogConst.LINE_SEP); + } + return sb.toString(); + } + + private static List getStackFrameList(final Throwable throwable) { + final StringWriter sw = new StringWriter(); + final PrintWriter pw = new PrintWriter(sw, true); + throwable.printStackTrace(pw); + final String stackTrace = sw.toString(); + final StringTokenizer frames = new StringTokenizer(stackTrace, LogConst.LINE_SEP); + final List list = new ArrayList<>(); + boolean traceStarted = false; + while (frames.hasMoreTokens()) { + final String token = frames.nextToken(); + // Determine if the line starts with at + final int at = token.indexOf("at"); + if (at != -1 && token.substring(0, at).trim().isEmpty()) { + traceStarted = true; + list.add(token); + } else if (traceStarted) { + break; + } + } + return list; + } + + private static void removeCommonFrames(final List causeFrames, final List wrapperFrames) { + int causeFrameIndex = causeFrames.size() - 1; + int wrapperFrameIndex = wrapperFrames.size() - 1; + while (causeFrameIndex >= 0 && wrapperFrameIndex >= 0) { + // Remove the frame from the cause trace if it is the same + // as in the wrapper trace + final String causeFrame = causeFrames.get(causeFrameIndex); + final String wrapperFrame = wrapperFrames.get(wrapperFrameIndex); + if (causeFrame.equals(wrapperFrame)) { + causeFrames.remove(causeFrameIndex); + } + causeFrameIndex--; + wrapperFrameIndex--; + } + } + } + + static class LogConst { + static LINE_SEP = System.getProperty("line.separator"); + static BORDER_TOP = "┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────" + LINE_SEP + static BORDER_LFT = "│ "; + static BORDER_BTM = "└────────────────────────────────────────────────────────────────────────────────────────────────────────────────" + LINE_SEP + + static final NOTHING = "log nothing"; + static final NULL = "null"; + } +} diff --git a/buildSrc/src/main/groovy/LibConfig.groovy b/buildSrc/src/main/groovy/LibConfig.groovy new file mode 100644 index 0000000000..6369553ba0 --- /dev/null +++ b/buildSrc/src/main/groovy/LibConfig.groovy @@ -0,0 +1,29 @@ +class LibConfig { + + String path + + String getGroupId() { + String[] splits = path.split(":") + return splits.length == 3 ? splits[0] : null + } + + String getArtifactId() { + String[] splits = path.split(":") + return splits.length == 3 ? splits[1] : null + } + + String getVersion() { + String[] splits = path.split(":") + return splits.length == 3 ? splits[2] : null + } + + @Override + String toString() { + return "LibConfig { path = $path }" + } + + static String getFlag(boolean b) { + return b ? "✅" : "❌" + } +} + diff --git a/buildSrc/src/main/groovy/ModuleConfig.groovy b/buildSrc/src/main/groovy/ModuleConfig.groovy new file mode 100644 index 0000000000..291abd8ffe --- /dev/null +++ b/buildSrc/src/main/groovy/ModuleConfig.groovy @@ -0,0 +1,35 @@ +class ModuleConfig { + + boolean isApply // 是否应用 + boolean useLocal // 是否使用本地的 + String localPath // 本地路径 + String remotePath // 远程路径 + def dep // 根据条件生成项目最终的依赖项 + + String getGroupId() { + String[] splits = remotePath.split(":") + return splits.length == 3 ? splits[0] : null + } + + String getArtifactId() { + String[] splits = remotePath.split(":") + return splits.length == 3 ? splits[1] : null + } + + String getVersion() { + String[] splits = remotePath.split(":") + return splits.length == 3 ? splits[2] : null + } + + @Override + String toString() { + return "ModuleConfig { isApply = ${getFlag(isApply)}" + + ", dep = " + dep + + " }" + } + + static String getFlag(boolean b) { + return b ? "✅" : "❌" + } +} + diff --git a/buildSrc/src/main/groovy/PluginConfig.groovy b/buildSrc/src/main/groovy/PluginConfig.groovy new file mode 100644 index 0000000000..3811c6a0ca --- /dev/null +++ b/buildSrc/src/main/groovy/PluginConfig.groovy @@ -0,0 +1,35 @@ +final class PluginConfig { + + boolean isApply = true // 是否应用 + boolean useLocal // 是否使用本地的 + String path // 插件路径 + String id // 插件 ID + + String getGroupId() { + String[] splits = path.split(":") + return splits.length == 3 ? splits[0] : null + } + + String getArtifactId() { + String[] splits = path.split(":") + return splits.length == 3 ? splits[1] : null + } + + String getVersion() { + String[] splits = path.split(":") + return splits.length == 3 ? splits[2] : null + } + + @Override + String toString() { + return "PluginConfig { isApply = ${getFlag(isApply)}" + + ", useLocal = ${getFlag(useLocal)}" + + ", path = " + path + + ", id = " + id + + " }" + } + + static String getFlag(boolean b) { + return b ? "✅" : "❌" + } +} \ No newline at end of file diff --git a/buildSrc/src/main/groovy/TaskDurationUtils.groovy b/buildSrc/src/main/groovy/TaskDurationUtils.groovy new file mode 100644 index 0000000000..6aacfcf30f --- /dev/null +++ b/buildSrc/src/main/groovy/TaskDurationUtils.groovy @@ -0,0 +1,91 @@ +import org.gradle.BuildListener +import org.gradle.BuildResult +import org.gradle.api.Task +import org.gradle.api.execution.TaskExecutionListener +import org.gradle.api.initialization.Settings +import org.gradle.api.invocation.Gradle +import org.gradle.api.tasks.TaskState + +import java.text.SimpleDateFormat + +/** + *
+ *     author: blankj
+ *     blog  : http://blankj.com
+ *     time  : 2019/11/22
+ *     desc  :
+ * 
+ */ +class TaskDurationUtils { + + static List taskInfoList = [] + static long startMillis + + static init(Gradle grd) { + startMillis = System.currentTimeMillis() + grd.addListener(new TaskExecutionListener() { + @Override + void beforeExecute(Task task) { + task.ext.startTime = System.currentTimeMillis() + } + + @Override + void afterExecute(Task task, TaskState state) { + def exeDuration = System.currentTimeMillis() - task.ext.startTime + if (exeDuration >= 500) { + taskInfoList.add(new TaskInfo(task: task, exeDuration: exeDuration)) + } + } + }) + grd.addBuildListener(new BuildListener() { + @Override + void beforeSettings(Settings settings) { + super.beforeSettings(settings) + } + + @Override + void buildStarted(Gradle gradle) {} + + @Override + void settingsEvaluated(Settings settings) {} + + @Override + void projectsLoaded(Gradle gradle) {} + + @Override + void projectsEvaluated(Gradle gradle) {} + + @Override + void buildFinished(BuildResult buildResult) { + if (!taskInfoList.isEmpty()) { + Collections.sort(taskInfoList, new Comparator() { + @Override + int compare(TaskInfo t, TaskInfo t1) { + return t1.exeDuration - t.exeDuration + } + }) + StringBuilder sb = new StringBuilder() + int buildSec = (System.currentTimeMillis() - startMillis) / 1000; + int m = buildSec / 60; + int s = buildSec % 60; + def timeInfo = (m == 0 ? "${s}s" : "${m}m ${s}s (${buildSec}s)") + sb.append("BUILD FINISHED in $timeInfo\n") + taskInfoList.each { + sb.append(String.format("%7sms %s\n", it.exeDuration, it.task.path)) + } + def content = sb.toString() + GLog.d(content) + File file = new File(grd.rootProject.buildDir.getAbsolutePath(), + "build_time_records_" + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date()) + ".txt") + file.getParentFile().mkdirs() + file.write(content) + } + } + }) + } + + private static class TaskInfo { + Task task + long exeDuration + } +} diff --git a/buildSrc/src/main/groovy/com/blankj/plugin/FormatUtils.groovy b/buildSrc/src/main/java/com/blankj/plugin/readme/FormatUtils.groovy similarity index 96% rename from buildSrc/src/main/groovy/com/blankj/plugin/FormatUtils.groovy rename to buildSrc/src/main/java/com/blankj/plugin/readme/FormatUtils.groovy index bc82b9f0f6..f617ff2eae 100644 --- a/buildSrc/src/main/groovy/com/blankj/plugin/FormatUtils.groovy +++ b/buildSrc/src/main/java/com/blankj/plugin/readme/FormatUtils.groovy @@ -1,9 +1,9 @@ -package com.blankj.plugin +package com.blankj.plugin.readme class FormatUtils { static def LINE_SEP = System.getProperty("line.separator") - static def LONG_SPACE = " " + static def LONG_SPACE = " " static def format(File readmeCN) { def sb = new StringBuilder(), diff --git a/buildSrc/src/main/groovy/com/blankj/plugin/ReadmeCorePlugin.groovy b/buildSrc/src/main/java/com/blankj/plugin/readme/ReadmeCorePlugin.groovy similarity index 71% rename from buildSrc/src/main/groovy/com/blankj/plugin/ReadmeCorePlugin.groovy rename to buildSrc/src/main/java/com/blankj/plugin/readme/ReadmeCorePlugin.groovy index af86a19c6e..8f3cf47780 100644 --- a/buildSrc/src/main/groovy/com/blankj/plugin/ReadmeCorePlugin.groovy +++ b/buildSrc/src/main/java/com/blankj/plugin/readme/ReadmeCorePlugin.groovy @@ -1,4 +1,4 @@ -package com.blankj.plugin +package com.blankj.plugin.readme import org.gradle.api.Plugin import org.gradle.api.Project @@ -30,10 +30,16 @@ class ReadmeCorePlugin implements Plugin { def sb = new StringBuilder() readmeCN.eachLine { line -> if (line.contains("* ###")) { - String utilsName = line.substring(line.indexOf("[") + 1, line.indexOf("Utils")) - sb.append("* ### About ").append(utilsName).append(line.substring(line.indexOf(" -> "))) + if (line.contains("UtilsTransActivity")) { + sb.append(line) + } else { + String utilsName = line.substring(line.indexOf("[") + 1, line.indexOf("Utils")) + sb.append("* ### About ").append(utilsName).append(line.substring(line.indexOf(" -> "))) + } } else if (line.contains(": ") && !line.contains("[")) { sb.append(line.substring(0, line.indexOf(':')).trim()) + } else if (line.contains("打个小广告") || line.contains("基你太美")) { + return } else { sb.append(line) } diff --git a/buildSrc/src/main/groovy/com/blankj/plugin/ReadmeExtension.groovy b/buildSrc/src/main/java/com/blankj/plugin/readme/ReadmeExtension.groovy similarity index 68% rename from buildSrc/src/main/groovy/com/blankj/plugin/ReadmeExtension.groovy rename to buildSrc/src/main/java/com/blankj/plugin/readme/ReadmeExtension.groovy index 91ca50af95..789e683c80 100644 --- a/buildSrc/src/main/groovy/com/blankj/plugin/ReadmeExtension.groovy +++ b/buildSrc/src/main/java/com/blankj/plugin/readme/ReadmeExtension.groovy @@ -1,4 +1,4 @@ -package com.blankj.plugin +package com.blankj.plugin.readme class ReadmeExtension { diff --git a/buildSrc/src/main/groovy/com/blankj/plugin/ReadmeSubPlugin.groovy b/buildSrc/src/main/java/com/blankj/plugin/readme/ReadmeSubPlugin.groovy similarity index 85% rename from buildSrc/src/main/groovy/com/blankj/plugin/ReadmeSubPlugin.groovy rename to buildSrc/src/main/java/com/blankj/plugin/readme/ReadmeSubPlugin.groovy index 84f688f312..bade51bbf4 100644 --- a/buildSrc/src/main/groovy/com/blankj/plugin/ReadmeSubPlugin.groovy +++ b/buildSrc/src/main/java/com/blankj/plugin/readme/ReadmeSubPlugin.groovy @@ -1,11 +1,8 @@ -package com.blankj.plugin +package com.blankj.plugin.readme import org.gradle.api.Plugin import org.gradle.api.Project -import static FormatUtils.LINE_SEP; - - class ReadmeSubPlugin implements Plugin { @Override @@ -30,9 +27,9 @@ class ReadmeSubPlugin implements Plugin { static def readmeOfSubUtil2Eng(File readmeCN, File readmeEng) { FormatUtils.format(readmeCN) def lines = readmeCN.readLines("UTF-8"), - sb = new StringBuilder("## How to use" + LINE_SEP - + LINE_SEP + - "You should copy the following classes which you want to use in your project." + LINE_SEP), + sb = new StringBuilder("## How to use" + FormatUtils.LINE_SEP + + FormatUtils.LINE_SEP + + "You should copy the following classes which you want to use in your project." + FormatUtils.LINE_SEP), i = 3, size = lines.size() for (; i < size; ++i) { @@ -45,7 +42,7 @@ class ReadmeSubPlugin implements Plugin { } else { sb.append(line) } - sb.append(LINE_SEP) + sb.append(FormatUtils.LINE_SEP) } readmeEng.write(sb.toString(), "UTF-8") } diff --git a/bus-gradle-plugin/.gitignore b/bus-gradle-plugin/.gitignore deleted file mode 100755 index 4f1e170e06..0000000000 --- a/bus-gradle-plugin/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/build -local.properties \ No newline at end of file diff --git a/bus-gradle-plugin/CHANGELOG.md b/bus-gradle-plugin/CHANGELOG.md deleted file mode 100644 index 735405d4cf..0000000000 --- a/bus-gradle-plugin/CHANGELOG.md +++ /dev/null @@ -1,22 +0,0 @@ -# Change Log - -## v1.6 -修复 inject 时候 zip 操作不对导致混淆出错的问题 - -## v1.5 -升级 javassist 来修复 Kotlin 匿名类 NotFoundException - -## v1.4 -优化 inject 兼容 Kotlin 的 bus - -## v1.3 -去除 static bus,只注入 utilcode - -## v1.2 -修复 bug - -## v1.1 -升级 javassist 版本,兼容 Java8 - -## v1.0 -发布初版本 \ No newline at end of file diff --git a/bus-gradle-plugin/build.gradle b/bus-gradle-plugin/build.gradle deleted file mode 100755 index 3abedc31ab..0000000000 --- a/bus-gradle-plugin/build.gradle +++ /dev/null @@ -1,56 +0,0 @@ -plugins { - id 'com.gradle.plugin-publish' version "0.10.0" //for pluginPublish.gradle -} - -apply { - plugin "groovy" - plugin "java-gradle-plugin" - from "${rootDir.path}/gradle/pluginPublish.gradle" - if (bus.isDebug) { - plugin "maven" - from "${rootDir.path}/gradle/localMavenUpload.gradle" - } else { - plugin "com.github.dcendents.android-maven" - plugin "com.jfrog.bintray" - from "${rootDir.path}/gradle/bintrayUploadJava.gradle" - } -} - -gradlePlugin { - plugins { - busPlugin { - id = 'com.blankj.bus' - implementationClass = 'com.blankj.bus.BusPlugin' - } - } -} - -dependencies { - implementation dep.plugin[0] - implementation dep.javassist - implementation dep.commons_io - implementation gradleApi() - implementation localGroovy() - - testImplementation dep.junit -} - -sourceSets { - main { - groovy { - srcDirs += 'src/main/java' - } - } - - test { - groovy { - srcDirs += 'src/test/java' - } - } -} - -group = bus.group -version = bus.version - -//./gradlew bus-gradle-plugin:bintrayUpload -//./gradlew publishPlugins diff --git a/bus-gradle-plugin/com/blankj/bus/BusUtils.class b/bus-gradle-plugin/com/blankj/bus/BusUtils.class deleted file mode 100644 index a706d4584e..0000000000 Binary files a/bus-gradle-plugin/com/blankj/bus/BusUtils.class and /dev/null differ diff --git a/bus-gradle-plugin/project.properties b/bus-gradle-plugin/project.properties deleted file mode 100755 index 23eb9a7453..0000000000 --- a/bus-gradle-plugin/project.properties +++ /dev/null @@ -1,6 +0,0 @@ -project.name=StaticBusPlugin -project.siteUrl=https://github.com/Blankj/StaticBus -project.gitUrl=https://github.com/Blankj/StaticBus.git - -#javadoc -javadoc.name=StaticBus \ No newline at end of file diff --git a/bus-gradle-plugin/src/main/java/com/blankj/bus/BusExtension.groovy b/bus-gradle-plugin/src/main/java/com/blankj/bus/BusExtension.groovy deleted file mode 100755 index 407a671996..0000000000 --- a/bus-gradle-plugin/src/main/java/com/blankj/bus/BusExtension.groovy +++ /dev/null @@ -1,5 +0,0 @@ -package com.blankj.bus - -class BusExtension { - -} diff --git a/bus-gradle-plugin/src/main/java/com/blankj/bus/BusInject.groovy b/bus-gradle-plugin/src/main/java/com/blankj/bus/BusInject.groovy deleted file mode 100755 index 98316776d5..0000000000 --- a/bus-gradle-plugin/src/main/java/com/blankj/bus/BusInject.groovy +++ /dev/null @@ -1,87 +0,0 @@ -package com.blankj.bus - -import com.blankj.util.JavassistUtils -import com.blankj.util.ZipUtils -import javassist.CtClass -import javassist.CtMethod -import javassist.NotFoundException -import org.apache.commons.io.FileUtils - -class BusInject { - - static void start(HashMap bus, File busJar) { - String jarPath = busJar.getAbsolutePath() - String decompressedJarPath = jarPath.substring(0, jarPath.length() - 4); - File decompressedJar = new File(decompressedJarPath) - ZipUtils.unzipFile(busJar, decompressedJar) - - CtClass busUtils = JavassistUtils.getPool().get(Config.BUS_UTILS_CLASS) - CtMethod callMethod; - try { - callMethod = busUtils.getDeclaredMethod("injectShell"); - callMethod.insertAfter(getInsertContent(bus, false)); - } catch (NotFoundException ignore) { - callMethod = busUtils.getDeclaredMethod("post"); - callMethod.insertAfter(getInsertContent(bus, true)); - } - busUtils.writeFile(decompressedJarPath) - busUtils.defrost() - FileUtils.forceDelete(busJar) - ZipUtils.zipFiles(Arrays.asList(decompressedJar.listFiles()), busJar) - FileUtils.forceDelete(decompressedJar) - } - - private static String getInsertContent(HashMap bus, boolean isLow) { - StringBuilder sb = new StringBuilder(); - bus.each { String key, String val -> - String name = key - String[] method = val.split(' ') - String returnType = method[0] - String methodName = method[1] - - sb.append('if ("').append(name).append('".equals($1)) {\n') - - int st = methodName.indexOf('(') - int end = methodName.length() - String params = methodName.substring(st + 1, end - 1); - if (params != '') { - String[] paramArr = params.split(",") - - StringBuilder args = new StringBuilder() - for (int i = 0; i < paramArr.length; i++) { - if (paramArr[i] == 'char') { - args.append(',$2[').append(i).append('].toString().charAt(0)') - } else if (paramArr[i] == 'boolean') { - args.append(',Boolean.parseBoolean($2[').append(i).append('].toString())') - } else if (paramArr[i] == 'byte') { - args.append(',Byte.parseByte($2[').append(i).append('].toString())') - } else if (paramArr[i] == 'short') { - args.append(',Short.parseShort($2[').append(i).append('].toString())') - } else if (paramArr[i] == 'int') { - args.append(',Integer.parseInt($2[').append(i).append('].toString())') - } else if (paramArr[i] == 'long') { - args.append(',Long.parseLong($2[').append(i).append('].toString())') - } else if (paramArr[i] == 'float') { - args.append(',Float.parseFloat($2[').append(i).append('].toString())') - } else if (paramArr[i] == 'double') { - args.append(',Double.parseDouble($2[').append(i).append('].toString())') - } else { - args.append(',(').append(paramArr[i]).append(')$2[').append(i).append(']') - } - } - methodName = methodName.substring(0, st + 1) + args.substring(1) + ")" - } - - if (returnType.equals('void')) { - sb.append(methodName).append(';\n').append('return null;\n') - } else { - sb.append('return ($w)').append(methodName).append(';\n') - } - sb.append("}") - } - if (isLow) { - sb.append('android.util.Log.e("BusUtils", "bus of <" + $1 + "> didn\'t exist.");') - } - return sb.toString() - } -} \ No newline at end of file diff --git a/bus-gradle-plugin/src/main/java/com/blankj/bus/BusPlugin.groovy b/bus-gradle-plugin/src/main/java/com/blankj/bus/BusPlugin.groovy deleted file mode 100755 index 72584b9037..0000000000 --- a/bus-gradle-plugin/src/main/java/com/blankj/bus/BusPlugin.groovy +++ /dev/null @@ -1,26 +0,0 @@ -package com.blankj.bus - -import com.android.build.gradle.AppExtension -import com.android.build.gradle.AppPlugin -import com.blankj.util.LogUtils - -import org.gradle.api.Plugin -import org.gradle.api.Project - -class BusPlugin implements Plugin { - - @Override - void apply(Project project) { - if (project.plugins.hasPlugin(AppPlugin)) { - LogUtils.init(project) - LogUtils.l('project(' + project.name + ') apply bus gradle plugin!') - - project.extensions.create(Config.EXT_NAME, BusExtension) - def android = project.extensions.getByType(AppExtension) - android.registerTransform(new BusTransform(project)) - project.afterEvaluate { - def ext = project[Config.EXT_NAME] as BusExtension - } - } - } -} \ No newline at end of file diff --git a/bus-gradle-plugin/src/main/java/com/blankj/bus/BusScan.groovy b/bus-gradle-plugin/src/main/java/com/blankj/bus/BusScan.groovy deleted file mode 100755 index 111686cda3..0000000000 --- a/bus-gradle-plugin/src/main/java/com/blankj/bus/BusScan.groovy +++ /dev/null @@ -1,113 +0,0 @@ -package com.blankj.bus - -import com.blankj.util.JavassistUtils -import com.blankj.util.LogUtils -import com.blankj.util.ZipUtils -import com.blankj.utilcode.util.BusUtils -import groovy.io.FileType -import javassist.CtClass -import javassist.CtField -import javassist.CtMethod -import javassist.NotFoundException -import org.apache.commons.io.FileUtils - -import java.lang.reflect.Modifier - -class BusScan { - - HashMap busMap - List scans - File busJar - - BusScan() { - busMap = [:] - scans = [] - } - - void scanJar(File jar) { - File tmp = new File(jar.getParent(), "temp_" + jar.getName()) - List unzipFile = ZipUtils.unzipFile(jar, tmp) - if (unzipFile != null && unzipFile.size() > 0) { - scanDir(tmp) - FileUtils.forceDelete(tmp) - } - } - - void scanDir(File root) { - String rootPath = root.getAbsolutePath() - if (!rootPath.endsWith(Config.FILE_SEP)) { - rootPath += Config.FILE_SEP - } - - if (root.isDirectory()) { - root.eachFileRecurse(FileType.FILES) { File file -> - def fileName = file.name - if (!fileName.endsWith('.class') - || fileName.startsWith('R$') - || fileName == 'R.class' - || fileName == 'BuildConfig.class') { - return - } - - def filePath = file.absolutePath - def packagePath = filePath.replace(rootPath, '') - def className = packagePath.replace(Config.FILE_SEP, ".") - // delete .class - className = className.substring(0, className.length() - 6) - - CtClass ctClass = JavassistUtils.getPool().get(className) - CtMethod[] methods = ctClass.getMethods(); - for (CtMethod method : methods) { - if (method.hasAnnotation(BusUtils.Subscribe.class)) { - String name = ((BusUtils.Subscribe) method.getAnnotation(BusUtils.Subscribe.class)).name(); - if (busMap.containsKey(name)) { - LogUtils.l("bus of " + name + " has registered: " + method.getLongName()); - continue; - } - String methodLongName = method.getLongName(); - if (Modifier.isStatic(method.getModifiers())) { - String sign = method.getReturnType().getName() + ' ' + methodLongName; - busMap.put(name, sign); - } else {// may be is kotlin - processKt(method, name, methodLongName) - } - } - } - } - } - } - - private void processKt(CtMethod method, String name, String longMethodName) { - CtClass ktClass = method.getDeclaringClass(); - try { - CtField instance = ktClass.getField("INSTANCE"); - LogUtils.l("find INSTANCE: " + name + ": " + longMethodName); - int i = longMethodName.lastIndexOf('('); - String temp = longMethodName.substring(0, i); - int j = temp.lastIndexOf('.'); - String sign = method.getReturnType().getName() + ' ' + - longMethodName.substring(0, j) + - ".INSTANCE" + - longMethodName.substring(j); - busMap.put(name, sign); - } catch (NotFoundException ignore) { - String innerClassSimpleName = ktClass.getSimpleName(); - if (innerClassSimpleName.contains('$') && !innerClassSimpleName.endsWith('$')) { - String innerClassName = ktClass.getName(); - String outerClassName = innerClassName.substring(0, innerClassName.lastIndexOf('$')); - CtClass outerClass = JavassistUtils.getPool().get(outerClassName); - try { - CtField ctField = outerClass.getField(innerClassSimpleName.substring(innerClassSimpleName.lastIndexOf('$') + 1)); - String fieldName = ctField.getName(); - String methodName = longMethodName.replace('$' + fieldName, '.' + fieldName); - String sign = method.getReturnType().getName() + ' ' + methodName; - busMap.put(name, sign); - } catch (NotFoundException ignored) { - LogUtils.l(longMethodName + "is not static"); - } - } else { - LogUtils.l(longMethodName + "is not static"); - } - } - } -} diff --git a/bus-gradle-plugin/src/main/java/com/blankj/bus/BusTransform.groovy b/bus-gradle-plugin/src/main/java/com/blankj/bus/BusTransform.groovy deleted file mode 100755 index 25db789307..0000000000 --- a/bus-gradle-plugin/src/main/java/com/blankj/bus/BusTransform.groovy +++ /dev/null @@ -1,129 +0,0 @@ -package com.blankj.bus - -import com.android.build.api.transform.* -import com.android.build.gradle.internal.pipeline.TransformManager -import com.blankj.util.JavassistUtils -import com.blankj.util.JsonUtils -import com.blankj.util.LogUtils - -import org.apache.commons.io.FileUtils -import org.gradle.api.Project - -class BusTransform extends Transform { - - Project mProject; - - BusTransform(Project project) { - mProject = project - } - - @Override - String getName() { - return "busTransform" - } - - @Override - Set getInputTypes() { - return TransformManager.CONTENT_CLASS - } - - @Override - Set getScopes() { - return TransformManager.SCOPE_FULL_PROJECT - } - - @Override - boolean isIncremental() { - return false - } - - @Override - void transform(TransformInvocation transformInvocation) - throws TransformException, InterruptedException, IOException { - super.transform(transformInvocation) - JavassistUtils.init(mProject) - LogUtils.l(getName() + " started") - - long stTime = System.currentTimeMillis(); - - def inputs = transformInvocation.getInputs() - def referencedInputs = transformInvocation.getReferencedInputs() - def outputProvider = transformInvocation.getOutputProvider() - def isIncremental = transformInvocation.isIncremental() - - outputProvider.deleteAll() - - BusScan busScan = new BusScan() - - inputs.each { TransformInput input -> - input.directoryInputs.each { DirectoryInput dirInput ->// 遍历文件夹 - File dir = dirInput.file - JavassistUtils.getPool().appendClassPath(dir.absolutePath) - - def dest = outputProvider.getContentLocation( - dirInput.name, - dirInput.contentTypes, - dirInput.scopes, - Format.DIRECTORY - ) - FileUtils.copyDirectory(dir, dest) - - LogUtils.l("scan dir: $dir [$dest]") - - busScan.scanDir(dir) - } - input.jarInputs.each { JarInput jarInput ->// 遍历 jar 文件 - File jar = jarInput.file - JavassistUtils.getPool().appendClassPath(jarInput.file.absolutePath) - - def jarName = jarInput.name - def dest = outputProvider.getContentLocation( - jarName, - jarInput.contentTypes, - jarInput.scopes, - Format.JAR - ) - FileUtils.copyFile(jar, dest) - - if (jarName.startsWith("com.blankj:utilcode:") - || jarName.contains("utilcode-lib")) { - busScan.busJar = dest - LogUtils.l("bus jar: $jarName [$dest]") - return - } - - if (jumpScan(jarName)) { - LogUtils.l("jump jar: $jarName [$dest]") - return - } - - LogUtils.l("scan jar: $jarName [$dest]") - busScan.scanJar(jar) - } - - } - - if (busScan.busJar != null) { - File jsonFile = new File(mProject.projectDir.getAbsolutePath(), "__bus__.json") - String busJson = JsonUtils.getFormatJson(busScan.busMap) - LogUtils.l(jsonFile.toString() + ": " + busJson) - FileUtils.write(jsonFile, busJson) - BusInject.start(busScan.busMap, busScan.busJar) - } else { - LogUtils.l('u should ') - } - - LogUtils.l(getName() + " finished: " + (System.currentTimeMillis() - stTime) + "ms") - } - - private static boolean jumpScan(String jarName) { - boolean isExcept = false - for (String except : Config.EXCEPTS) { - if (jarName.startsWith(except)) { - isExcept = true - break - } - } - isExcept - } -} \ No newline at end of file diff --git a/bus-gradle-plugin/src/main/java/com/blankj/bus/Config.groovy b/bus-gradle-plugin/src/main/java/com/blankj/bus/Config.groovy deleted file mode 100755 index 27bb63ec11..0000000000 --- a/bus-gradle-plugin/src/main/java/com/blankj/bus/Config.groovy +++ /dev/null @@ -1,20 +0,0 @@ -package com.blankj.bus - -class Config { - - public static final String EXT_NAME = 'bus' - - public static final List EXCEPTS = [ - 'com.android.support:', - 'com.android.support.constraint:', - 'android.arch.', - 'com.blankj:', - 'org.jetbrains.kotlin:', - 'org.jetbrains:', - 'com.squareup.' - ] - - public static final String FILE_SEP = System.getProperty("file.separator") - - public static final String BUS_UTILS_CLASS = 'com.blankj.utilcode.util.BusUtils' -} diff --git a/bus-gradle-plugin/src/main/java/com/blankj/util/JavassistUtils.groovy b/bus-gradle-plugin/src/main/java/com/blankj/util/JavassistUtils.groovy deleted file mode 100644 index 00c8771f70..0000000000 --- a/bus-gradle-plugin/src/main/java/com/blankj/util/JavassistUtils.groovy +++ /dev/null @@ -1,29 +0,0 @@ -package com.blankj.util - -import javassist.ClassPool -import org.gradle.api.Project; - -/** - *
- *     author: blankj
- *     blog  : http://blankj.com
- *     time  : 2018/11/25
- *     desc  :
- * 
- */ -class JavassistUtils { - - public static ClassPool sPool - - static void init(Project project) { - sPool = new ClassPool(null) - sPool.appendSystemPath() - // 加入本地 android 包 - LogUtils.l(project.android.bootClasspath[0].toString()) - sPool.appendClassPath(project.android.bootClasspath[0].toString()) - } - - static ClassPool getPool() { - return sPool - } -} diff --git a/bus-gradle-plugin/src/main/java/com/blankj/util/LogUtils.groovy b/bus-gradle-plugin/src/main/java/com/blankj/util/LogUtils.groovy deleted file mode 100755 index c51d161ea2..0000000000 --- a/bus-gradle-plugin/src/main/java/com/blankj/util/LogUtils.groovy +++ /dev/null @@ -1,34 +0,0 @@ -package com.blankj.util - -import org.gradle.api.Project -import org.gradle.api.logging.Logger - -final class LogUtils { - - private static Logger sLogger - private static String PREFIX = "PLUGIN-BUS >>> " - - static void init(Project project) { - sLogger = project.getLogger() - } - - static void l(Object content) { - sLogger.lifecycle(PREFIX + content) - } - - static void d(Object content) { - sLogger.debug(PREFIX + content) - } - - static void i(Object content) { - sLogger.info(PREFIX + content) - } - - static void w(Object content) { - sLogger.warn(PREFIX + content) - } - - static void e(Object content) { - sLogger.error(PREFIX + content) - } -} \ No newline at end of file diff --git a/bus-gradle-plugin/src/main/java/com/blankj/utilcode/util/BusUtils.java b/bus-gradle-plugin/src/main/java/com/blankj/utilcode/util/BusUtils.java deleted file mode 100755 index 507919ff49..0000000000 --- a/bus-gradle-plugin/src/main/java/com/blankj/utilcode/util/BusUtils.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.blankj.utilcode.util; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -public final class BusUtils { - - @Target({ElementType.METHOD}) - @Retention(RetentionPolicy.CLASS) - public @interface Subscribe { - String name() default ""; - } -} \ No newline at end of file diff --git a/bus-gradle-plugin/src/test/java/com/blankj/bus/BusTest.java b/bus-gradle-plugin/src/test/java/com/blankj/bus/BusTest.java deleted file mode 100755 index 9f7ef5828d..0000000000 --- a/bus-gradle-plugin/src/test/java/com/blankj/bus/BusTest.java +++ /dev/null @@ -1,162 +0,0 @@ -package com.blankj.bus; - - -/** - *
- *     author: Blankj
- *     blog  : http://blankj.com
- *     time  : 2018/09/21
- *     desc  :
- * 
- */ -public class BusTest { - -// @Test -// public void test() throws Exception { -// String rootPath = "/Users/blankj/Repo/AndroidUtilCode/app/build/intermediates/transforms/busTransform/debug/43/"; -// File root = new File(rootPath); -// ClassPool mPool = new ClassPool(null); -// mPool.appendSystemPath(); -// mPool.appendClassPath(rootPath); -// mPool.appendClassPath("/Users/blankj/Library/Android/sdk/platforms/android-27/android.jar"); -// HashMap busMap = new HashMap<>(); -// if (root.isDirectory()) { -// Collection files = FileUtils.listFiles(root, new String[]{"class"}, true); -// -// for (File file : files) { -// String fileName = file.getName(); -// -// String filePath = file.getCanonicalPath(); -// String packagePath = filePath.replace(rootPath, ""); -// String className = packagePath.replace(System.getProperty("file.separator"), "."); -// // delete .class -// className = className.substring(0, className.length() - 6); -// -// CtClass ctClass = mPool.get(className); -// -// CtMethod[] methods = ctClass.getDeclaredMethods(); -// for (CtMethod method : methods) { -// if (method.hasAnnotation(BusUtils.Subscribe.class)) { -// String name = ((BusUtils.Subscribe) method.getAnnotation(BusUtils.Subscribe.class)).name(); -// if (busMap.containsKey(name)) { -// System.out.println("bus of " + name + " has registered." + method.getLongName()); -// continue; -// } -// String longMethodName = method.getLongName(); -// if (Modifier.isStatic(method.getModifiers())) { -// String sign = method.getReturnType().getName() + ' ' + longMethodName; -// busMap.put(name, sign); -// } else {// may be is kotlin -// processKt(mPool, busMap, method, name, longMethodName); -// } -// } -// } -// } -// System.out.println(JsonUtils.getFormatJson(busMap)); -// } -// CtClass ctClass = mPool.makeClass("com.blankj.bus.BusUtils"); -// -// String src = "" + -// "public static Object post(String name, Object[] objects) {\n" + -// " if (name == null || name.length() == 0) return null;\n" + -// " return null;\n" + -// "}"; -// -// CtMethod make = CtNewMethod.make(src, ctClass); -// ctClass.addMethod(make); -// make.insertAfter(getInsertContent(busMap)); -// ctClass.debugWriteFile(); -// -// } -// -// private void processKt(ClassPool mPool, -// HashMap busMap, -// CtMethod method, String name, -// String longMethodName) throws NotFoundException { -// CtClass innerClass = method.getDeclaringClass(); -// try { -// CtField instance = innerClass.getField("INSTANCE"); -// System.out.println("find INSTANCE: " + name + ": " + longMethodName); -// int i = longMethodName.lastIndexOf('('); -// String temp = longMethodName.substring(0, i); -// int j = temp.lastIndexOf('.'); -// String sign = method.getReturnType().getName() + ' ' -// + longMethodName.substring(0, j) -// + ".INSTANCE" -// + longMethodName.substring(j); -// System.out.println(sign); -// busMap.put(name, sign); -// } catch (NotFoundException ignore) { -// String innerClassSimpleName = innerClass.getSimpleName(); -// if (innerClassSimpleName.contains("$") && !innerClassSimpleName.endsWith("$")) { -// String innerClassName = innerClass.getName(); -// String outerClassName = innerClassName.substring(0, innerClassName.lastIndexOf('$')); -// CtClass outerClass = mPool.get(outerClassName); -// try { -// CtField ctField = outerClass.getField(innerClassSimpleName.substring(innerClassSimpleName.lastIndexOf('$') + 1)); -// String fieldName = ctField.getName(); -// String methodName = longMethodName.replace("$" + fieldName, "." + fieldName); -// String sign = method.getReturnType().getName() + ' ' + methodName; -// busMap.put(name, sign); -// } catch (NotFoundException e) { -// System.out.println(longMethodName + "is not static"); -// } -// } else { -// System.out.println(longMethodName + "is not static"); -// } -// } -// } -// -// private static String getInsertContent(HashMap bus) { -// final StringBuilder sb = new StringBuilder(); -// bus.forEach(new BiConsumer() { -// @Override -// public void accept(String name, String sign) { -// String[] method = sign.split(" "); -// String returnType = method[0]; -// String methodName = method[1]; -// -// sb.append("if (\"").append(name).append("\".equals($1)) {\n"); -// -// int st = methodName.indexOf('('); -// int end = methodName.length(); -// String params = methodName.substring(st + 1, end - 1); -// if (!params.equals("")) { -// String[] paramArr = params.split(","); -// -// StringBuilder args = new StringBuilder(); -// for (int i = 0; i < paramArr.length; i++) { -// if (paramArr[i].equals("char")) { -// args.append(",$2[").append(i).append("].toString().charAt(0)"); -// } else if (paramArr[i].equals("boolean")) { -// args.append(",Boolean.parseBoolean($2[").append(i).append("].toString())"); -// } else if (paramArr[i].equals("byte")) { -// args.append(",Byte.parseByte($2[").append(i).append("].toString())"); -// } else if (paramArr[i].equals("short")) { -// args.append(",Short.parseShort($2[").append(i).append("].toString())"); -// } else if (paramArr[i].equals("int")) { -// args.append(",Integer.parseInt($2[").append(i).append("].toString())"); -// } else if (paramArr[i].equals("long")) { -// args.append(",Long.parseLong($2[").append(i).append("].toString())"); -// } else if (paramArr[i].equals("float")) { -// args.append(",Float.parseFloat($2[").append(i).append("].toString())"); -// } else if (paramArr[i].equals("double")) { -// args.append(",Double.parseDouble($2[").append(i).append("].toString())"); -// } else { -// args.append(",(").append(paramArr[i]).append(")$2[").append(i).append("]"); -// } -// } -// methodName = methodName.substring(0, st + 1) + args.substring(1) + ")"; -// } -// -// if (returnType.equals("void")) { -// sb.append(methodName).append(";\n").append("return null;\n"); -// } else { -// sb.append("return ($w)").append(methodName).append(";\n"); -// } -// sb.append("}"); -// } -// }); -// return sb.toString(); -// } -} diff --git a/config.gradle b/config.gradle deleted file mode 100644 index c5ccd57c17..0000000000 --- a/config.gradle +++ /dev/null @@ -1,57 +0,0 @@ -ext { - applicationId = 'com.blankj.androidutilcode' - appName = 'Util' - - compileSdkVersion = 27 - minSdkVersion = 14 - targetSdkVersion = 27 - versionCode = 1_022_007 - versionName = '1.22.7'// E.g. 1.9.72 => 1,009,072 - - bus = [ - isDebug: false, - version: '1.6', - group : 'com.blankj' - ] - - // lib version - kotlin_version = '1.3.0' - support_version = '27.1.1' - leakcanary_version = '1.5.4' - - dep = [ - plugin : [ - "com.android.tools.build:gradle:3.2.1", - "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version", - "com.github.dcendents:android-maven-gradle-plugin:2.1",// 上传到 maven - "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4",// 上传到 bintray - "tech.harmonysoft:traute-gradle:1.1.8",// 注解转非空判断 - "com.blankj:bus-gradle-plugin:$bus.version",// 组件化 Static Bus - ], - - // lib - support : [ - appcompat_v7: "com.android.support:appcompat-v7:$support_version", - design : "com.android.support:design:$support_version", - multidex : "com.android.support:multidex:1.0.2", - ], - constraint : "com.android.support.constraint:constraint-layout:1.1.3", - kotlin : "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version", - leakcanary : [ - android : "com.squareup.leakcanary:leakcanary-android:$leakcanary_version", - android_no_op: "com.squareup.leakcanary:leakcanary-android-no-op:$leakcanary_version", - ], - free_proguard: "com.blankj:free-proguard:0.0.7", - adapt_screen : "com.blankj:adapt-screen:0.0.3", - - gson : "com.google.code.gson:gson:2.8.2", - glide : "com.github.bumptech.glide:glide:4.7.1", - retrofit : "com.squareup.retrofit2:retrofit:2.4.0", - javassist : "org.javassist:javassist:3.24.0-GA", - commons_io : "commons-io:commons-io:2.5", - - junit : "junit:junit:4.12", - robolectric : "org.robolectric:robolectric:3.1.2", - ] -} -//./gradlew clean utilcode-lib:bintrayUpload \ No newline at end of file diff --git a/config/flavor.gradle b/config/flavor.gradle new file mode 100644 index 0000000000..25c1801983 --- /dev/null +++ b/config/flavor.gradle @@ -0,0 +1,22 @@ +android { + flavorDimensions "env" + productFlavors { + dev { + dimension "env" + } + + production { + dimension "env" + } + } + + variantFilter { variant -> + def flavorNames = variant.flavors*.name + def buildTypeName = variant.buildType.name + + // production 包不允许 debug 构建 + if (flavorNames.contains("production") && buildTypeName.contains("debug")) { + variant.setIgnore(true) + } + } +} \ No newline at end of file diff --git a/config/publish.gradle b/config/publish.gradle new file mode 100644 index 0000000000..7608215123 --- /dev/null +++ b/config/publish.gradle @@ -0,0 +1,226 @@ +/* + 1. add + signing.keyId=xx + signing.password=xx + signing.secretKeyRingFile=/Users/xx/secring.gpg + ossrhUsername=xx + ossrhPassword=xx + in root local.properties + + 2. copy the file to the directory of gradle, and apply the file in the module + ext { + groupId = Config.modules.lib_utilcode.groupId + artifactId = Config.modules.lib_utilcode.artifactId + version = Config.modules.lib_utilcode.version + website = "https://github.com/Blankj/AndroidUtilCode" +} + apply from: "${rootDir.path}/config/publish.gradle" + + 3. execute following command to publish + ./gradlew :xxmodule:publish2Local -> upload to mavenLocal + ./gradlew :xxmodule:publish2Remote -> upload to mavenCentral +*/ + +apply plugin: 'maven-publish' +apply plugin: 'signing' + +ext.multiPublishMode = true + +File localPropertiesFile = project.rootProject.file("local.properties"); +if (!localPropertiesFile.exists()) { + return +} + +Properties properties = new Properties() +properties.load(new FileInputStream(localPropertiesFile)) +properties.each { name, value -> ext[name] = value } + +afterEvaluate { + def ext = project.ext + publishing { + publications { + release(MavenPublication) { + groupId ext.groupId + artifactId ext.artifactId + version ext.version + + if (isAndroidEnv(project)) { + if (project.ext.multiPublishMode) { + artifact("$buildDir/outputs/aar/${project.getName()}-release.aar") + artifact sourcesJar + } else { + from project.components.release + } + } else { + from project.components.java + } + + pom { + name = ext.artifactId + description = ext.artifactId + url = ext.website + + licenses { + license { + name = 'The Apache Software License, Version 2.0' + url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' + } + } + developers { + developer { + id = ext.ossrhUsername + name = ext.ossrhUsername + } + } + scm { + url = ext.website + connection = ext.website + developerConnection = ext.website + ".git" + } + + if (project.ext.multiPublishMode) { + withXml { + def dependenciesNode = asNode().getAt('dependencies')[0] ?: + asNode().appendNode('dependencies') + + configurations.api.getDependencies().each { + dep -> addDependency(project, dependenciesNode, dep, "compile") + } + configurations.implementation.getDependencies().each { + dep -> addDependency(project, dependenciesNode, dep, "runtime") + } + } + } + } + } + } + + repositories { + maven { + // s01 is newest + def releasesUrl = "https://s01.oss.sonatype.org/content/repositories/releases/" + def snapshotUrl = "https://s01.oss.sonatype.org/content/repositories/snapshots/" + url = version.toUpperCase().endsWith('SNAPSHOT') ? snapshotUrl : releasesUrl + + credentials { + username ossrhUsername + password ossrhPassword + } + } + } + } + + signing { + sign publishing.publications + } +} + +private void addDependency(Project project, def dependenciesNode, Dependency dep, String scope) { + if (dep.group == null || dep.version == null || dep.name == null || dep.name == "unspecified") { + return + } + + final dependencyNode = dependenciesNode.appendNode('dependency') + dependencyNode.appendNode('scope', scope) + + if (dep.version == 'unspecified') { + // 检测 module 中的 dependencies 是否有源码依赖 + // 如果是源码依赖,而且没有在 config 中配置 remotePath, + // 那么发布到仓库,其他地方依赖该库时会找不到源码的那个库 + println "publish -> module(unspecified) <${dep.group}:${dep.name}:${dep.version}>" + if (project.ext.groupId || project.ext.version) { + throw new GradleException("The module of <" + dep.name + "> should set groupId & version.") + } + // 源码依赖,但配置了 remotePath,让 pom 中写入 remotePath + println("publish -> module(wrapped) <${project.ext.groupId}:${name}:${project.ext.version}>") + + dependencyNode.appendNode('groupId', project.ext.pomGroupID) + dependencyNode.appendNode('artifactId', dep.name) + dependencyNode.appendNode('version', project.ext.pomVersion) + } else { + dependencyNode.appendNode('groupId', dep.group) + dependencyNode.appendNode('artifactId', dep.name) + dependencyNode.appendNode('version', dep.version) + println("publish -> library <${dep.group}:${dep.name}:${dep.version}>") + } + + if (!dep.transitive) { + // In case of non transitive dependency, + // all its dependencies should be force excluded from them POM file + final exclusionNode = dependencyNode.appendNode('exclusions').appendNode('exclusion') + exclusionNode.appendNode('groupId', '*') + exclusionNode.appendNode('artifactId', '*') + } else if (!dep.properties.excludeRules.empty) { + // For transitive with exclusions, all exclude rules should be added to the POM file + final exclusions = dependencyNode.appendNode('exclusions') + dep.properties.excludeRules.each { ExcludeRule rule -> + final exclusionNode = exclusions.appendNode('exclusion') + exclusionNode.appendNode('groupId', rule.group ?: '*') + exclusionNode.appendNode('artifactId', rule.module ?: '*') + } + } +} + +if (isAndroidEnv(project)) { + // This generates sources.jar + task sourcesJar(type: Jar) { + classifier = 'sources' + from android.sourceSets.main.java.source + } + + task javadoc(type: Javadoc) { + source = android.sourceSets.main.java.source + classpath += configurations.compile + classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) + } + + task javadocJar(type: Jar, dependsOn: javadoc) { + classifier = 'javadoc' + from javadoc.destinationDir + } +} else { + task sourcesJar(type: Jar, dependsOn: classes) { + classifier = 'sources' + from sourceSets.main.allSource + } + + task javadocJar(type: Jar, dependsOn: javadoc) { + classifier = 'javadoc' + from javadoc.destinationDir + } +} + +if (project.hasProperty("kotlin")) { + // Disable creating javadocs + project.tasks.withType(Javadoc) { + enabled = false + } +} + +javadoc { + options { + encoding "UTF-8" + charSet 'UTF-8' + author true + version project.ext.version + links "http://docs.oracle.com/javase/7/docs/api" + title "${project.ext.artifactId} ${project.ext.version}" + } +} + +artifacts { + archives javadocJar + archives sourcesJar +} + +static def isAndroidEnv(Project project) { + return project.getPlugins().hasPlugin('com.android.application') || project.getPlugins().hasPlugin('com.android.library') +} + +task publish2Local(type: GradleBuild) { + tasks = ['assemble', 'publishReleasePublicationToMavenLocal'] +} + +task publish2Remote(type: GradleBuild) { + tasks = ['assemble', 'publishReleasePublicationToMavenRepository'] +} \ No newline at end of file diff --git a/config_app.gradle b/config_app.gradle deleted file mode 100644 index d2e0ce2733..0000000000 --- a/config_app.gradle +++ /dev/null @@ -1,89 +0,0 @@ -apply { - plugin "com.android.application" - plugin "kotlin-android" - plugin "kotlin-android-extensions" - plugin "com.blankj.bus" -} - -configSigning project -configApkName project - -android { - compileSdkVersion rootProject.compileSdkVersion - defaultConfig { - minSdkVersion rootProject.minSdkVersion - versionCode rootProject.versionCode - versionName rootProject.versionName - applicationId rootProject.applicationId + suffix - targetSdkVersion rootProject.targetSdkVersion - multiDexEnabled true - resValue "string", "app_name", rootProject.appName + suffix - } - - buildTypes { - debug { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - release { - minifyEnabled true - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - } - - lintOptions { - abortOnError false - } -} - - -dependencies { - // LeakCanary - debugImplementation dep.leakcanary.android - releaseImplementation dep.leakcanary.android_no_op -} - -private String getSuffix() { - if (project.name == "launcher-app") return "" - String[] splits = project.name.split("-") - String suffix = "" - if (splits.length == 2) { - suffix = "_" + splits[0] - } - return suffix -} - -def configSigning(Project pro) { - - File signPropertiesFile = file("${rootDir.path}/sign/keystore.properties") - if (!signPropertiesFile.exists()) return - - println "$pro.name config sign start..." - pro.android { - Properties properties = new Properties() - properties.load(new FileInputStream(signPropertiesFile)) - signingConfigs { - release { - storeFile new File(signPropertiesFile.getParent(), properties['keystore']) - storePassword properties['storePassword'] - keyAlias properties['keyAlias'] - keyPassword properties['keyPassword'] - } - } - buildTypes.release.signingConfig signingConfigs.release - } - println "$pro.name config sign end..." -} - -def configApkName(Project pro) { - pro.android.applicationVariants.all { variant -> - if (variant.buildType.name != "debug") { - variant.getPackageApplication().outputDirectory = new File("${rootDir.path}/apk") - variant.getPackageApplication().outputScope.apkDatas.forEach { apkData -> - apkData.outputFileName = "util" + suffix + - "_" + variant.versionName.replace(".", "_") + - ".apk" - } - } - } -} \ No newline at end of file diff --git a/launcher/app/.gitignore b/feature/launcher/app/.gitignore similarity index 100% rename from launcher/app/.gitignore rename to feature/launcher/app/.gitignore diff --git a/feature/launcher/app/build.gradle b/feature/launcher/app/build.gradle new file mode 100644 index 0000000000..8f2b6d205d --- /dev/null +++ b/feature/launcher/app/build.gradle @@ -0,0 +1,5 @@ +apply plugin: 'kotlin-kapt' + +dependencies { + kapt Config.libs.eventbus_processor.path +} \ No newline at end of file diff --git a/launcher/app/proguard-rules.pro b/feature/launcher/app/proguard-rules.pro similarity index 100% rename from launcher/app/proguard-rules.pro rename to feature/launcher/app/proguard-rules.pro diff --git a/launcher/app/src/main/AndroidManifest.xml b/feature/launcher/app/src/main/AndroidManifest.xml similarity index 69% rename from launcher/app/src/main/AndroidManifest.xml rename to feature/launcher/app/src/main/AndroidManifest.xml index bc44173799..4f033c06a6 100644 --- a/launcher/app/src/main/AndroidManifest.xml +++ b/feature/launcher/app/src/main/AndroidManifest.xml @@ -3,16 +3,19 @@ package="com.blankj.launcher.app"> + android:theme="@style/SplashTheme" + android:windowSoftInputMode="stateHidden"> diff --git a/feature/launcher/app/src/main/java/com/blankj/launcher/app/LauncherApp.java b/feature/launcher/app/src/main/java/com/blankj/launcher/app/LauncherApp.java new file mode 100644 index 0000000000..7dc22cee69 --- /dev/null +++ b/feature/launcher/app/src/main/java/com/blankj/launcher/app/LauncherApp.java @@ -0,0 +1,28 @@ +package com.blankj.launcher.app; + +import com.blankj.common.CommonApplication; + +/** + *
+ *     author: Blankj
+ *     blog  : http://blankj.com
+ *     time  : 2016/10/12
+ *     desc  :
+ * 
+ */ +public class LauncherApp extends CommonApplication { + + private static LauncherApp sInstance; + + public static LauncherApp getInstance() { + return sInstance; + } + + @Override + public void onCreate() { + super.onCreate(); + sInstance = this; + } +} + + diff --git a/launcher/pkg/.gitignore b/feature/main/app/.gitignore similarity index 100% rename from launcher/pkg/.gitignore rename to feature/main/app/.gitignore diff --git a/feature/main/app/build.gradle b/feature/main/app/build.gradle new file mode 100644 index 0000000000..e69de29bb2 diff --git a/launcher/pkg/proguard-rules.pro b/feature/main/app/proguard-rules.pro similarity index 100% rename from launcher/pkg/proguard-rules.pro rename to feature/main/app/proguard-rules.pro diff --git a/feature/main/app/src/main/AndroidManifest.xml b/feature/main/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..bb8c3398d4 --- /dev/null +++ b/feature/main/app/src/main/AndroidManifest.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/subutil/app/src/main/java/com/blankj/subutil/app/SubUtilApp.java b/feature/main/app/src/main/java/com/blankj/main/app/MainApp.java similarity index 61% rename from subutil/app/src/main/java/com/blankj/subutil/app/SubUtilApp.java rename to feature/main/app/src/main/java/com/blankj/main/app/MainApp.java index d98c2020d3..7b083b92ba 100644 --- a/subutil/app/src/main/java/com/blankj/subutil/app/SubUtilApp.java +++ b/feature/main/app/src/main/java/com/blankj/main/app/MainApp.java @@ -1,23 +1,22 @@ -package com.blankj.subutil.app; +package com.blankj.main.app; import android.content.Context; -import com.blankj.lib.base.BaseApplication; - +import com.blankj.common.CommonApplication; /** *
  *     author: Blankj
  *     blog  : http://blankj.com
  *     time  : 2016/10/12
- *     desc  : app about utils
+ *     desc  :
  * 
*/ -public class SubUtilApp extends BaseApplication { +public class MainApp extends CommonApplication { - private static SubUtilApp sInstance; + private static MainApp sInstance; - public static SubUtilApp getInstance() { + public static MainApp getInstance() { return sInstance; } diff --git a/subutil/app/.gitignore b/feature/main/pkg/.gitignore similarity index 100% rename from subutil/app/.gitignore rename to feature/main/pkg/.gitignore diff --git a/feature/main/pkg/build.gradle b/feature/main/pkg/build.gradle new file mode 100644 index 0000000000..e69de29bb2 diff --git a/subutil/app/proguard-rules.pro b/feature/main/pkg/proguard-rules.pro similarity index 100% rename from subutil/app/proguard-rules.pro rename to feature/main/pkg/proguard-rules.pro diff --git a/launcher/pkg/src/main/AndroidManifest.xml b/feature/main/pkg/src/main/AndroidManifest.xml similarity index 51% rename from launcher/pkg/src/main/AndroidManifest.xml rename to feature/main/pkg/src/main/AndroidManifest.xml index 7d1a12cfcb..1cfdba8f69 100644 --- a/launcher/pkg/src/main/AndroidManifest.xml +++ b/feature/main/pkg/src/main/AndroidManifest.xml @@ -1,11 +1,13 @@ + package="com.blankj.main.pkg"> + android:theme="@style/SplashTheme" + android:windowSoftInputMode="stateHidden" /> diff --git a/feature/main/pkg/src/main/java/com/blankj/main/pkg/MainActivity.kt b/feature/main/pkg/src/main/java/com/blankj/main/pkg/MainActivity.kt new file mode 100644 index 0000000000..b00aba9585 --- /dev/null +++ b/feature/main/pkg/src/main/java/com/blankj/main/pkg/MainActivity.kt @@ -0,0 +1,74 @@ +package com.blankj.main.pkg + +import android.graphics.Color +import android.os.Bundle +import android.view.View +import androidx.appcompat.app.ActionBarDrawerToggle +import com.blankj.common.activity.CommonActivity +import com.blankj.common.item.CommonItem +import com.blankj.common.item.CommonItemClick +import com.blankj.subutil.export.api.SubUtilApi +import com.blankj.utilcode.export.api.UtilCodeApi +import com.blankj.utilcode.util.ApiUtils +import com.blankj.utilcode.util.BarUtils +import com.blankj.utilcode.util.ClickUtils +import com.blankj.utilcode.util.CollectionUtils +import kotlinx.android.synthetic.main.activity_main.* + + +/** + * ``` + * author: Blankj + * blog : http://blankj.com + * time : 2016/09/29 + * desc : MainActivity + * ``` + */ +class MainActivity : CommonActivity() { + + override fun isSwipeBack(): Boolean { + return false + } + + override fun bindDrawer(): Boolean { + return true + } + + override fun bindLayout(): Int { + return R.layout.activity_main + } + + override fun onCreate(savedInstanceState: Bundle?) { + window.setBackgroundDrawable(null) + super.onCreate(savedInstanceState) + } + + override fun initView(savedInstanceState: Bundle?, contentView: View?) { + super.initView(savedInstanceState, contentView) + setCommonItems(mainRv, CollectionUtils.newArrayList>( + CommonItemClick(R.string.core_util, true) { + ApiUtils.getApi(UtilCodeApi::class.java)?.startUtilCodeActivity(this) + }, + CommonItemClick(R.string.sub_util, true) { + ApiUtils.getApi(SubUtilApi::class.java)?.startSubUtilActivity(this) + } + )) + + launcherMainCtl.setExpandedTitleColor(Color.TRANSPARENT) + setSupportActionBar(launcherMainToolbar) + val toggle = ActionBarDrawerToggle(this, + drawerView.mBaseDrawerRootLayout, + launcherMainToolbar, + R.string.navigation_drawer_open, + R.string.navigation_drawer_close) + drawerView.mBaseDrawerRootLayout.addDrawerListener(toggle) + toggle.syncState() + + BarUtils.setStatusBarColor4Drawer(drawerView.mBaseDrawerRootLayout, launcherMainFakeStatusBar, Color.TRANSPARENT, false) + BarUtils.addMarginTopEqualStatusBarHeight(launcherMainToolbar) + } + + override fun onBackPressed() { + ClickUtils.back2HomeFriendly("Press again to exit.") + } +} diff --git a/feature/main/pkg/src/main/java/com/blankj/main/pkg/SplashActivity.kt b/feature/main/pkg/src/main/java/com/blankj/main/pkg/SplashActivity.kt new file mode 100644 index 0000000000..9f842cda06 --- /dev/null +++ b/feature/main/pkg/src/main/java/com/blankj/main/pkg/SplashActivity.kt @@ -0,0 +1,7 @@ +package com.blankj.main.pkg + +import com.blankj.common.activity.CommonActivity + +class SplashActivity : CommonActivity() { + +} \ No newline at end of file diff --git a/launcher/pkg/src/main/res/layout/activity_main.xml b/feature/main/pkg/src/main/res/layout/activity_main.xml similarity index 52% rename from launcher/pkg/src/main/res/layout/activity_main.xml rename to feature/main/pkg/src/main/res/layout/activity_main.xml index 3b31dafe32..3a33dd0f8e 100644 --- a/launcher/pkg/src/main/res/layout/activity_main.xml +++ b/feature/main/pkg/src/main/res/layout/activity_main.xml @@ -1,17 +1,16 @@ - - - - - - + + - + app:layout_behavior="@string/appbar_scrolling_view_behavior" /> - - -