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 8a2a05788d..9d11f56a24 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,6 @@ local.properties .externalNativeBuild /apk *.phrof -/maven +/mavenLocal +/reports +*/reports \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 195511dd82..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 aR diff --git a/CHANGELOG.md b/CHANGELOG.md index fc6b83293b..73e8145bf1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,87 @@ +* `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. @@ -27,6 +111,7 @@ * `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. diff --git a/README-CN.md b/README-CN.md index 9d987223dd..5c85dca1fe 100644 --- a/README-CN.md +++ b/README-CN.md @@ -40,12 +40,16 @@ ## [Change Log][changeLog.md] +## 打个小广告 + +欢迎加入我的小专栏「**[基你太美](https://xiaozhuanlan.com/Blankj)**」一起学习。 + [logo]: https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/logo.png -[frame]: https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/auc_frame.png +[frame]: https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/auc_frame_cn.png -[aucSvg]: https://img.shields.io/badge/AndroidUtilCode-v1.25.5-brightgreen.svg +[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 diff --git a/README.md b/README.md index ac7e693288..9ae668e26e 100644 --- a/README.md +++ b/README.md @@ -40,12 +40,16 @@ 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 [frame]: https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/auc_frame.png -[aucSvg]: https://img.shields.io/badge/AndroidUtilCode-v1.25.5-brightgreen.svg +[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 diff --git a/art/auc_frame.png b/art/auc_frame.png index 2382c03197..68c92d37b1 100644 Binary files a/art/auc_frame.png 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/auc_frame_general.png b/art/auc_frame_general.png deleted file mode 100644 index 3f6b866388..0000000000 Binary files a/art/auc_frame_general.png and /dev/null 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 f03d8e43b9..e0f0f36c87 100644 --- a/build.gradle +++ b/build.gradle @@ -1,50 +1,26 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { + ConfigUtils.init(gradle) repositories { - // use for debug plugin local - if (Config.depConfig.plugin.bus.useLocal || Config.depConfig.plugin.api.useLocal) { - maven() { - url new File("maven") - } - } - maven { - url 'https://maven.aliyun.com/repository/public' - name 'replace jcenter() and mavenCentral()' - } - maven { - url 'https://maven.aliyun.com/repository/jcenter' - name 'replace jcenter()' - } - maven { - url 'https://maven.aliyun.com/repository/google' - name 'replace google()' - } + mavenLocal() google() + mavenCentral() jcenter() } dependencies { for (def entrySet : ConfigUtils.getApplyPlugins().entrySet()) { - classpath entrySet.value.dep + classpath entrySet.value.path } } } allprojects { repositories { - maven { - url 'https://maven.aliyun.com/repository/public' - name 'replace jcenter() and mavenCentral()' - } - maven { - url 'https://maven.aliyun.com/repository/jcenter' - name 'replace jcenter()' - } - maven { - url 'https://maven.aliyun.com/repository/google' - name 'replace google()' - } + mavenLocal() + maven { url "https://jitpack.io/" } google() + mavenCentral() jcenter() } @@ -52,9 +28,9 @@ allprojects { resolutionStrategy.cacheChangingModulesFor 0, 'seconds' resolutionStrategy.eachDependency { - if (it.requested.group == 'com.android.support' - && !it.requested.name.contains('multidex')) { - it.useVersion Config.support_version + if (it.requested.group == 'com.android.support' && !it.requested.name.contains( + 'multidex')) { + it.useVersion Config.supportVersion } } } @@ -62,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 index 1c87fdae14..93f0b9b1d4 100644 --- a/buildApp.gradle +++ b/buildApp.gradle @@ -1,35 +1,41 @@ +apply plugin: "com.android.application" + apply { - plugin "com.android.application" - plugin "kotlin-android" - plugin "kotlin-android-extensions" - if (Config.depConfig.plugin.bus.isApply) { - plugin "com.blankj.bus" + 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.depConfig.plugin.api.isApply) { - plugin "com.blankj.api" + 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 { - compileSdkVersion Config.compileSdkVersion defaultConfig { - minSdkVersion 16 - versionCode Config.versionCode - versionName Config.versionName applicationId Config.applicationId + suffix targetSdkVersion Config.targetSdkVersion multiDexEnabled true - resValue "string", "app_name", Config.appName + suffix } buildTypes { - debug { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } + debug {} + release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' @@ -46,33 +52,42 @@ android { 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.depConfig.leakcanary.android.dep - debugImplementation Config.depConfig.leakcanary.support_fragment.dep - releaseImplementation Config.depConfig.leakcanary.android_no_op.dep + debugImplementation Config.libs.leakcanary.path - debugImplementation 'com.didichuxing.doraemonkit:doraemonkit:1.1.8' - releaseImplementation 'com.didichuxing.doraemonkit:doraemonkit-no-op:1.1.8' + 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 } - // 如果 Config.pkgConfig 不为空,说明可能导入了部分 pkg, - // 那么可能有些 api 没有实现,需要导入 mock 层的 api - if (!Config.pkgConfig.isEmpty()) { - api Config.depConfig.feature.mock.dep + if (Config.modules.feature_mock.isApply) { + api ModuleConfig.modules.feature_mock.dep } } def getSuffix() { - if (project.path == ":feature:launcher:app") return "" - return project.path.replace(":", "_").substring(":feature".length(), project.path.length() - ":app".length()) + if (project.name == "feature_launcher_app") return "" + return "." + project. + name. + substring("feature_".length(), project.name.length() - "_app".length()) } def configSigning() { @@ -102,12 +117,14 @@ def configApkName() { if (variant.buildType.name != "debug") { def artifact = variant.getPackageApplicationProvider().get() artifact.outputDirectory = new File("${rootDir.path}/apk") - artifact.outputScope.apkDatas.forEach { apkData -> - apkData.outputFileName = "util" + suffix + - (variant.flavorName == "" ? "" : ("_" + variant.flavorName)) + - "_" + variant.versionName.replace(".", "_") + - "_" + variant.buildType.name + - ".apk" + variant.outputs.each { + it.outputFileName = "util" + suffix + + (variant.flavorName == "" ? "" : ("_" + variant.flavorName)) + + "_" + + variant.versionName.replace(".", "_") + + "_" + + variant.buildType.name + + ".apk" } } } diff --git a/buildCommon.gradle b/buildCommon.gradle new file mode 100644 index 0000000000..2cba3ffea2 --- /dev/null +++ b/buildCommon.gradle @@ -0,0 +1,30 @@ +apply { + plugin "kotlin-android" + plugin "kotlin-android-extensions" +} + +android { + compileSdkVersion Config.compileSdkVersion + defaultConfig { + minSdkVersion Config.minSdkVersion + versionCode Config.versionCode + versionName Config.versionName + consumerProguardFiles 'proguard-rules.pro' + } + + buildTypes { + release { + minifyEnabled true + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + lintOptions { + abortOnError false + } +} \ No newline at end of file diff --git a/buildLib.gradle b/buildLib.gradle index f6342eea02..aed207cbee 100644 --- a/buildLib.gradle +++ b/buildLib.gradle @@ -1,43 +1,13 @@ -apply { - plugin "com.android.library" - plugin "kotlin-android" - plugin "kotlin-android-extensions" -} - -android { - compileSdkVersion Config.compileSdkVersion - defaultConfig { - minSdkVersion Config.minSdkVersion - versionCode Config.versionCode - versionName Config.versionName - consumerProguardFiles 'proguard-rules.pro' - } - - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - consumerProguardFiles 'proguard-rules.pro' - } - } - - lintOptions { - abortOnError false - } -} - -afterEvaluate { - generateReleaseBuildConfig.enabled = false - generateDebugBuildConfig.enabled = false -} +apply plugin: "com.android.library" +apply from: "${rootDir.path}/buildCommon.gradle" dependencies { - if (project.name == 'pkg' || project.name == 'mock') { + 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 == 'export') { - api Config.depConfig.lib.common.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 37285c1c20..349aed4fec 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -12,12 +12,12 @@ 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' } } } 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 index 057aa69945..9a8d69d659 100644 --- a/buildSrc/src/main/groovy/Config.groovy +++ b/buildSrc/src/main/groovy/Config.groovy @@ -1,114 +1,89 @@ -/** - *
- *     author: blankj
- *     blog  : http://blankj.com
- *     time  : 2019/07/13
- *     desc  :
- * 
- */ class Config { static applicationId = 'com.blankj.androidutilcode' static appName = 'Util' - static compileSdkVersion = 28 + static compileSdkVersion = 29 static minSdkVersion = 14 - static targetSdkVersion = 28 - static versionCode = 1_025_005 - static versionName = '1.25.5'// E.g. 1.9.72 => 1,009,072 + static targetSdkVersion = 29 + static versionCode = 1_031_001 + static versionName = '1.31.1'// E.g. 1.9.72 => 1,009,072 // lib version - static kotlin_version = '1.3.10' - static support_version = '28.0.0' - static leakcanary_version = '1.6.3' - - // appConfig 配置的是可以跑 app 的模块,git 提交务必只包含 launcher - static appConfig = ['launcher'] - // pkgConfig 配置的是要依赖的功能包,为空则依赖全部,git 提交务必为空 - static pkgConfig = [] - - static depConfig = [ - plugin : [ - gradle : new DepConfig("com.android.tools.build:gradle:3.3.0"), - kotlin : new DepConfig("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"), - maven : new DepConfig("com.github.dcendents:android-maven-gradle-plugin:2.1"),// 上传到 maven - bintray: new DepConfig("com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4"),// 上传到 bintray - traute : new DepConfig("tech.harmonysoft:traute-gradle:1.1.10"),// 注解转非空判断 - - // 本地第一次上传插件新的版本需设置 useLocal = true, isApply = false - // 本地上传成功之后 isApply = true 即可应用插件来调试,后续版本更新无需设置 isApply = false - // 发布版本的话把 useLocal = false, isApply = false,发布成功后 isApply = true 即可使用远程库版本 - api : new DepConfig(false/*是否本地调试*/, "com.blankj:api-gradle-plugin:1.0", true/*是否使用插件*/), - bus : new DepConfig(false/*是否本地调试*/, "com.blankj:bus-gradle-plugin:2.0", true/*是否使用插件*/), - ], - - api_gradle_plugin: new DepConfig(":plugin:api-gradle-plugin", false), - bus_gradle_plugin: new DepConfig(":plugin:bus-gradle-plugin", false), - - feature : [ - mock : new DepConfig(":feature:mock"), - - launcher: [ - app: new DepConfig(":feature:launcher:app") - ], - - main : [ - app: new DepConfig(":feature:main:app"), - pkg: new DepConfig(":feature:main:pkg"), - ], + 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*/ + ] - subutil : [ - app : new DepConfig(":feature:subutil:app"), - pkg : new DepConfig(":feature:subutil:pkg"), - export: new DepConfig(":feature:subutil:export"), - ], + 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 + ] - utilcode: [ - app : new DepConfig(":feature:utilcode:app"), - pkg : new DepConfig(":feature:utilcode:pkg"), - export: new DepConfig(":feature:utilcode:export"), - ], - ], + 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"), - lib : [ - base : new DepConfig(":lib:base"), - common : new DepConfig(":lib:common"), - subutil : new DepConfig(":lib:subutil"), - utilcode : new DepConfig(true/*是否本地调试*/, ":lib:utilcode", "com.blankj:utilcode:$versionName"), - utildebug: new DepConfig(true/*是否本地调试*/, ":lib:utildebug", "com.blankj:utildebug:$versionName"), - ], + kotlin : new LibConfig(path: "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion"), - support : [ - appcompat_v7: new DepConfig("com.android.support:appcompat-v7:$support_version"), - design : new DepConfig("com.android.support:design:$support_version"), - multidex : new DepConfig("com.android.support:multidex:1.0.2"), - constraint : new DepConfig("com.android.support.constraint:constraint-layout:1.1.3"), - ], + leakcanary : new LibConfig(path: "com.squareup.leakcanary:leakcanary-android:2.1"), - kotlin : new DepConfig("org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"), + free_proguard : new LibConfig(path: "com.blankj:free-proguard:1.0.2"), + swipe_panel : new LibConfig(path: "com.blankj:swipe-panel:1.2"), - leakcanary : [ - android : new DepConfig("com.squareup.leakcanary:leakcanary-android:$leakcanary_version"), - android_no_op : new DepConfig("com.squareup.leakcanary:leakcanary-android-no-op:$leakcanary_version"), - support_fragment: new DepConfig("com.squareup.leakcanary:leakcanary-support-fragment:$leakcanary_version"), - ], + 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"), - free_proguard : new DepConfig("com.blankj:free-proguard:1.0.1"), - swipe_panel : new DepConfig("com.blankj:swipe-panel:1.1"), + eventbus_lib : new LibConfig(path: "org.greenrobot:eventbus:3.1.1"), + eventbus_processor : new LibConfig(path: "org.greenrobot:eventbus-annotation-processor:3.0.1"), - gson : new DepConfig("com.google.code.gson:gson:2.8.2"), - glide : new DepConfig("com.github.bumptech.glide:glide:4.7.1"), - retrofit : new DepConfig("com.squareup.retrofit2:retrofit:2.4.0"), - commons_io : new DepConfig("commons-io:commons-io:2.6"), - eventbus : [ - lib : new DepConfig("org.greenrobot:eventbus:3.1.1"), - processor: new DepConfig("org.greenrobot:eventbus-annotation-processor:3.0.1") - ], + photo_view : new LibConfig(path: "com.github.chrisbanes:PhotoView:2.0.0"), - test : [ - junit : new DepConfig("junit:junit:4.12"), - robolectric: new DepConfig("org.robolectric:robolectric:4.2"), - ], + 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 +//./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 index f202f25a35..6a09d2f2d9 100644 --- a/buildSrc/src/main/groovy/ConfigUtils.groovy +++ b/buildSrc/src/main/groovy/ConfigUtils.groovy @@ -1,16 +1,7 @@ -import org.apache.commons.io.FileUtils -import org.gradle.BuildListener -import org.gradle.BuildResult import org.gradle.api.Project import org.gradle.api.ProjectEvaluationListener import org.gradle.api.ProjectState -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 /** *
@@ -22,234 +13,87 @@ import java.text.SimpleDateFormat
  */
 class ConfigUtils {
 
-    static getApplyPlugins() {
-        def plugins = getDepConfigByFilter(new DepConfigFilter() {
-            @Override
-            boolean accept(String name, DepConfig config) {
-                if (!name.startsWith("plugin.")) return false
-                if (!config.isApply) return false
-                return true
-            }
-        })
-        GLog.d("getApplyPlugins = ${GLog.object2String(plugins)}")
-        return plugins
+    static init(Gradle gradle) {
+        generateDep(gradle)
+        addCommonGradle(gradle)
+        TaskDurationUtils.init(gradle)
     }
 
-    static getApplyPkgs() {
-        def applyPkgs = getDepConfigByFilter(new DepConfigFilter() {
-            @Override
-            boolean accept(String name, DepConfig config) {
-                if (!config.isApply) return false
-                return name.endsWith(".pkg")
+    /**
+     * 根据 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
             }
-        })
-        GLog.d("getApplyPkgs = ${GLog.object2String(applyPkgs)}")
-        return applyPkgs
+            configs.put(name, config)
+        }
+        GLog.l("generateDep = ${GLog.object2String(configs)}")
     }
 
-    static getApplyExports() {
-        def applyExports = getDepConfigByFilter(new DepConfigFilter() {
+    private static addCommonGradle(Gradle gradle) {
+        gradle.addProjectEvaluationListener(new ProjectEvaluationListener() {
             @Override
-            boolean accept(String name, DepConfig config) {
-                if (!config.isApply) return false
-                return name.endsWith(".export")
-            }
-        })
-        GLog.d("getApplyExports = ${GLog.object2String(applyExports)}")
-        return applyExports
-    }
-
-    static addBuildListener(Gradle gradle) {
-        gradle.addBuildListener(new ConfigBuildListener())
-    }
-
-    private static class ConfigBuildListener implements BuildListener {
-
-        private List taskInfoList = []
-        private long startBuildMillis
-
-        @Override
-        void buildStarted(Gradle gradle) {}
-
-        @Override
-        void settingsEvaluated(Settings settings) {
-            startBuildMillis = System.currentTimeMillis()
-            GLog.d("settingsEvaluated")
-            includeModule(settings)
-        }
-
-        @Override
-        void projectsLoaded(Gradle gradle) {
-            GLog.d("projectsLoaded")
-            generateDep(gradle)
-
-            gradle.addProjectEvaluationListener(new ProjectEvaluationListener() {
-                @Override
-                void beforeEvaluate(Project project) {
-                    if (project.subprojects.isEmpty()) {
-                        if (project.path.contains(":plugin:")) {
-                            return
-                        }
-                        if (project.name == "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 projectState) {
-                }
-            })
-        }
-
-        @Override
-        void projectsEvaluated(Gradle gradle) {
-            GLog.d("projectsEvaluated")
-
-            gradle.addListener(new TaskExecutionListener() {
-                @Override
-                void beforeExecute(Task task) {
-                    task.ext.startTime = System.currentTimeMillis()
+            void beforeEvaluate(Project project) {
+                // 在 project 的 build.gradle 前 do sth.
+                if (project.name.contains("plugin")) {
+                    return
                 }
-
-                @Override
-                void afterExecute(Task task, TaskState state) {
-                    def exeDuration = System.currentTimeMillis() - task.ext.startTime
-                    if (exeDuration >= 100) {
-                        taskInfoList.add(new TaskInfo(task, exeDuration))
+                if (project.name.endsWith("_app")) {
+                    GLog.l(project.toString() + " applies buildApp.gradle")
+                    project.apply {
+                        from "${project.rootDir.path}/buildApp.gradle"
                     }
-                }
-            })
-        }
-
-        @Override
-        void buildFinished(BuildResult result) {
-            GLog.d("buildFinished")
-            if (!taskInfoList.isEmpty()) {
-                Collections.sort(taskInfoList, new Comparator() {
-                    @Override
-                    int compare(TaskInfo t, TaskInfo t1) {
-                        return t1.exeDuration - t.exeDuration
+                } else {
+                    GLog.l(project.toString() + " applies buildLib.gradle")
+                    project.apply {
+                        from "${project.rootDir.path}/buildLib.gradle"
                     }
-                })
-                StringBuilder sb = new StringBuilder()
-                int buildSec = (System.currentTimeMillis() - startBuildMillis) / 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.l(content)
-                File file = new File(result.gradle.rootProject.buildDir.getAbsolutePath(),
-                        "build_time_records_" + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date()) + ".txt")
-                FileUtils.write(file, content)
             }
-        }
 
-        /**
-         * 在 settings.gradle 中 根据 appConfig 和 pkgConfig 来 include 本地模块
-         */
-        private static includeModule(Settings settings) {
-            if (Config.pkgConfig.isEmpty()) {
-                Config.depConfig.feature.mock.isApply = false
+            @Override
+            void afterEvaluate(Project project, ProjectState state) {
+                // 在 project 的 build.gradle 末 do sth.
             }
-            def config = getDepConfigByFilter(new DepConfigFilter() {
-                @Override
-                boolean accept(String name, DepConfig config) {
-                    if (name.endsWith('.app')) {
-                        def appName = name.substring('feature.'.length(), name.length() - 4)
-                        if (!Config.appConfig.contains(appName)) {
-                            config.isApply = false
-                        }
-                    }
-                    if (name.endsWith('.pkg')) {
-                        if (!Config.pkgConfig.isEmpty()) {
-                            def pkgName = name.substring('feature.'.length(), name.length() - 4)
-                            if (!Config.pkgConfig.contains(pkgName)) {
-                                config.isApply = false
-                            }
-                        }
-                    }
+        })
+    }
 
-                    if (!config.isApply) return false
-                    if (!config.useLocal) return false
-                    if (config.localPath == "") return false
-                    return true
-                }
-            }).each { _, cfg ->
-                settings.include cfg.localPath
+    static getApplyPlugins() {
+        def plugins = [:]
+        for (Map.Entry entry : Config.plugins.entrySet()) {
+            if (entry.value.isApply) {
+                plugins.put(entry.key, entry.value)
             }
-            GLog.l("includeModule = ${GLog.object2String(config)}")
-        }
-
-        /**
-         * 根据 depConfig 生成 dep
-         */
-        private static generateDep(Gradle gradle) {
-            def config = getDepConfigByFilter(new DepConfigFilter() {
-                @Override
-                boolean accept(String name, DepConfig config) {
-                    if (name.startsWith("plugin.")) {
-                        config.dep = config.remotePath
-                        return true
-                    }
-                    if (config.useLocal) {
-                        config.dep = gradle.rootProject.findProject(config.localPath)
-                    } else {
-                        config.dep = config.remotePath
-                    }
-                    return true
-                }
-            })
-            GLog.l("generateDep = ${GLog.object2String(config)}")
         }
+        GLog.d("getApplyPlugins = ${GLog.object2String(plugins)}")
+        return plugins
+    }
 
-        private static class TaskInfo {
-
-            Task task
-            long exeDuration
-
-            TaskInfo(Task task, long exeDuration) {
-                this.task = task
-                this.exeDuration = exeDuration
+    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 Map getDepConfigByFilter(DepConfigFilter filter) {
-        return _getDepConfigByFilter("", Config.depConfig, filter)
-    }
-
-    private static _getDepConfigByFilter(String namePrefix, Map map, DepConfigFilter filter) {
-        def depConfigList = [:]
-        for (Map.Entry entry : map.entrySet()) {
-            def (name, value) = [entry.getKey(), entry.getValue()]
-            if (value instanceof Map) {
-                namePrefix += (name + '.')
-                depConfigList.putAll(_getDepConfigByFilter(namePrefix, value, filter))
-                namePrefix -= (name + '.')
-                continue
-            }
-            def config = value as DepConfig
-            if (filter == null || filter.accept(namePrefix + name, config)) {
-                depConfigList.put(namePrefix + name, config)
+    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)
             }
         }
-        return depConfigList
-    }
-
-    interface DepConfigFilter {
-        boolean accept(String name, DepConfig config);
+        GLog.d("getApplyExports = ${GLog.object2String(exports)}")
+        return exports
     }
 }
diff --git a/buildSrc/src/main/groovy/DepConfig.groovy b/buildSrc/src/main/groovy/DepConfig.groovy
deleted file mode 100644
index 86e56578cf..0000000000
--- a/buildSrc/src/main/groovy/DepConfig.groovy
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * 
- *     author: blankj
- *     blog  : http://blankj.com
- *     time  : 2019/07/13
- *     desc  :
- * 
- */ -class DepConfig { - boolean useLocal // 是否使用本地的 - String localPath // 本地路径 - String remotePath// 远程路径 - boolean isApply // 是否应用 - String path // 最后的路径 - def dep // 根据条件生成项目最终的依赖项 - - DepConfig(String path) { - this(path, true) - } - - DepConfig(String path, boolean isApply) { - if (path.startsWith(":")) { - this.useLocal = true - this.localPath = path - this.isApply = isApply - } else { - this.useLocal = false - this.remotePath = path - this.isApply = isApply - } - this.path = path - } - - DepConfig(boolean useLocal, String path, boolean isApply) { // 自定义插件的构造函数 - this(useLocal, "", path, isApply) - } - - DepConfig(boolean useLocal, String localPath, String remotePath) { - this(useLocal, localPath, remotePath, true) - } - - DepConfig(boolean useLocal, String localPath, String remotePath, boolean isApply) { - this.useLocal = useLocal - this.localPath = localPath - this.remotePath = remotePath - this.isApply = isApply - this.path = useLocal ? localPath : remotePath - } - - 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 "DepConfig { " + - "useLocal = " + useLocal + - (dep == null ? ", path = " + path : (", dep = " + dep)) + - ", isApply = " + isApply + - " }" - } -} \ No newline at end of file diff --git a/buildSrc/src/main/groovy/GLog.groovy b/buildSrc/src/main/groovy/GLog.groovy index 012ca02850..6a5554fc46 100644 --- a/buildSrc/src/main/groovy/GLog.groovy +++ b/buildSrc/src/main/groovy/GLog.groovy @@ -91,7 +91,7 @@ class GLog { sb.append("[") list.each { v -> if (v instanceof Map || v instanceof List) { - sb.append(String.format("$LogConst.LINE_SEP%${deep++ * 8}s${object2String(v)},", "", k)) + 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,", "")) 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/java/com/blankj/plugin/FormatUtils.groovy b/buildSrc/src/main/java/com/blankj/plugin/readme/FormatUtils.groovy similarity index 96% rename from buildSrc/src/main/java/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/java/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/java/com/blankj/plugin/ReadmeCorePlugin.groovy b/buildSrc/src/main/java/com/blankj/plugin/readme/ReadmeCorePlugin.groovy similarity index 71% rename from buildSrc/src/main/java/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/java/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/java/com/blankj/plugin/ReadmeExtension.groovy b/buildSrc/src/main/java/com/blankj/plugin/readme/ReadmeExtension.groovy similarity index 68% rename from buildSrc/src/main/java/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/java/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/java/com/blankj/plugin/ReadmeSubPlugin.groovy b/buildSrc/src/main/java/com/blankj/plugin/readme/ReadmeSubPlugin.groovy similarity index 85% rename from buildSrc/src/main/java/com/blankj/plugin/ReadmeSubPlugin.groovy rename to buildSrc/src/main/java/com/blankj/plugin/readme/ReadmeSubPlugin.groovy index 36af34934e..bade51bbf4 100644 --- a/buildSrc/src/main/java/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/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/feature/launcher/app/build.gradle b/feature/launcher/app/build.gradle index 9320e2df30..8f2b6d205d 100644 --- a/feature/launcher/app/build.gradle +++ b/feature/launcher/app/build.gradle @@ -1,5 +1,5 @@ apply plugin: 'kotlin-kapt' dependencies { - kapt Config.depConfig.eventbus.processor.dep + kapt Config.libs.eventbus_processor.path } \ No newline at end of file diff --git a/feature/launcher/app/src/main/AndroidManifest.xml b/feature/launcher/app/src/main/AndroidManifest.xml index b683051e68..4f033c06a6 100644 --- a/feature/launcher/app/src/main/AndroidManifest.xml +++ b/feature/launcher/app/src/main/AndroidManifest.xml @@ -7,12 +7,14 @@ android:allowBackup="false" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" + android:supportsRtl="true" android:theme="@style/AppTheme"> 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 index 405e3749a8..7dc22cee69 100644 --- 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 @@ -1,7 +1,5 @@ package com.blankj.launcher.app; -import android.content.Context; - import com.blankj.common.CommonApplication; /** @@ -20,11 +18,6 @@ public static LauncherApp getInstance() { return sInstance; } - @Override - protected void attachBaseContext(Context base) { - super.attachBaseContext(base); - } - @Override public void onCreate() { super.onCreate(); diff --git a/feature/main/app/src/main/AndroidManifest.xml b/feature/main/app/src/main/AndroidManifest.xml index 5ccc1079c0..bb8c3398d4 100644 --- a/feature/main/app/src/main/AndroidManifest.xml +++ b/feature/main/app/src/main/AndroidManifest.xml @@ -13,6 +13,7 @@ android:name="com.blankj.main.pkg.MainActivity" android:configChanges="orientation|keyboardHidden|screenSize" android:screenOrientation="user" + android:theme="@style/SplashTheme" android:windowSoftInputMode="stateHidden"> diff --git a/feature/main/pkg/src/main/AndroidManifest.xml b/feature/main/pkg/src/main/AndroidManifest.xml index f24a83ec2a..1cfdba8f69 100644 --- a/feature/main/pkg/src/main/AndroidManifest.xml +++ b/feature/main/pkg/src/main/AndroidManifest.xml @@ -1,11 +1,12 @@ + package="com.blankj.main.pkg"> 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 index bfad337aab..b00aba9585 100644 --- 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 @@ -2,14 +2,17 @@ package com.blankj.main.pkg import android.graphics.Color import android.os.Bundle -import android.support.v7.app.ActionBarDrawerToggle import android.view.View -import android.widget.ImageView -import com.blankj.common.CommonDrawerActivity +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.constant.PermissionConstants import com.blankj.utilcode.export.api.UtilCodeApi -import com.blankj.utilcode.util.* +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.* @@ -21,62 +24,51 @@ import kotlinx.android.synthetic.main.activity_main.* * desc : MainActivity * ``` */ -class MainActivity : CommonDrawerActivity() { +class MainActivity : CommonActivity() { - override fun initData(bundle: Bundle?) { - - PermissionUtils.permission(PermissionConstants.CALENDAR) - .callback(object : PermissionUtils.SimpleCallback { - override fun onGranted() { - LogUtils.e() - } + override fun isSwipeBack(): Boolean { + return false + } - override fun onDenied() { - LogUtils.e() - } - }) + override fun bindDrawer(): Boolean { + return true } override fun bindLayout(): Int { return R.layout.activity_main } - private var view: ImageView? = null + 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, - mBaseDrawerRootLayout, + drawerView.mBaseDrawerRootLayout, launcherMainToolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close) - mBaseDrawerRootLayout.addDrawerListener(toggle) + drawerView.mBaseDrawerRootLayout.addDrawerListener(toggle) toggle.syncState() - BarUtils.setStatusBarColor4Drawer(mBaseDrawerRootLayout, launcherMainFakeStatusBar, Color.TRANSPARENT, false) + BarUtils.setStatusBarColor4Drawer(drawerView.mBaseDrawerRootLayout, launcherMainFakeStatusBar, Color.TRANSPARENT, false) BarUtils.addMarginTopEqualStatusBarHeight(launcherMainToolbar) - - applyDebouncingClickListener( - launcherMainCoreUtilBtn, - launcherMainSubUtilBtn - ) - } - - override fun doBusiness() {} - - override fun onDebouncingClick(view: View) { - when (view.id) { - R.id.launcherMainCoreUtilBtn -> { - ApiUtils.getApi(UtilCodeApi::class.java).startUtilCodeActivity(this) - } - R.id.launcherMainSubUtilBtn -> { - ApiUtils.getApi(SubUtilApi::class.java).startSubUtilActivity(this) - } - } } override fun onBackPressed() { - ActivityUtils.startHomeActivity() + 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 index 49d88f4f62..9f842cda06 100644 --- 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 @@ -1,31 +1,7 @@ package com.blankj.main.pkg -import android.os.Bundle -import android.view.View -import com.blankj.common.CommonBackActivity +import com.blankj.common.activity.CommonActivity -class SplashActivity : CommonBackActivity() { - override fun isSwipeBack(): Boolean { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. - } +class SplashActivity : CommonActivity() { - override fun initData(bundle: Bundle?) { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. - } - - override fun bindLayout(): Int { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. - } - - override fun initView(savedInstanceState: Bundle?, contentView: View?) { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. - } - - override fun doBusiness() { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. - } - - override fun onDebouncingClick(view: View) { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. - } } \ No newline at end of file diff --git a/feature/main/pkg/src/main/res/layout/activity_main.xml b/feature/main/pkg/src/main/res/layout/activity_main.xml index 9d757f9ef8..3a33dd0f8e 100644 --- a/feature/main/pkg/src/main/res/layout/activity_main.xml +++ b/feature/main/pkg/src/main/res/layout/activity_main.xml @@ -1,16 +1,16 @@ - - - - - - + + - + app:layout_behavior="@string/appbar_scrolling_view_behavior" /> - - -