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 index 3071e5de4e..311fc1deaa 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -8,10 +8,10 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - 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 + run: ./gradlew build aR diff --git a/.gitignore b/.gitignore index 94dfba6c2e..9d11f56a24 100644 --- a/.gitignore +++ b/.gitignore @@ -10,5 +10,6 @@ local.properties .externalNativeBuild /apk *.phrof -/maven -/reports \ No newline at end of file +/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 30c8d44b10..73e8145bf1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,65 @@ +* `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. @@ -49,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 59c3ff9950..5c85dca1fe 100644 --- a/README-CN.md +++ b/README-CN.md @@ -42,16 +42,14 @@ ## 打个小广告 -欢迎加入我的知识星球「**[基你太美](https://t.zsxq.com/FmeqfYF)**」,我会在星球中分享 [AucFrame](https://blankj.com/2019/07/22/auc-frame/) 框架、大厂面经、[AndroidUtilCode](https://github.com/Blankj/AndroidUtilCode) 更详尽的说明...一切我所了解的知识,你可以通过支付进入我的星球「**[基你太美](https://t.zsxq.com/FmeqfYF)**」进行体验,加入后优先观看星球中精华的部分,如果觉得星球的内容对自身没有收益,你可以自行申请退款退出星球,也没必要加我好友;**如果你已确定要留在我的星球,可以通过扫描如下二维码(备注:基你太美+你的星球昵称)加我个人微信,方便我后续拉你进群(PS:进得越早价格越便宜)。** - - +欢迎加入我的小专栏「**[基你太美](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_cn.png -[aucSvg]: https://img.shields.io/badge/AndroidUtilCode-v1.26.0-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 65cc565ff2..9ae668e26e 100644 --- a/README.md +++ b/README.md @@ -42,16 +42,14 @@ If this project helps you a lot and you want to support the project's developmen ## 打个小广告 -欢迎加入我的知识星球「**[基你太美](https://t.zsxq.com/FmeqfYF)**」,我会在星球中分享 [AucFrame](https://blankj.com/2019/07/22/auc-frame/) 框架、大厂面经、[AndroidUtilCode](https://github.com/Blankj/AndroidUtilCode) 更详尽的说明...一切我所了解的知识,你可以通过支付进入我的星球「**[基你太美](https://t.zsxq.com/FmeqfYF)**」进行体验,加入后优先观看星球中精华的部分,如果觉得星球的内容对自身没有收益,你可以自行申请退款退出星球,也没必要加我好友;**如果你已确定要留在我的星球,可以通过扫描如下二维码(备注:基你太美)加我个人微信,发送给我你的星球 ID,方便我后续拉你进群(PS:进得越早价格越便宜)。** - - +欢迎加入我的小专栏「**[基你太美](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.26.0-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/wechat.png b/art/wechat.png deleted file mode 100644 index e166a4783f..0000000000 Binary files a/art/wechat.png and /dev/null differ diff --git a/build.gradle b/build.gradle index 04628ed39a..e0f0f36c87 100644 --- a/build.gradle +++ b/build.gradle @@ -2,53 +2,25 @@ 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()' - } - maven { - url "https://jitpack.io" - } + mavenLocal() + maven { url "https://jitpack.io" } google() + mavenCentral() jcenter() } @@ -56,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 } } } @@ -66,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 e9cdd3ad72..93f0b9b1d4 100644 --- a/buildApp.gradle +++ b/buildApp.gradle @@ -1,53 +1,44 @@ +apply plugin: "com.android.application" + apply { - plugin "com.android.application" - plugin "kotlin-android" - plugin "kotlin-android-extensions" - if (Config.depConfig.plugin_bus.isApply) { - plugin Config.depConfig.plugin_bus.pluginId + 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 Config.depConfig.plugin_api.pluginId + if (Config.plugins.plugin_bus.isApply) { + plugin Config.plugins.plugin_bus.id } } configSigning() configApkName() -if (Config.depConfig.plugin_bus.isApply) { - bus { - onlyScanLibRegex = '^([:]|(com\\.blankj)).+$' - } -} - -if (Config.depConfig.plugin_api.isApply) { - api { - onlyScanLibRegex = '^([:]|(com\\.blankj)).+$' - } -} +//if (PluginConfig.plugin_bus.isApply) { +// bus { +// onlyScanLibRegex = '^([:]|(com\\.blankj)).+$' +// } +//} +// +//if (PluginConfig.plugin_api.isApply) { +// api { +// onlyScanLibRegex = '^([:]|(com\\.blankj)).+$' +// } +//} android { - compileSdkVersion Config.compileSdkVersion defaultConfig { - minSdkVersion Config.minSdkVersion - versionCode Config.versionCode - versionName Config.versionName applicationId Config.applicationId + suffix targetSdkVersion Config.targetSdkVersion multiDexEnabled true } buildTypes { - debug { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - applicationIdSuffix ".debug" - resValue "string", "app_name", Config.appName + suffix + ".debug" - } + debug {} release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - resValue "string", "app_name", Config.appName + suffix } } @@ -61,31 +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 Config.depConfig.lib_utildebug.dep - releaseImplementation Config.depConfig.lib_utildebug_no_op.dep + 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.depConfig.feature_mock.isApply) { - 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() { @@ -115,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 6dc9b18b2b..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 4a24413e04..9a8d69d659 100644 --- a/buildSrc/src/main/groovy/Config.groovy +++ b/buildSrc/src/main/groovy/Config.groovy @@ -1,87 +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_026_001 - static versionName = '1.26.1'// 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.50' - static support_version = '28.0.0' - static leakcanary_version = '1.6.3' + static gradlePluginVersion = '4.1.0' + static kotlinVersion = '1.3.72' + static androidxVersion = '1.0.0' - static depConfig = [ - /*Never delete this line*/ - /*Generated by "config.json"*/ - plugin_api_gradle_plugin : new DepConfig(false, true, ":plugin:api-gradle-plugin"), - plugin_bus_gradle_plugin : new DepConfig(false, true, ":plugin:bus-gradle-plugin"), - feature_mock : new DepConfig(false, true, ":feature:mock"), - feature_launcher_app : new DepConfig(true, true, ":feature:launcher:app"), - feature_main_app : new DepConfig(false, true, ":feature:main:app"), - feature_main_pkg : new DepConfig(true, true, ":feature:main:pkg"), - feature_subutil_app : new DepConfig(false, true, ":feature:subutil:app"), - feature_subutil_pkg : new DepConfig(true, true, ":feature:subutil:pkg"), - feature_subutil_export : new DepConfig(true, true, ":feature:subutil:export"), - feature_utilcode_app : new DepConfig(false, true, ":feature:utilcode:app"), - feature_utilcode_pkg : new DepConfig(true, true, ":feature:utilcode:pkg"), - feature_utilcode_export : new DepConfig(true, true, ":feature:utilcode:export"), - lib_base : new DepConfig(true, true, ":lib:base"), - lib_common : new DepConfig(true, true, ":lib:common"), - lib_subutil : new DepConfig(true, true, ":lib:subutil"), - lib_utilcode : new DepConfig(true, true, ":lib:utilcode", "com.blankj:utilcode:1.26.0"), - lib_utildebug : new DepConfig(true, true, ":lib:utildebug", "com.blankj:utildebug:1.25.10-alpha5"), - lib_utildebug_no_op : new DepConfig(true, true, ":lib:utildebug-no-op", "com.blankj:utildebug-no-op:1.25.10-alpha5"), - /*Never delete this line*/ - plugin_gradle : new DepConfig(pluginPath: "com.android.tools.build:gradle:3.5.2"), - plugin_kotlin : new DepConfig(pluginPath: "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"), - plugin_maven : new DepConfig(pluginPath: "com.github.dcendents:android-maven-gradle-plugin:2.1", pluginId: "com.github.dcendents.android-maven"),// 上传到 maven - plugin_bintray : new DepConfig(pluginPath: "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4", pluginId: "com.jfrog.bintray"),// 上传到 bintray - plugin_traute : new DepConfig(pluginPath: "tech.harmonysoft:traute-gradle:1.1.10", pluginId: "tech.harmonysoft.oss.traute"),// 注解转非空判断 + 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"), - // 本地第一次上传插件新的版本需设置 isApply = false, useLocal = true - // 本地上传成功之后 isApply = true 即可应用插件来调试,后续版本更新无需设置 isApply = false - // 发布版本的话把 isApply = false, useLocal = false,更新版本号,发布成功后 isApply = true 即可使用远程库版本 - plugin_api : new DepConfig(isApply: true, useLocal: false, pluginPath: "com.blankj:api-gradle-plugin:1.2", pluginId: "com.blankj.api"), - plugin_bus : new DepConfig(isApply: true, useLocal: false, pluginPath: "com.blankj:bus-gradle-plugin:2.4", pluginId: "com.blankj.bus"), + // 上传新版本插件更新 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 + ] - support_appcompat_v7 : new DepConfig("com.android.support:appcompat-v7:$support_version"), - support_design : new DepConfig("com.android.support:design:$support_version"), - support_multidex : new DepConfig("com.android.support:multidex:1.0.2"), - support_constraint : new DepConfig("com.android.support.constraint:constraint-layout:1.1.3"), + 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 DepConfig("org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"), + kotlin : new LibConfig(path: "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion"), - leakcanary_android : new DepConfig("com.squareup.leakcanary:leakcanary-android:$leakcanary_version"), - leakcanary_android_no_op : new DepConfig("com.squareup.leakcanary:leakcanary-android-no-op:$leakcanary_version"), - leakcanary_support_fragment: new DepConfig("com.squareup.leakcanary:leakcanary-support-fragment:$leakcanary_version"), + leakcanary : new LibConfig(path: "com.squareup.leakcanary:leakcanary-android:2.1"), - free_proguard : new DepConfig("com.blankj:free-proguard:1.0.1"), - swipe_panel : new DepConfig("com.blankj:swipe-panel:1.2"), + 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 DepConfig("com.google.code.gson:gson:2.8.6"), - 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"), + 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 DepConfig("org.greenrobot:eventbus:3.1.1"), - eventbus_processor : new DepConfig("org.greenrobot:eventbus-annotation-processor:3.0.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"), - photo_view : new DepConfig("com.github.chrisbanes:PhotoView:2.0.0"), + photo_view : new LibConfig(path: "com.github.chrisbanes:PhotoView:2.0.0"), - test_junit : new DepConfig("junit:junit:4.12"), - test_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 4fc02f91a7..6a09d2f2d9 100644 --- a/buildSrc/src/main/groovy/ConfigUtils.groovy +++ b/buildSrc/src/main/groovy/ConfigUtils.groovy @@ -17,7 +17,6 @@ class ConfigUtils { generateDep(gradle) addCommonGradle(gradle) TaskDurationUtils.init(gradle) - GitUtils.init(gradle) } /** @@ -25,16 +24,12 @@ class ConfigUtils { */ private static void generateDep(Gradle gradle) { def configs = [:] - for (Map.Entry
- * author: blankj - * blog : http://blankj.com - * time : 2019/07/13 - * desc : - *- */ -class DepConfig { - boolean isApply // 是否应用 - boolean useLocal // 是否使用本地的 - String localPath // 本地路径 - String remotePath// 远程路径 - String pluginPath// 插件路径 - String pluginId // 插件 ID - def dep // 根据条件生成项目最终的依赖项 - - DepConfig() { - isApply = true - } - - DepConfig(String path) { - this(true, path) - } - - DepConfig(boolean isApply, String path) { - if (path.startsWith(":")) { - this.useLocal = true - this.localPath = path - this.isApply = isApply - } else { - this.useLocal = false - this.remotePath = path - this.isApply = isApply - } - } - - DepConfig(boolean useLocal, String localPath, String remotePath) { - this(true, useLocal, localPath, remotePath) - } - - DepConfig(boolean isApply, boolean useLocal, String localPath) { - this(isApply, useLocal, localPath, null) - } - - DepConfig(boolean isApply, boolean useLocal, String localPath, String remotePath) { - this.isApply = isApply - this.useLocal = useLocal - this.localPath = localPath - this.remotePath = remotePath - } - - void setPluginPath(String pluginPath){ - this.pluginPath = pluginPath - this.remotePath = pluginPath - } - - String getPath() { - if (pluginPath != null) return pluginPath - return 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 "{ isApply = ${getFlag(isApply)}" + - ", useLocal = ${getFlag(useLocal)}" + - (dep == null ? ", path = " + path : (", dep = " + dep)) + - " }" - } - - static String getFlag(boolean b) { - return b ? "✅" : "❌" - } -} \ No newline at end of file diff --git a/buildSrc/src/main/groovy/GitUtils.groovy b/buildSrc/src/main/groovy/GitUtils.groovy deleted file mode 100644 index a78cb982d5..0000000000 --- a/buildSrc/src/main/groovy/GitUtils.groovy +++ /dev/null @@ -1,75 +0,0 @@ -import org.gradle.api.Action -import org.gradle.api.Project -import org.gradle.api.invocation.Gradle - -import java.text.SimpleDateFormat - -/** - *
- * author: blankj - * blog : http://blankj.com - * time : 2019/08/16 - * desc : - *- */ -class GitUtils { - - private static String sCurBranchName; - - static void init(Gradle gradle) { - gradle.rootProject(new Action
- * author: Blankj - * blog : http://blankj.com - * time : 2016/08/07 - * desc : utils about shell - *- */ -public final class ShellUtils { - - private static final String LINE_SEP = System.getProperty("line.separator"); - - private ShellUtils() { - throw new UnsupportedOperationException("u can't instantiate me..."); - } - - /** - * Execute the command. - * - * @param command The command. - * @return the single {@link CommandResult} instance - */ - public static CommandResult execCmd(final String command) { - return execCmd(new String[]{command}, false, true); - } - - /** - * Execute the command. - * - * @param command The command. - * @param isRooted True to use root, false otherwise. - * @return the single {@link CommandResult} instance - */ - public static CommandResult execCmd(final String command, final boolean isRooted) { - return execCmd(new String[]{command}, isRooted, true); - } - - /** - * Execute the command. - * - * @param commands The commands. - * @return the single {@link CommandResult} instance - */ - public static CommandResult execCmd(final List
* author: blankj diff --git a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/mvp/MvpModel.java b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/mvp/MvpModel.java index 94de5120c3..e16b4f1934 100644 --- a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/mvp/MvpModel.java +++ b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/mvp/MvpModel.java @@ -12,33 +12,33 @@ * desc : **/ -public class MvpModel extends BaseModel implements IMvp.Model { +public class MvpModel extends BaseModel implements MvpMvp.Model { private int index; @Override - public void onCreateModel() { + public void onCreate() { index = 0; } @Override - public void onDestroyModel() { - - } - - @Override - public void requestUpdateMsg(final Utils.Func1
diff --git a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/screen/ScreenActivity.kt b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/screen/ScreenActivity.kt
index 53ef761b24..88286c4df5 100644
--- a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/screen/ScreenActivity.kt
+++ b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/screen/ScreenActivity.kt
@@ -3,6 +3,8 @@ package com.blankj.utilcode.pkg.feature.screen
import android.content.Context
import android.content.Intent
import android.os.Build
+import android.widget.ImageView
+import android.widget.TextView
import com.blankj.common.activity.CommonActivity
import com.blankj.common.item.CommonItem
import com.blankj.common.item.CommonItemClick
@@ -61,10 +63,8 @@ class ScreenActivity : CommonActivity() {
CommonItemSwitch(
"isFullScreen",
- Utils.Func1 {
- ScreenUtils.isFullScreen(this)
- },
- Utils.Func1 {
+ { ScreenUtils.isFullScreen(this) },
+ {
if (it) {
ScreenUtils.setFullScreen(this)
BarUtils.setStatusBarVisibility(this, false)
@@ -76,10 +76,8 @@ class ScreenActivity : CommonActivity() {
),
CommonItemSwitch(
"isLandscape",
- Utils.Func1 {
- ScreenUtils.isLandscape()
- },
- Utils.Func1 {
+ { ScreenUtils.isLandscape() },
+ {
if (it) {
ScreenUtils.setLandscape(this)
} else {
@@ -88,7 +86,15 @@ class ScreenActivity : CommonActivity() {
}
),
CommonItemClick(R.string.screen_screenshot) {
- DialogHelper.showScreenshotDialog(ScreenUtils.screenShot(this))
+ val iv :ImageView = ImageView(this)
+ iv.setImageResource(R.mipmap.ic_launcher)
+
+ val tv: TextView = TextView(this)
+ tv.setText("wowowowwowo")
+
+ DialogHelper.showScreenshotDialog(ImageUtils.view2Bitmap(tv))
+
+// DialogHelper.showScreenshotDialog(ScreenUtils.screenShot(this))
}
)
}
diff --git a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/sdcard/SDCardActivity.kt b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/sdcard/SDCardActivity.kt
index 62d0f0a218..0c51475952 100644
--- a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/sdcard/SDCardActivity.kt
+++ b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/sdcard/SDCardActivity.kt
@@ -7,6 +7,7 @@ import com.blankj.common.item.CommonItem
import com.blankj.common.item.CommonItemTitle
import com.blankj.utilcode.pkg.R
import com.blankj.utilcode.util.CollectionUtils
+import com.blankj.utilcode.util.ConvertUtils
import com.blankj.utilcode.util.SDCardUtils
/**
@@ -35,7 +36,11 @@ class SDCardActivity : CommonActivity() {
CommonItemTitle("isSDCardEnableByEnvironment", SDCardUtils.isSDCardEnableByEnvironment().toString()),
CommonItemTitle("getSDCardPathByEnvironment", SDCardUtils.getSDCardPathByEnvironment()),
CommonItemTitle("getSDCardInfo", SDCardUtils.getSDCardInfo().toString()),
- CommonItemTitle("getMountedSDCardPath", SDCardUtils.getMountedSDCardPath().toString())
+ CommonItemTitle("getMountedSDCardPath", SDCardUtils.getMountedSDCardPath().toString()),
+ CommonItemTitle("getExternalTotalSize", ConvertUtils.byte2FitMemorySize(SDCardUtils.getExternalTotalSize(), 2)),
+ CommonItemTitle("getExternalAvailableSize", ConvertUtils.byte2FitMemorySize(SDCardUtils.getExternalAvailableSize(), 2)),
+ CommonItemTitle("getInternalTotalSize", ConvertUtils.byte2FitMemorySize(SDCardUtils.getInternalTotalSize(), 2)),
+ CommonItemTitle("getInternalAvailableSize", ConvertUtils.byte2FitMemorySize(SDCardUtils.getInternalAvailableSize(), 2))
)
}
}
diff --git a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/shadow/ShadowActivity.kt b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/shadow/ShadowActivity.kt
index fc34e89e60..2ec21ad483 100644
--- a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/shadow/ShadowActivity.kt
+++ b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/shadow/ShadowActivity.kt
@@ -39,9 +39,14 @@ class ShadowActivity : CommonActivity() {
override fun initView(savedInstanceState: Bundle?, contentView: View?) {
super.initView(savedInstanceState, contentView)
- ShadowUtils.apply(shadowRectView, Config().setShadowRadius(0.01f).setShadowColor(Color.BLUE, Color.GREEN))
- ShadowUtils.apply(shadowRoundRectView, Config().setShadowRadius(
- SizeUtils.dp2px(16f).toFloat()).setShadowColor(Color.RED, Color.BLUE))
- ShadowUtils.apply(shadowCircleView, Config().setCircle().setShadowColor(Color.GREEN, Color.BLUE))
+ ShadowUtils.apply(shadowRectView, Config().setShadowColor(0x44000000, 0x55000000))
+ ShadowUtils.apply(shadowRoundRectView, Config().setShadowColor(0x44000000, 0x55000000).setShadowRadius(
+ SizeUtils.dp2px(16f).toFloat()))
+ ShadowUtils.apply(shadowCircleView, Config().setCircle().setShadowColor(0x44000000, 0x55000000))
+
+ ShadowUtils.apply(shadowRectView1, Config().setShadowColor(0x44000000, 0x55000000))
+ ShadowUtils.apply(shadowRoundRectView1, Config().setShadowColor(0x44000000, 0x55000000).setShadowRadius(
+ SizeUtils.dp2px(16f).toFloat()))
+ ShadowUtils.apply(shadowCircleView1, Config().setCircle().setShadowColor(0x44000000, 0x55000000))
}
}
diff --git a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/snackbar/SnackbarActivity.kt b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/snackbar/SnackbarActivity.kt
index bf50677739..dcde367a5b 100644
--- a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/snackbar/SnackbarActivity.kt
+++ b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/snackbar/SnackbarActivity.kt
@@ -3,10 +3,10 @@ package com.blankj.utilcode.pkg.feature.snackbar
import android.content.Context
import android.content.Intent
import android.graphics.Color
-import android.support.annotation.StringRes
import android.text.SpannableStringBuilder
import android.view.ViewGroup
import android.widget.TextView
+import androidx.annotation.StringRes
import com.blankj.common.activity.CommonActivity
import com.blankj.common.item.CommonItem
import com.blankj.common.item.CommonItemClick
@@ -39,22 +39,37 @@ class SnackbarActivity : CommonActivity() {
override fun bindItems(): MutableList> {
return CollectionUtils.newArrayList(
- CommonItemClick(R.string.snackbar_show_short) {
+ CommonItemClick(R.string.snackbar_short) {
SnackbarUtils.with(mContentView)
.setMessage(getMsg(R.string.snackbar_short))
.setMessageColor(Color.WHITE)
.setBgResource(R.drawable.snackbar_custom_bg)
.show()
},
- CommonItemClick(R.string.snackbar_show_short_with_action) {
+ CommonItemClick(R.string.snackbar_short_top) {
SnackbarUtils.with(mContentView)
- .setMessage(getMsg(R.string.snackbar_short))
+ .setMessage(getMsg(R.string.snackbar_short_top))
+ .setMessageColor(Color.WHITE)
+ .setBgResource(R.drawable.snackbar_custom_bg)
+ .show(true)
+ },
+ CommonItemClick(R.string.snackbar_short_with_action) {
+ SnackbarUtils.with(mContentView)
+ .setMessage(getMsg(R.string.snackbar_short_with_action))
.setMessageColor(Color.WHITE)
.setBgResource(R.drawable.snackbar_custom_bg)
.setAction(getString(R.string.snackbar_click), Color.YELLOW) { ToastUtils.showShort(getString(R.string.snackbar_click)) }
.show()
},
- CommonItemClick(R.string.snackbar_show_long) {
+ CommonItemClick(R.string.snackbar_short_with_action_top) {
+ SnackbarUtils.with(mContentView)
+ .setMessage(getMsg(R.string.snackbar_short_with_action_top))
+ .setMessageColor(Color.WHITE)
+ .setBgResource(R.drawable.snackbar_custom_bg)
+ .setAction(getString(R.string.snackbar_click), Color.YELLOW) { ToastUtils.showShort(getString(R.string.snackbar_click)) }
+ .show(true)
+ },
+ CommonItemClick(R.string.snackbar_long) {
SnackbarUtils.with(mContentView)
.setMessage(getMsg(R.string.snackbar_long))
.setMessageColor(Color.WHITE)
@@ -62,16 +77,16 @@ class SnackbarActivity : CommonActivity() {
.setBgResource(R.drawable.snackbar_custom_bg)
.show()
},
- CommonItemClick(R.string.snackbar_show_long_with_action) {
+ CommonItemClick(R.string.snackbar_long_with_action) {
SnackbarUtils.with(mContentView)
- .setMessage(getMsg(R.string.snackbar_long))
+ .setMessage(getMsg(R.string.snackbar_long_with_action))
.setMessageColor(Color.WHITE)
.setBgResource(R.drawable.snackbar_custom_bg)
.setDuration(SnackbarUtils.LENGTH_LONG)
.setAction(getString(R.string.snackbar_click), Color.YELLOW) { ToastUtils.showShort(getString(R.string.snackbar_click)) }
.show()
},
- CommonItemClick(R.string.snackbar_show_indefinite) {
+ CommonItemClick(R.string.snackbar_indefinite) {
SnackbarUtils.with(mContentView)
.setMessage(getMsg(R.string.snackbar_indefinite))
.setMessageColor(Color.WHITE)
@@ -79,9 +94,9 @@ class SnackbarActivity : CommonActivity() {
.setBgResource(R.drawable.snackbar_custom_bg)
.show()
},
- CommonItemClick(R.string.snackbar_show_indefinite_with_action) {
+ CommonItemClick(R.string.snackbar_indefinite_with_action) {
SnackbarUtils.with(mContentView)
- .setMessage(getMsg(R.string.snackbar_indefinite))
+ .setMessage(getMsg(R.string.snackbar_indefinite_with_action))
.setMessageColor(Color.WHITE)
.setDuration(SnackbarUtils.LENGTH_INDEFINITE)
.setBgResource(R.drawable.snackbar_custom_bg)
@@ -113,17 +128,17 @@ class SnackbarActivity : CommonActivity() {
snackbarView.setOnClickListener { SnackbarUtils.dismiss() }
}
},
- CommonItemClick(R.string.snackbar_show_success) {
+ CommonItemClick(R.string.snackbar_success) {
SnackbarUtils.with(mContentView)
.setMessage(getMsg(R.string.snackbar_success))
.showSuccess()
},
- CommonItemClick(R.string.snackbar_show_warning) {
+ CommonItemClick(R.string.snackbar_warning) {
SnackbarUtils.with(mContentView)
.setMessage(getMsg(R.string.snackbar_warning))
.showWarning()
},
- CommonItemClick(R.string.snackbar_show_error) {
+ CommonItemClick(R.string.snackbar_error) {
SnackbarUtils.with(mContentView)
.setMessage(getMsg(R.string.snackbar_error))
.showError()
diff --git a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/span/SpanActivity.kt b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/span/SpanActivity.kt
index bf5d46b154..84c9f868bb 100644
--- a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/span/SpanActivity.kt
+++ b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/span/SpanActivity.kt
@@ -5,7 +5,6 @@ import android.content.Context
import android.content.Intent
import android.graphics.*
import android.os.Bundle
-import android.support.annotation.ColorInt
import android.text.Layout
import android.text.SpannableStringBuilder
import android.text.TextPaint
@@ -14,6 +13,7 @@ import android.text.style.ClickableSpan
import android.text.style.UpdateAppearance
import android.view.View
import android.view.animation.LinearInterpolator
+import androidx.annotation.ColorInt
import com.blankj.common.activity.CommonActivity
import com.blankj.utilcode.pkg.R
import com.blankj.utilcode.util.SpanUtils
@@ -81,6 +81,7 @@ class SpanActivity : CommonActivity() {
SpanUtils.with(spanAboutTv)
.appendLine("SpanUtils").setBackgroundColor(Color.LTGRAY).setBold().setForegroundColor(Color.YELLOW).setHorizontalAlign(Layout.Alignment.ALIGN_CENTER)
.appendLine("前景色").setForegroundColor(Color.GREEN)
+// .appendLine("测试哈哈").setForegroundColor(Color.RED).setBackgroundColor(Color.LTGRAY).setFontSize(10).setLineHeight(280, SpanUtils.ALIGN_BOTTOM)
.appendLine("背景色").setBackgroundColor(Color.LTGRAY)
.appendLine("行高居中对齐").setLineHeight(2 * lineHeight, SpanUtils.ALIGN_CENTER).setBackgroundColor(Color.LTGRAY)
.appendLine("行高底部对齐").setLineHeight(2 * lineHeight, SpanUtils.ALIGN_BOTTOM).setBackgroundColor(Color.GREEN)
diff --git a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/toast/CustomToast.kt b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/toast/CustomToast.kt
index 314ba33d59..f0b6876ad4 100644
--- a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/toast/CustomToast.kt
+++ b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/toast/CustomToast.kt
@@ -1,14 +1,11 @@
package com.blankj.utilcode.pkg.feature.toast
-import android.os.Handler
-import android.os.Looper
-import android.support.annotation.StringRes
import android.widget.TextView
-import android.widget.Toast
-
+import androidx.annotation.StringRes
import com.blankj.utilcode.pkg.R
+import com.blankj.utilcode.util.StringUtils
import com.blankj.utilcode.util.ToastUtils
-import com.blankj.utilcode.util.Utils
+import com.blankj.utilcode.util.ViewUtils
/**
* ```
@@ -20,62 +17,42 @@ import com.blankj.utilcode.util.Utils
*/
object CustomToast {
- private val HANDLER = Handler(Looper.getMainLooper())
-
fun showShort(text: CharSequence) {
- showReal(text, Toast.LENGTH_SHORT)
+ show(text, false)
}
fun showShort(@StringRes resId: Int) {
- show(resId, Toast.LENGTH_SHORT)
+ show(StringUtils.getString(resId), false)
}
fun showShort(@StringRes resId: Int, vararg args: Any) {
- show(resId, Toast.LENGTH_SHORT, *args)
+ show(StringUtils.getString(resId, args), false)
}
fun showShort(format: String, vararg args: Any) {
- show(format, Toast.LENGTH_SHORT, *args)
+ show(StringUtils.format(format, args), false)
}
fun showLong(text: CharSequence) {
- showReal(text, Toast.LENGTH_LONG)
+ show(text, true)
}
fun showLong(@StringRes resId: Int) {
- show(resId, Toast.LENGTH_LONG)
+ show(StringUtils.getString(resId), true)
}
fun showLong(@StringRes resId: Int, vararg args: Any) {
- show(resId, Toast.LENGTH_LONG, *args)
+ show(StringUtils.getString(resId, args), true)
}
fun showLong(format: String, vararg args: Any) {
- show(format, Toast.LENGTH_LONG, *args)
- }
-
- private fun show(@StringRes resId: Int, duration: Int) {
- show(Utils.getApp().resources.getString(resId), duration)
- }
-
- private fun show(@StringRes resId: Int, duration: Int, vararg args: Any) {
- show(String.format(Utils.getApp().resources.getString(resId), *args), duration)
- }
-
- private fun show(format: String, duration: Int, vararg args: Any) {
- showReal(String.format(format, *args), duration)
+ show(StringUtils.format(format, args), true)
}
- private fun showReal(text: CharSequence, duration: Int) {
- HANDLER.post {
- val toastView: TextView
- if (duration == Toast.LENGTH_SHORT) {
- toastView = ToastUtils.showCustomShort(R.layout.toast_custom) as TextView
- } else {
- toastView = ToastUtils.showCustomLong(R.layout.toast_custom) as TextView
- }
- toastView.text = text
- }
+ private fun show(text: CharSequence, isLong: Boolean) {
+ val textView = ViewUtils.layoutId2View(R.layout.toast_custom) as TextView
+ textView.text = text
+ ToastUtils.make().setDurationIsLong(isLong).show(textView)
}
fun cancel() {
diff --git a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/toast/ToastActivity.kt b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/toast/ToastActivity.kt
index b62d9b33f8..f4267ad3a9 100644
--- a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/toast/ToastActivity.kt
+++ b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/toast/ToastActivity.kt
@@ -3,14 +3,15 @@ package com.blankj.utilcode.pkg.feature.toast
import android.content.Context
import android.content.Intent
import android.graphics.Color
-import android.support.v4.content.ContextCompat
import android.view.Gravity
+import androidx.core.content.ContextCompat
import com.blankj.common.activity.CommonActivity
import com.blankj.common.item.CommonItem
import com.blankj.common.item.CommonItemClick
import com.blankj.utilcode.pkg.R
import com.blankj.utilcode.pkg.helper.DialogHelper
import com.blankj.utilcode.util.CollectionUtils
+import com.blankj.utilcode.util.ColorUtils
import com.blankj.utilcode.util.SpanUtils
import com.blankj.utilcode.util.ToastUtils
@@ -38,30 +39,18 @@ class ToastActivity : CommonActivity() {
override fun bindItems(): MutableList> {
return CollectionUtils.newArrayList(
CommonItemClick(R.string.toast_show_short) {
- resetToast()
Thread(Runnable { ToastUtils.showShort(R.string.toast_short) }).start()
},
CommonItemClick(R.string.toast_show_long) {
- resetToast()
Thread(Runnable { ToastUtils.showLong(R.string.toast_long) }).start()
},
- CommonItemClick(R.string.toast_show_green_font) {
- resetToast()
- ToastUtils.setMsgColor(Color.GREEN)
- ToastUtils.showLong(R.string.toast_green_font)
- },
- CommonItemClick(R.string.toast_show_bg_color) {
- resetToast()
- ToastUtils.setBgColor(ContextCompat.getColor(this, R.color.colorAccent))
- ToastUtils.showLong(R.string.toast_bg_color)
+ CommonItemClick(R.string.toast_show_null) {
+ ToastUtils.showLong(null)
},
- CommonItemClick(R.string.toast_show_bg_resource) {
- resetToast()
- ToastUtils.setBgResource(R.drawable.toast_round_rect)
- ToastUtils.showLong(R.string.toast_custom_bg)
+ CommonItemClick(R.string.toast_show_empty) {
+ ToastUtils.showLong("")
},
CommonItemClick(R.string.toast_show_span) {
- resetToast()
ToastUtils.showLong(
SpanUtils()
.appendImage(R.mipmap.ic_launcher, SpanUtils.ALIGN_CENTER)
@@ -70,34 +59,43 @@ class ToastActivity : CommonActivity() {
.create()
)
},
- CommonItemClick(R.string.toast_show_custom_view) {
- resetToast()
- Thread(Runnable { CustomToast.showLong(R.string.toast_custom_view) }).start()
+ CommonItemClick(R.string.toast_show_long_string) {
+ ToastUtils.showLong(R.string.toast_long_string)
+ },
+ CommonItemClick(R.string.toast_show_green_font) {
+ ToastUtils.make().setTextColor(Color.GREEN).setDurationIsLong(true).show(R.string.toast_green_font)
+ },
+ CommonItemClick(R.string.toast_show_bg_color) {
+ ToastUtils.make().setBgColor(ColorUtils.getColor(R.color.colorAccent)).show(R.string.toast_bg_color)
+ },
+ CommonItemClick(R.string.toast_show_bg_resource) {
+ ToastUtils.make().setBgResource(R.drawable.toast_round_rect).show(R.string.toast_custom_bg)
+ },
+ CommonItemClick(R.string.toast_show_left_icon) {
+ ToastUtils.make().setLeftIcon(R.mipmap.ic_launcher).show(R.string.toast_show_left_icon)
+ },
+ CommonItemClick(R.string.toast_show_dark_mode) {
+ ToastUtils.make().setTopIcon(R.mipmap.ic_launcher).setMode(ToastUtils.MODE.DARK).show(R.string.toast_show_dark_mode)
},
CommonItemClick(R.string.toast_show_middle) {
- resetToast()
- ToastUtils.setGravity(Gravity.CENTER, 0, 0)
- ToastUtils.showLong(R.string.toast_middle)
+ ToastUtils.make().setGravity(Gravity.CENTER, 0, 0).show(R.string.toast_middle)
+ },
+ CommonItemClick(R.string.toast_show_top) {
+ ToastUtils.make().setGravity(Gravity.TOP or Gravity.CENTER_HORIZONTAL, 0, 0).show(R.string.toast_top)
+ },
+ CommonItemClick(R.string.toast_show_custom_view) {
+ Thread(Runnable { CustomToast.showLong(R.string.toast_custom_view) }).start()
},
CommonItemClick(R.string.toast_cancel) {
ToastUtils.cancel()
},
CommonItemClick(R.string.toast_show_toast_dialog) {
- resetToast()
DialogHelper.showToastDialog()
+ },
+ CommonItemClick(R.string.toast_show_toast_when_start_activity) {
+ ToastUtils.showLong(R.string.toast_show_toast_when_start_activity)
+ start(this)
}
)
}
-
- override fun onDestroy() {
- resetToast()
- super.onDestroy()
- }
-
- private fun resetToast() {
- ToastUtils.setMsgColor(-0x1000001)
- ToastUtils.setBgColor(-0x1000001)
- ToastUtils.setBgResource(-1)
- ToastUtils.setGravity(-1, -1, -1)
- }
}
diff --git a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/uiMessage/UiMessageActivity.kt b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/uiMessage/UiMessageActivity.kt
new file mode 100644
index 0000000000..a486645654
--- /dev/null
+++ b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/uiMessage/UiMessageActivity.kt
@@ -0,0 +1,78 @@
+package com.blankj.utilcode.pkg.feature.uiMessage
+
+import android.content.Context
+import android.content.Intent
+import com.blankj.common.activity.CommonActivity
+import com.blankj.common.item.CommonItem
+import com.blankj.common.item.CommonItemClick
+import com.blankj.common.item.CommonItemTitle
+import com.blankj.utilcode.pkg.R
+import com.blankj.utilcode.util.CollectionUtils
+import com.blankj.utilcode.util.UiMessageUtils
+
+
+/**
+ * ```
+ * author: Blankj
+ * blog : http://blankj.com
+ * time : 2020/04/14
+ * desc : demo about UiMessageUtils
+ * ```
+ */
+class UiMessageActivity : CommonActivity(), UiMessageUtils.UiMessageCallback {
+
+ private val titleItem: CommonItemTitle = CommonItemTitle("", true);
+ private var sendContent: String = ""
+
+ companion object {
+ fun start(context: Context) {
+ val starter = Intent(context, UiMessageActivity::class.java)
+ context.startActivity(starter)
+ }
+ }
+
+ override fun bindTitleRes(): Int {
+ return R.string.demo_uiMessage
+ }
+
+ override fun bindItems(): List> {
+ return CollectionUtils.newArrayList(
+ titleItem,
+ CommonItemClick(R.string.uiMessage_add_listener_id) {
+ UiMessageUtils.getInstance().addListener(R.id.utilCodeUiMessageAddListenerId, this)
+ },
+ CommonItemClick(R.string.uiMessage_remove_all_id) {
+ UiMessageUtils.getInstance().removeListeners(R.id.utilCodeUiMessageAddListenerId)
+ },
+ CommonItemClick(R.string.uiMessage_add_listener) {
+ UiMessageUtils.getInstance().addListener(this)
+ },
+ CommonItemClick(R.string.uiMessage_remove_listener) {
+ UiMessageUtils.getInstance().removeListener(this)
+ },
+ CommonItemClick(R.string.uiMessage_send) {
+ sendContent = "send: UiMessageActivity#${UiMessageActivity.hashCode()}"
+ titleItem.title = ""
+ UiMessageUtils.getInstance().send(R.id.utilCodeUiMessageAddListenerId, UiMessageActivity)
+ }
+ )
+ }
+
+ override fun handleMessage(localMessage: UiMessageUtils.UiMessage) {
+ if (localMessage.id == R.id.utilCodeUiMessageAddListenerId) {
+ var content: String = sendContent
+ content += "\nreceive: UiMessageActivity#${localMessage.getObject().hashCode()}"
+ titleItem.title = if (titleItem.title.toString().isEmpty()) {
+ content
+ } else {
+ titleItem.title.toString() + "\n" + content
+ }
+ }
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ UiMessageUtils.getInstance().removeListeners(R.id.utilCodeUiMessageAddListenerId)
+ UiMessageUtils.getInstance().removeListener(this)
+ }
+}
\ No newline at end of file
diff --git a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/vibrate/VibrateActivity.kt b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/vibrate/VibrateActivity.kt
index d2cd9bc147..5dc337bc5b 100644
--- a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/vibrate/VibrateActivity.kt
+++ b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/vibrate/VibrateActivity.kt
@@ -32,11 +32,23 @@ class VibrateActivity : CommonActivity() {
override fun bindItems(): MutableList> {
return CollectionUtils.newArrayList(
- CommonItemClick(R.string.vibrate_1000ms) { VibrateUtils.vibrate(1000) },
+ CommonItemClick(R.string.vibrate_1000ms) {
+ VibrateUtils.vibrate(1000)
+ },
CommonItemClick(R.string.vibrate_custom) {
VibrateUtils.vibrate(longArrayOf(0, 1000, 1000, 2000, 2000, 1000), 1)
},
- CommonItemClick(R.string.vibrate_cancel) { VibrateUtils.cancel() }
+ CommonItemClick(R.string.vibrate_background) {
+ backHome()
+ mContentView.postDelayed({
+// VibrateUtils.vibrate(1000) -- can not vibrate in background
+ VibrateUtils.vibrateCompat(longArrayOf(0, 1000, 1000, 2000, 2000, 1000), 1)
+// VibrateUtils.vibrateCompat(1000)
+ }, 1000)
+ },
+ CommonItemClick(R.string.vibrate_cancel) {
+ VibrateUtils.cancel()
+ }
)
}
@@ -44,4 +56,11 @@ class VibrateActivity : CommonActivity() {
super.onDestroy()
VibrateUtils.cancel()
}
+
+ private fun backHome() {
+ val intent = Intent(Intent.ACTION_MAIN).apply {
+ addCategory(Intent.CATEGORY_HOME)
+ }
+ startActivity(intent)
+ }
}
diff --git a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/volume/VolumeActivity.kt b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/volume/VolumeActivity.kt
new file mode 100644
index 0000000000..26d67dda07
--- /dev/null
+++ b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/volume/VolumeActivity.kt
@@ -0,0 +1,63 @@
+package com.blankj.utilcode.pkg.feature.volume
+
+import android.content.Context
+import android.content.Intent
+import android.media.AudioManager
+import android.widget.SeekBar
+import com.blankj.common.activity.CommonActivity
+import com.blankj.common.item.CommonItem
+import com.blankj.common.item.CommonItemSeekBar
+import com.blankj.utilcode.pkg.R
+import com.blankj.utilcode.util.CollectionUtils
+import com.blankj.utilcode.util.VolumeUtils
+
+/**
+ * ```
+ * author: Blankj
+ * blog : http://blankj.com
+ * time : 2018/12/29
+ * desc : demo about VibrateUtils
+ * ```
+ */
+class VolumeActivity : CommonActivity() {
+
+ companion object {
+ fun start(context: Context) {
+ val starter = Intent(context, VolumeActivity::class.java)
+ context.startActivity(starter)
+ }
+ }
+
+ override fun bindTitleRes(): Int {
+ return R.string.demo_volume
+ }
+
+ override fun bindItems(): MutableList> {
+ return CollectionUtils.newArrayList(
+ getItemSeekBar("Voice Call", AudioManager.STREAM_VOICE_CALL),
+ getItemSeekBar("System", AudioManager.STREAM_SYSTEM),
+ getItemSeekBar("Music", AudioManager.STREAM_MUSIC),
+ getItemSeekBar("Ring", AudioManager.STREAM_RING),
+ getItemSeekBar("Alarm", AudioManager.STREAM_ALARM),
+ getItemSeekBar("Notification", AudioManager.STREAM_NOTIFICATION),
+ getItemSeekBar("Dtmf", AudioManager.STREAM_DTMF)
+ )
+ }
+
+ private fun getItemSeekBar(title: CharSequence, streamType: Int): CommonItemSeekBar {
+ return CommonItemSeekBar(title, VolumeUtils.getMaxVolume(streamType), object : CommonItemSeekBar.ProgressListener() {
+ override fun getCurValue(): Int {
+ return VolumeUtils.getVolume(streamType)
+ }
+
+ override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
+ VolumeUtils.setVolume(streamType, progress, AudioManager.FLAG_SHOW_UI)
+ }
+ })
+ }
+
+ override fun onResume() {
+ super.onResume()
+ itemsView.updateItems(bindItems())
+ }
+}
diff --git a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/helper/DialogHelper.kt b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/helper/DialogHelper.kt
index 91d89a4864..7d38fda3ca 100644
--- a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/helper/DialogHelper.kt
+++ b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/helper/DialogHelper.kt
@@ -1,11 +1,10 @@
package com.blankj.utilcode.pkg.helper
+import android.content.Context
import android.content.DialogInterface
import android.graphics.Bitmap
import android.graphics.drawable.ColorDrawable
-import android.support.v4.app.FragmentActivity
import android.text.method.ScrollingMovementMethod
-import android.util.Pair
import android.view.Gravity
import android.view.View
import android.view.Window
@@ -13,12 +12,14 @@ import android.widget.Button
import android.widget.EditText
import android.widget.ImageView
import android.widget.TextView
+import androidx.fragment.app.FragmentActivity
import com.blankj.base.dialog.BaseDialogFragment
import com.blankj.base.dialog.DialogLayoutCallback
-import com.blankj.common.dialog.CommonDialogContent
import com.blankj.utilcode.pkg.R
-import com.blankj.utilcode.util.*
-import com.blankj.utilcode.util.PermissionUtils.OnRationaleListener.ShouldRequest
+import com.blankj.utilcode.util.ActivityUtils
+import com.blankj.utilcode.util.KeyboardUtils
+import com.blankj.utilcode.util.ScreenUtils
+import com.blankj.utilcode.util.ToastUtils
/**
* ```
@@ -30,35 +31,8 @@ import com.blankj.utilcode.util.PermissionUtils.OnRationaleListener.ShouldReques
*/
object DialogHelper {
- fun showRationaleDialog(shouldRequest: ShouldRequest) {
- val topActivity = ActivityUtils.getTopActivity() ?: return
- CommonDialogContent().init(topActivity as FragmentActivity,
- StringUtils.getString(android.R.string.dialog_alert_title),
- StringUtils.getString(R.string.permission_rationale_message),
- Pair(StringUtils.getString(android.R.string.ok), View.OnClickListener {
- shouldRequest.again(true)
- }),
- Pair(StringUtils.getString(android.R.string.cancel), View.OnClickListener {
- shouldRequest.again(false)
- })).show()
- }
-
- fun showOpenAppSettingDialog() {
- val topActivity = ActivityUtils.getTopActivity() ?: return
- CommonDialogContent().init(topActivity as FragmentActivity,
- StringUtils.getString(android.R.string.dialog_alert_title),
- StringUtils.getString(R.string.permission_denied_forever_message),
- Pair(StringUtils.getString(android.R.string.ok), View.OnClickListener {
- PermissionUtils.launchAppDetailsSettings()
- }),
- Pair(StringUtils.getString(android.R.string.cancel), View.OnClickListener {
- }))
- .show()
- }
-
- fun showKeyboardDialog() {
- val topActivity = ActivityUtils.getTopActivity() ?: return
- BaseDialogFragment().init(topActivity as FragmentActivity, object : DialogLayoutCallback {
+ fun showKeyboardDialog(context: Context) {
+ BaseDialogFragment().init(context, object : DialogLayoutCallback {
override fun bindTheme(): Int {
return View.NO_ID
}
@@ -88,7 +62,8 @@ object DialogHelper {
contentView.findViewById(R.id.keyboardDialogCloseBtn).setOnClickListener(listener)
dialog.dialog.setOnShowListener(DialogInterface.OnShowListener {
- KeyboardUtils.fixAndroidBug5497(dialog.dialog.window)
+ KeyboardUtils.fixAndroidBug5497(dialog.dialog.window!!)
+ KeyboardUtils.showSoftInput()
})
}
@@ -180,4 +155,4 @@ object DialogHelper {
override fun onDismiss(dialog: BaseDialogFragment) {}
}).show()
}
-}
+}
\ No newline at end of file
diff --git a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/helper/PermissionHelper.kt b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/helper/PermissionHelper.kt
deleted file mode 100644
index 22c7483f54..0000000000
--- a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/helper/PermissionHelper.kt
+++ /dev/null
@@ -1,62 +0,0 @@
-package com.blankj.utilcode.pkg.helper
-
-import com.blankj.utilcode.constant.PermissionConstants
-import com.blankj.utilcode.util.LogUtils
-import com.blankj.utilcode.util.PermissionUtils
-
-/**
- * ```
- * author: Blankj
- * blog : http://blankj.com
- * time : 2018/01/06
- * desc : helper about permission
- * ```
- */
-object PermissionHelper {
-
- fun requestCamera(listener: OnPermissionGrantedListener,
- deniedListener: OnPermissionDeniedListener) {
- request(listener, deniedListener, PermissionConstants.CAMERA)
- }
-
- fun requestStorage(listener: OnPermissionGrantedListener,
- deniedListener: OnPermissionDeniedListener) {
- request(listener, deniedListener, PermissionConstants.STORAGE)
- }
-
- fun requestPhone(listener: OnPermissionGrantedListener,
- deniedListener: OnPermissionDeniedListener) {
- request(listener, deniedListener, PermissionConstants.PHONE)
- }
-
- private fun request(grantedListener: OnPermissionGrantedListener,
- deniedListener: OnPermissionDeniedListener,
- @PermissionConstants.Permission vararg permissions: String) {
- PermissionUtils.permission(*permissions)
- .rationale { shouldRequest -> DialogHelper.showRationaleDialog(shouldRequest) }
- .callback(object : PermissionUtils.FullCallback {
- override fun onGranted(permissionsGranted: List) {
- LogUtils.d(permissionsGranted)
- grantedListener.onPermissionGranted()
- }
-
- override fun onDenied(permissionsDeniedForever: List, permissionsDenied: List) {
- LogUtils.d(permissionsDeniedForever, permissionsDenied)
- if (!permissionsDeniedForever.isEmpty()) {
- DialogHelper.showOpenAppSettingDialog()
- return
- }
- deniedListener.onPermissionDenied()
- }
- })
- .request()
- }
-
- interface OnPermissionGrantedListener {
- fun onPermissionGranted()
- }
-
- interface OnPermissionDeniedListener {
- fun onPermissionDenied()
- }
-}
diff --git a/feature/utilcode/pkg/src/main/res/drawable/bar_status_custom.xml b/feature/utilcode/pkg/src/main/res/drawable/bar_status_custom.xml
index abe259f89f..50a4898a07 100644
--- a/feature/utilcode/pkg/src/main/res/drawable/bar_status_custom.xml
+++ b/feature/utilcode/pkg/src/main/res/drawable/bar_status_custom.xml
@@ -2,8 +2,9 @@
+ android:angle="180"
+ android:centerColor="@android:color/transparent"
+ android:endColor="@color/colorPrimary"
+ android:startColor="@color/colorPrimary" />
\ No newline at end of file
diff --git a/feature/utilcode/pkg/src/main/res/drawable/shadow_circle.xml b/feature/utilcode/pkg/src/main/res/drawable/shadow_circle.xml
index 5589315966..7abb0e7159 100644
--- a/feature/utilcode/pkg/src/main/res/drawable/shadow_circle.xml
+++ b/feature/utilcode/pkg/src/main/res/drawable/shadow_circle.xml
@@ -2,6 +2,6 @@
-
+
\ No newline at end of file
diff --git a/feature/utilcode/pkg/src/main/res/drawable/shadow_round_rect.xml b/feature/utilcode/pkg/src/main/res/drawable/shadow_round_rect.xml
index 97c4e0b168..576688b254 100644
--- a/feature/utilcode/pkg/src/main/res/drawable/shadow_round_rect.xml
+++ b/feature/utilcode/pkg/src/main/res/drawable/shadow_round_rect.xml
@@ -1,7 +1,7 @@
-
+
\ No newline at end of file
diff --git a/feature/utilcode/pkg/src/main/res/layout/activity_adaptscreen.xml b/feature/utilcode/pkg/src/main/res/layout/activity_adaptscreen.xml
new file mode 100644
index 0000000000..278fe8c2c6
--- /dev/null
+++ b/feature/utilcode/pkg/src/main/res/layout/activity_adaptscreen.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/feature/utilcode/pkg/src/main/res/layout/adaptscreen_close_activity.xml b/feature/utilcode/pkg/src/main/res/layout/adaptscreen_close_activity.xml
index 0214eb4806..2f8476a4a0 100644
--- a/feature/utilcode/pkg/src/main/res/layout/adaptscreen_close_activity.xml
+++ b/feature/utilcode/pkg/src/main/res/layout/adaptscreen_close_activity.xml
@@ -7,7 +7,7 @@
android:fillViewport="true"
tools:context=".feature.adaptScreen.AdaptCloseActivity">
-
@@ -42,6 +42,6 @@
android:textSize="30pt"
app:layout_constraintTop_toBottomOf="@id/adaptScreenCloseAdaptDpTv" />
-
+
\ No newline at end of file
diff --git a/feature/utilcode/pkg/src/main/res/layout/adaptscreen_height_activity.xml b/feature/utilcode/pkg/src/main/res/layout/adaptscreen_height_activity.xml
index 819d6bb99d..75fa87e8e5 100644
--- a/feature/utilcode/pkg/src/main/res/layout/adaptscreen_height_activity.xml
+++ b/feature/utilcode/pkg/src/main/res/layout/adaptscreen_height_activity.xml
@@ -6,7 +6,7 @@
android:layout_height="match_parent"
tools:context=".feature.adaptScreen.AdaptHeightActivity">
-
@@ -93,6 +93,6 @@
android:textSize="30pt" />
-
+
\ No newline at end of file
diff --git a/feature/utilcode/pkg/src/main/res/layout/adaptscreen_width_activity.xml b/feature/utilcode/pkg/src/main/res/layout/adaptscreen_width_activity.xml
index 9c5e953ecb..b6bfdb2c80 100644
--- a/feature/utilcode/pkg/src/main/res/layout/adaptscreen_width_activity.xml
+++ b/feature/utilcode/pkg/src/main/res/layout/adaptscreen_width_activity.xml
@@ -7,7 +7,7 @@
android:fillViewport="true"
tools:context=".feature.adaptScreen.AdaptWidthActivity">
-
@@ -148,6 +148,6 @@
-
+
\ No newline at end of file
diff --git a/feature/utilcode/pkg/src/main/res/layout/bar_status_fragment_activity.xml b/feature/utilcode/pkg/src/main/res/layout/bar_status_fragment_activity.xml
index 23dbb69305..16518fc22f 100644
--- a/feature/utilcode/pkg/src/main/res/layout/bar_status_fragment_activity.xml
+++ b/feature/utilcode/pkg/src/main/res/layout/bar_status_fragment_activity.xml
@@ -5,7 +5,7 @@
android:layout_height="match_parent"
android:orientation="vertical">
-
-
-
\ No newline at end of file
diff --git a/feature/utilcode/pkg/src/main/res/layout/mvp_activity.xml b/feature/utilcode/pkg/src/main/res/layout/mvp_activity.xml
index 807c158b67..d594eb654d 100644
--- a/feature/utilcode/pkg/src/main/res/layout/mvp_activity.xml
+++ b/feature/utilcode/pkg/src/main/res/layout/mvp_activity.xml
@@ -14,4 +14,17 @@
android:text="Get Update Msg"
app:layout_constraintTop_toTopOf="parent" />
+
+
\ No newline at end of file
diff --git a/feature/utilcode/pkg/src/main/res/layout/shadow_activity.xml b/feature/utilcode/pkg/src/main/res/layout/shadow_activity.xml
index 1046396a29..c8fca04657 100644
--- a/feature/utilcode/pkg/src/main/res/layout/shadow_activity.xml
+++ b/feature/utilcode/pkg/src/main/res/layout/shadow_activity.xml
@@ -6,34 +6,57 @@
android:orientation="vertical"
android:padding="16dp">
-
-
+ android:gravity="center"
+ android:orientation="horizontal">
+
+
+
+
+
+
+
+
+
-
-
+ android:gravity="center"
+ android:orientation="horizontal">
@@ -65,34 +87,57 @@
android:id="@+id/shadowRoundRectView"
android:layout_width="80dp"
android:layout_height="80dp"
- android:layout_marginLeft="32dp"
+ android:layout_gravity="center"
+ android:layout_marginLeft="16dp"
android:background="@drawable/shadow_round_rect"
android:clickable="true" />
+
+
+
+
+
+
+
+
+
-
-
+ android:gravity="center"
+ android:orientation="horizontal">
@@ -100,10 +145,33 @@
android:id="@+id/shadowCircleView"
android:layout_width="80dp"
android:layout_height="80dp"
- android:layout_marginLeft="32dp"
+ android:layout_gravity="center"
+ android:layout_marginLeft="16dp"
android:background="@drawable/shadow_circle"
android:clickable="true" />
+
+
+
+
+
+
+
+
Language Demo
- Language
- Language App Context
- Language Activity Context
Apply Simple Chinese
Apply American
+ Apply English
+ Apply Arabic
Apply System
\ No newline at end of file
diff --git a/feature/utilcode/pkg/src/main/res/values-zh-rCN/strings.xml b/feature/utilcode/pkg/src/main/res/values-zh-rCN/strings.xml
index d1ba24cff1..e06759a6d0 100644
--- a/feature/utilcode/pkg/src/main/res/values-zh-rCN/strings.xml
+++ b/feature/utilcode/pkg/src/main/res/values-zh-rCN/strings.xml
@@ -3,11 +3,10 @@
语言例子
- 语言
- App 上下文语言
- Activity 上下文语言
- 应用简体中文
- 应用英语
- 应用系统语言
+ 设置简体中文
+ 设置美语
+ 设置英语
+ 设置阿拉伯语
+ 设置系统语言
\ No newline at end of file
diff --git a/feature/utilcode/pkg/src/main/res/values/ids.xml b/feature/utilcode/pkg/src/main/res/values/ids.xml
new file mode 100644
index 0000000000..00728ce459
--- /dev/null
+++ b/feature/utilcode/pkg/src/main/res/values/ids.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/feature/utilcode/pkg/src/main/res/values/strings.xml b/feature/utilcode/pkg/src/main/res/values/strings.xml
index 2ea4c0df1e..551f9adbaf 100644
--- a/feature/utilcode/pkg/src/main/res/values/strings.xml
+++ b/feature/utilcode/pkg/src/main/res/values/strings.xml
@@ -6,15 +6,17 @@
AppUtils Demo
BarUtils Demo
BrightnessUtils Demo
- BlurUtils Demo
+ BusUtils Demo
CleanUtils Demo
ClickUtils Demo
- BusUtils Demo
+ ClipboardUtils Demo
CrashUtils Demo
DeviceUtils Demo
+ FileUtils Demo
FlashlightUtils Demo
FragmentUtils Demo
ImageUtils Demo
+ IntentUtils Demo
KeyboardUtils Demo
Language Demo
LogUtils Demo
@@ -37,7 +39,10 @@
SPStaticUtils Demo
SpanUtils Demo
ToastUtils Demo
+ UiMessage Demo
+ TransActivity Demo
VibrateUtils Demo
+ VolumeUtils Demo
Shared Element
@@ -70,6 +75,7 @@
Start Launcher Activity
Finish CoreUtilActivity
Finish To CoreUtilActivity
+ Finish All Activities Except Newest
Finish All Activities
@@ -135,6 +141,7 @@
Clean Internal Databases
Clean Internal SP
Clean External Cache
+ cleanAppUserData
Click View Scale Default
@@ -204,7 +211,6 @@
Fast Blur
Render Script Blur
Stack Blur
- Save
Compress By Scale
Compress By Quality Half
Compress By Quality Max Size
@@ -224,18 +230,20 @@
Close Dialog
- Language
- Language App Context
- Language Activity Context
+ Relaunch App
Apply Simple Chinese
Apply American
+ Apply English
+ Apply Arabic
Apply System
Log Switch
- Console Switch
+ Console Switch
+ Console Listener Switch
Head Switch
File Switch
+ File Listener Switch
Border Switch
Single Tag Switch
Log With No Tag
@@ -292,26 +300,22 @@
Screenshot
- Show Short Snackbar
- Show Short Snackbar With Action
- Show Long Snackbar
- Show Long Snackbar With Action
- Show Indefinite Snackbar
- Show Indefinite Snackbar With Action
- Add View
- Add View With Action
- Show Success
- Show Warning
- Show Error
- Dismiss Snackbar
Short Snackbar
+ Short Snackbar Top
+ Short Snackbar With Action
+ Short Snackbar With Action Top
Long Snackbar
+ Long Snackbar With Action
Indefinite Snackbar
- Click
- Custom View
+ Indefinite Snackbar With Action
+ Add View
+ Add View With Action
Success
Warning
Error
+ Dismiss Snackbar
+ Click
+ Custom View
Click To Dismiss
@@ -326,16 +330,23 @@
Show Short
Show Long
+ Show Null
+ Show Empty
Show Green Font
Show Bg Color
Show Bg Resource
Show Span
+ Show Left Icon
+ Show Dark Mode
+ Show Long String
+ A toast is a view containing a quick little message for the user. The ToastUtils class helps you create and show those.
Show Custom View
Custom View
Show Middle
+ Show Top
Cancel
Show Toast Dialog
-
+ Show Toast When Start Activity
Short
Long
Green Font
@@ -343,9 +354,18 @@
Custom Bg
Spannable String
Middle
+ Top
+
+
+ Add Listener Id
+ Remove All Id
+ Add Listener
+ Remove Listener
+ Send
Vibrate 1000ms
Vibrate Custom
+ Vibrate Background
Cancel
diff --git a/gradle.properties b/gradle.properties
index 63f495a02a..b9d5f2bcbf 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -13,10 +13,14 @@
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
#org.gradle.jvmargs=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005
+
+android.enableJetifier=true
+android.useAndroidX=true
+
org.gradle.jvmargs=-Xmx8192m -XX:MaxPermSize=2048m -XX:+HeapDumpOnOutOfMemoryError -XX:-UseGCOverheadLimit -Dfile.encoding=UTF-8
org.gradle.daemon=true
#org.gradle.configureondemand=true
org.gradle.parallel=true
org.gradle.caching=true
-#-Dorg.gradle.debug=true --no-daemon
\ No newline at end of file
+#-Dorg.gradle.debug=true --no-daemon
diff --git a/gradle/upload/bintrayUploadAndroid.gradle b/gradle/upload/bintrayUploadAndroid.gradle
deleted file mode 100644
index 6d9800bfbb..0000000000
--- a/gradle/upload/bintrayUploadAndroid.gradle
+++ /dev/null
@@ -1,121 +0,0 @@
-// load properties
-Properties properties = new Properties()
-File localPropertiesFile = project.file("local.properties");
-if (localPropertiesFile.exists()) {
- properties.load(localPropertiesFile.newDataInputStream())
-}
-File projectPropertiesFile = project.file("project.properties");
-if (projectPropertiesFile.exists()) {
- properties.load(projectPropertiesFile.newDataInputStream())
-}
-
-// read properties
-def projectName = properties.getProperty("project.name")
-def projectGroupId = properties.getProperty("project.groupId")
-def projectArtifactId = properties.getProperty("project.artifactId")
-def projectVersionName = android.defaultConfig.versionName
-def projectPackaging = properties.getProperty("project.packaging")
-def projectSiteUrl = properties.getProperty("project.siteUrl")
-def projectGitUrl = properties.getProperty("project.gitUrl")
-
-def developerId = properties.getProperty("developer.id")
-def developerName = properties.getProperty("developer.name")
-def developerEmail = properties.getProperty("developer.email")
-
-def bintrayUser = properties.getProperty("bintray.user")
-def bintrayApikey = properties.getProperty("bintray.apikey")
-
-def javadocName = properties.getProperty("javadoc.name")
-
-group = projectGroupId
-
-// This generates POM.xml with proper parameters
-install {
- repositories.mavenInstaller {
- pom {
- project {
- name projectName
- groupId projectGroupId
- artifactId projectArtifactId
- version projectVersionName
- packaging projectPackaging
- url projectSiteUrl
- licenses {
- license {
- name 'The Apache Software License, Version 2.0'
- url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
- }
- }
- developers {
- developer {
- id developerId
- name developerName
- email developerEmail
- }
- }
- scm {
- connection projectGitUrl
- developerConnection projectGitUrl
- url projectSiteUrl
- }
- }
- }
- }
-}
-
-if (project.hasProperty("kotlin")) {
- // Disable creating javadocs
- tasks.withType(Javadoc) {
- enabled = false
- }
-}
-
-// This generates sources.jar
-task sourcesJar(type: Jar) {
- from android.sourceSets.main.java.srcDirs
- classifier = 'sources'
-}
-
-task javadoc(type: Javadoc) {
- source = android.sourceSets.main.java.srcDirs
- classpath += configurations.compile
- classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
-}
-
-// This generates javadoc.jar
-task javadocJar(type: Jar, dependsOn: javadoc) {
- classifier = 'javadoc'
- from javadoc.destinationDir
-}
-
-artifacts {
- archives javadocJar
- archives sourcesJar
-}
-
-// javadoc configuration
-javadoc {
- options {
- encoding "UTF-8"
- charSet 'UTF-8'
- author true
- version projectVersionName
- links "http://docs.oracle.com/javase/7/docs/api"
- title javadocName
- }
-}
-
-// bintray configuration
-bintray {
- user = bintrayUser
- key = bintrayApikey
- configurations = ['archives']
- pkg {
- repo = "maven"
- name = projectName
- websiteUrl = projectSiteUrl
- vcsUrl = projectGitUrl
- licenses = ["Apache-2.0"]
- publish = true
- }
-}
\ No newline at end of file
diff --git a/gradle/upload/bintrayUploadJava.gradle b/gradle/upload/bintrayUploadJava.gradle
deleted file mode 100755
index ba9440a3e0..0000000000
--- a/gradle/upload/bintrayUploadJava.gradle
+++ /dev/null
@@ -1,79 +0,0 @@
-// load properties
-Properties properties = new Properties()
-File localPropertiesFile = project.file("local.properties");
-if (localPropertiesFile.exists()) {
- properties.load(localPropertiesFile.newDataInputStream())
-}
-File projectPropertiesFile = project.file("project.properties");
-if (projectPropertiesFile.exists()) {
- properties.load(projectPropertiesFile.newDataInputStream())
-}
-
-// read properties
-def projectName = properties.getProperty("project.name")
-def projectGroupId = properties.getProperty("project.groupId")
-def projectSiteUrl = properties.getProperty("project.siteUrl")
-def projectGitUrl = properties.getProperty("project.gitUrl")
-
-def developerId = properties.getProperty("developer.id")
-def developerName = properties.getProperty("developer.name")
-def developerEmail = properties.getProperty("developer.email")
-
-def bintrayUser = properties.getProperty("bintray.user")
-def bintrayApikey = properties.getProperty("bintray.apikey")
-
-def javadocName = properties.getProperty("javadoc.name")
-
-// This generates POM.xml with proper parameters
-install.repositories.mavenInstaller.pom.project {
- name projectName
- url projectSiteUrl
- licenses {
- license {
- name 'The Apache Software License, Version 2.0'
- url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
- }
- }
- developers {
- developer {
- id developerId
- name developerName
- email developerEmail
- }
- }
- scm {
- connection projectGitUrl
- developerConnection projectGitUrl
- url projectSiteUrl
- }
-}
-
-task sourcesJar(type: Jar, dependsOn: classes) {
- classifier = 'sources'
- from sourceSets.main.allSource
-}
-
-task javadocJar(type: Jar, dependsOn: javadoc) {
- classifier = 'javadoc'
- from javadoc.destinationDir
-}
-
-artifacts {
- archives sourcesJar
- archives javadocJar
-}
-
-// bintray configuration
-bintray {
- user = bintrayUser
- key = bintrayApikey
- configurations = ['archives']
- pkg {
- repo = "maven"
- name = projectName
- websiteUrl = projectSiteUrl
- vcsUrl = projectGitUrl
- licenses = ["Apache-2.0"]
- publish = true
- }
-}
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 13372aef5e..5c2d1cf016 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 36fcbfeb86..1e0ae1a108 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.0-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip
diff --git a/gradlew b/gradlew
index 9d82f78915..b0d6d0ab5d 100755
--- a/gradlew
+++ b/gradlew
@@ -1,4 +1,20 @@
-#!/usr/bin/env bash
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
##############################################################################
##
@@ -6,20 +22,38 @@
##
##############################################################################
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
-warn ( ) {
+warn () {
echo "$*"
}
-die ( ) {
+die () {
echo
echo "$*"
echo
@@ -30,6 +64,7 @@ die ( ) {
cygwin=false
msys=false
darwin=false
+nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
@@ -40,26 +75,11 @@ case "`uname`" in
MINGW* )
msys=true
;;
+ NONSTOP* )
+ nonstop=true
+ ;;
esac
-# Attempt to set APP_HOME
-# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
-done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >/dev/null
-APP_HOME="`pwd -P`"
-cd "$SAVED" >/dev/null
-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
@@ -85,7 +105,7 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
@@ -150,11 +170,19 @@ if $cygwin ; then
esac
fi
-# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
-function splitJvmOpts() {
- JVM_OPTS=("$@")
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
}
-eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
-JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
-exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
index 8a0b282aa6..15e1ee37a7 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -1,90 +1,100 @@
-@if "%DEBUG%" == "" @echo off
-@rem ##########################################################################
-@rem
-@rem Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
-set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto init
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:init
-@rem Get command-line arguments, handling Windowz variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-if "%@eval[2+2]" == "4" goto 4NT_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-goto execute
-
-:4NT_args
-@rem Get arguments from the 4NT Shell from JP Software
-set CMD_LINE_ARGS=%$
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
-
-:end
-@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem http://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/lib/base/build.gradle b/lib/base/build.gradle
index e518eada92..b7eb9d588c 100644
--- a/lib/base/build.gradle
+++ b/lib/base/build.gradle
@@ -1,16 +1,14 @@
dependencies {
- implementation fileTree(include: ['*.jar'], dir: 'libs')
- api Config.depConfig.lib_subutil.dep
- api Config.depConfig.lib_utilcode.dep
+ api Config.modules.lib_subutil.dep
+ api Config.modules.lib_utilcode.dep
- api Config.depConfig.support_appcompat_v7.dep
- api Config.depConfig.support_design.dep
- api Config.depConfig.support_multidex.dep
- api Config.depConfig.support_constraint.dep
- api Config.depConfig.kotlin.dep
- api Config.depConfig.free_proguard.dep
- api Config.depConfig.swipe_panel.dep
- api Config.depConfig.eventbus_lib.dep
- compileOnly Config.depConfig.lib_utildebug_no_op.dep
- compileOnly Config.depConfig.leakcanary_android_no_op.dep
+ api Config.libs.androidx_appcompat.path
+ api Config.libs.androidx_material.path
+ api Config.libs.androidx_multidex.path
+ api Config.libs.androidx_constraint.path
+ api Config.libs.kotlin.path
+ api Config.libs.free_proguard.path
+ api Config.libs.swipe_panel.path
+ api Config.libs.eventbus_lib.path
+ compileOnly Config.modules.lib_utildebug_no_op.dep
}
\ No newline at end of file
diff --git a/lib/base/src/main/java/com/blankj/base/BaseActivity.java b/lib/base/src/main/java/com/blankj/base/BaseActivity.java
index c0c1fce1ce..c0348203f8 100644
--- a/lib/base/src/main/java/com/blankj/base/BaseActivity.java
+++ b/lib/base/src/main/java/com/blankj/base/BaseActivity.java
@@ -2,10 +2,12 @@
import android.app.Activity;
import android.os.Bundle;
-import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
+import androidx.annotation.LayoutRes;
+import androidx.appcompat.app.AppCompatActivity;
+
import com.blankj.utilcode.util.ClickUtils;
/**
diff --git a/lib/base/src/main/java/com/blankj/base/BaseApplication.java b/lib/base/src/main/java/com/blankj/base/BaseApplication.java
index 0925dfba3f..f1fd6186c0 100644
--- a/lib/base/src/main/java/com/blankj/base/BaseApplication.java
+++ b/lib/base/src/main/java/com/blankj/base/BaseApplication.java
@@ -2,13 +2,15 @@
import android.app.Application;
import android.content.Context;
-import android.support.multidex.MultiDex;
+
+import androidx.multidex.MultiDex;
import com.blankj.utilcode.util.AppUtils;
import com.blankj.utilcode.util.CrashUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.ProcessUtils;
-import com.squareup.leakcanary.LeakCanary;
+import com.blankj.utildebug.DebugUtils;
+import com.blankj.utildebug.debug.IDebug;
import java.util.ArrayList;
@@ -37,26 +39,13 @@ protected void attachBaseContext(Context base) {
MultiDex.install(this);
}
-// provider
-
@Override
public void onCreate() {
super.onCreate();
sInstance = this;
- initLeakCanary();
initLog();
initCrash();
- }
-
- private void initLeakCanary() {// 内存泄露检查工具
- if (isDebug()) {
- if (LeakCanary.isInAnalyzerProcess(this)) {
- // This process is dedicated to LeakCanary for heap analysis.
- // You should not init your app in this process.
- return;
- }
- LeakCanary.install(this);
- }
+ initDebugMenu();
}
// init it in ur application
@@ -86,20 +75,25 @@ public String format(ArrayList arrayList) {
return "LogUtils Formatter ArrayList { " + arrayList.toString() + " }";
}
})
- .setFileWriter(null);
+ .addFileExtraHead("ExtraKey", "ExtraValue");
LogUtils.i(config.toString());
}
private void initCrash() {
CrashUtils.init(new CrashUtils.OnCrashListener() {
@Override
- public void onCrash(String crashInfo, Throwable e) {
- LogUtils.e(crashInfo);
+ public void onCrash(CrashUtils.CrashInfo crashInfo) {
+ crashInfo.addExtraHead("extraKey", "extraValue");
+ LogUtils.e(crashInfo.toString());
AppUtils.relaunchApp();
}
});
}
+ private void initDebugMenu() {
+ DebugUtils.addDebugs(new ArrayList());
+ }
+
private boolean isDebug() {
if (isDebug == null) isDebug = AppUtils.isAppDebug();
return isDebug;
diff --git a/lib/base/src/main/java/com/blankj/base/BaseFragment.java b/lib/base/src/main/java/com/blankj/base/BaseFragment.java
index 2ff0a90913..ab2b8877fe 100644
--- a/lib/base/src/main/java/com/blankj/base/BaseFragment.java
+++ b/lib/base/src/main/java/com/blankj/base/BaseFragment.java
@@ -2,13 +2,6 @@
import android.content.Context;
import android.os.Bundle;
-import android.support.annotation.IdRes;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentTransaction;
-import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -17,6 +10,14 @@
import com.blankj.utilcode.util.AppUtils;
import com.blankj.utilcode.util.ClickUtils;
+import androidx.annotation.IdRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
+
/**
*
* author: Blankj
@@ -89,7 +90,7 @@ public void onCreate(@Nullable Bundle savedInstanceState) {
} else {
ft.show(this);
}
- ft.commitAllowingStateLoss();
+ ft.commitNowAllowingStateLoss();
}
Bundle bundle = getArguments();
initData(bundle);
diff --git a/lib/base/src/main/java/com/blankj/base/IBaseView.java b/lib/base/src/main/java/com/blankj/base/IBaseView.java
index 282649b774..821cbf4399 100644
--- a/lib/base/src/main/java/com/blankj/base/IBaseView.java
+++ b/lib/base/src/main/java/com/blankj/base/IBaseView.java
@@ -1,11 +1,12 @@
package com.blankj.base;
import android.os.Bundle;
-import android.support.annotation.LayoutRes;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
import android.view.View;
+import androidx.annotation.LayoutRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
/**
*
diff --git a/lib/base/src/main/java/com/blankj/base/dialog/BaseDialog.java b/lib/base/src/main/java/com/blankj/base/dialog/BaseDialog.java
index fcb8a84858..1599d8becc 100644
--- a/lib/base/src/main/java/com/blankj/base/dialog/BaseDialog.java
+++ b/lib/base/src/main/java/com/blankj/base/dialog/BaseDialog.java
@@ -4,12 +4,13 @@
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
-import android.support.annotation.NonNull;
import android.view.View;
import android.view.Window;
import com.blankj.utilcode.util.ActivityUtils;
-import com.blankj.utilcode.util.Utils;
+import com.blankj.utilcode.util.ThreadUtils;
+
+import androidx.annotation.NonNull;
/**
*
@@ -53,7 +54,7 @@ protected void onCreate(Bundle savedInstanceState) {
@Override
public void show() {
- Utils.runOnUiThread(new Runnable() {
+ ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
if (ActivityUtils.isActivityAlive(getContext())) {
@@ -65,7 +66,7 @@ public void run() {
@Override
public void dismiss() {
- Utils.runOnUiThread(new Runnable() {
+ ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
if (ActivityUtils.isActivityAlive(getContext())) {
diff --git a/lib/base/src/main/java/com/blankj/base/dialog/BaseDialogFragment.java b/lib/base/src/main/java/com/blankj/base/dialog/BaseDialogFragment.java
index 21e224bf62..e115e78878 100644
--- a/lib/base/src/main/java/com/blankj/base/dialog/BaseDialogFragment.java
+++ b/lib/base/src/main/java/com/blankj/base/dialog/BaseDialogFragment.java
@@ -1,22 +1,26 @@
package com.blankj.base.dialog;
import android.annotation.SuppressLint;
+import android.app.Activity;
import android.app.Dialog;
+import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.v4.app.DialogFragment;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentActivity;
-import android.support.v4.app.FragmentManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import com.blankj.utilcode.util.ActivityUtils;
-import com.blankj.utilcode.util.Utils;
+import com.blankj.utilcode.util.LogUtils;
+import com.blankj.utilcode.util.ThreadUtils;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.DialogFragment;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
+import androidx.fragment.app.FragmentManager;
/**
*
@@ -34,18 +38,28 @@ public class BaseDialogFragment extends DialogFragment {
protected FragmentActivity mActivity;
protected View mContentView;
- public BaseDialogFragment init(FragmentActivity activity, DialogLayoutCallback listener) {
- mActivity = activity;
+ public BaseDialogFragment init(Context context, DialogLayoutCallback listener) {
+ mActivity = getFragmentActivity(context);
mDialogLayoutCallback = listener;
return this;
}
- public BaseDialogFragment init(FragmentActivity activity, DialogCallback dialogCallback) {
- mActivity = activity;
+ public BaseDialogFragment init(Context context, DialogCallback dialogCallback) {
+ mActivity = getFragmentActivity(context);
mDialogCallback = dialogCallback;
return this;
}
+ private FragmentActivity getFragmentActivity(Context context) {
+ Activity activity = ActivityUtils.getActivityByContext(context);
+ if (activity == null) return null;
+ if (activity instanceof FragmentActivity) {
+ return (FragmentActivity) activity;
+ }
+ LogUtils.w(context + "not instanceof FragmentActivity");
+ return null;
+ }
+
@Override
public int getTheme() {
if (mDialogLayoutCallback != null) {
@@ -59,10 +73,19 @@ public int getTheme() {
@NonNull
public Dialog onCreateDialog(Bundle savedInstanceState) {
+ Dialog dialog;
+ if (mDialogCallback != null) {
+ dialog = mDialogCallback.bindDialog(mActivity);
+ } else {
+ dialog = super.onCreateDialog(savedInstanceState);
+ }
+ Window window = dialog.getWindow();
if (mDialogCallback != null) {
- return mDialogCallback.bindDialog(mActivity);
+ mDialogCallback.setWindowStyle(window);
+ } else if (mDialogLayoutCallback != null) {
+ mDialogLayoutCallback.setWindowStyle(window);
}
- return super.onCreateDialog(savedInstanceState);
+ return dialog;
}
@Nullable
@@ -83,20 +106,6 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
super.onViewCreated(view, savedInstanceState);
}
- @Override
- public void onStart() {
- super.onStart();
- Dialog dialog = getDialog();
- if (dialog == null) return;
- Window window = dialog.getWindow();
- if (window == null) return;
- if (mDialogCallback != null) {
- mDialogCallback.setWindowStyle(window);
- } else if (mDialogLayoutCallback != null) {
- mDialogLayoutCallback.setWindowStyle(window);
- }
- }
-
@Override
public void onCancel(DialogInterface dialog) {
super.onCancel(dialog);
@@ -118,7 +127,7 @@ public void show() {
}
public void show(final String tag) {
- Utils.runOnUiThread(new Runnable() {
+ ThreadUtils.runOnUiThread(new Runnable() {
@SuppressLint("CommitTransaction")
@Override
public void run() {
@@ -128,7 +137,7 @@ public void run() {
if (prev != null) {
fm.beginTransaction().remove(prev);
}
- BaseDialogFragment.super.showNow(fm, tag);
+ BaseDialogFragment.super.show(fm, tag);
}
}
});
@@ -136,7 +145,7 @@ public void run() {
@Override
public void dismiss() {
- Utils.runOnUiThread(new Runnable() {
+ ThreadUtils.runOnUiThread(new Runnable() {
@Override
public void run() {
if (ActivityUtils.isActivityAlive(mActivity)) {
diff --git a/lib/base/src/main/java/com/blankj/base/dialog/DialogCallback.java b/lib/base/src/main/java/com/blankj/base/dialog/DialogCallback.java
index 7d1c6e632a..defd34483f 100644
--- a/lib/base/src/main/java/com/blankj/base/dialog/DialogCallback.java
+++ b/lib/base/src/main/java/com/blankj/base/dialog/DialogCallback.java
@@ -2,9 +2,10 @@
import android.app.Activity;
import android.app.Dialog;
-import android.support.annotation.NonNull;
import android.view.Window;
+import androidx.annotation.NonNull;
+
/**
*
* author: blankj
diff --git a/lib/base/src/main/java/com/blankj/base/mvp/BaseModel.java b/lib/base/src/main/java/com/blankj/base/mvp/BaseModel.java
index cbdd94c2be..b48ed32f23 100644
--- a/lib/base/src/main/java/com/blankj/base/mvp/BaseModel.java
+++ b/lib/base/src/main/java/com/blankj/base/mvp/BaseModel.java
@@ -1,10 +1,8 @@
package com.blankj.base.mvp;
-import com.blankj.utilcode.util.ThreadUtils;
-import com.blankj.utilcode.util.ToastUtils;
+import android.util.Log;
-import java.util.ArrayList;
-import java.util.List;
+import androidx.annotation.CallSuper;
/**
*
@@ -16,24 +14,12 @@
*/
public abstract class BaseModel {
- private List mTasks = new ArrayList<>();
+ private static final String TAG = BaseView.TAG;
- public abstract void onCreateModel();
+ public abstract void onCreate();
- public abstract void onDestroyModel();
-
- public ThreadUtils.Task addAutoDestroyTask(ThreadUtils.Task task) {
- if (task == null) return null;
- mTasks.add(task);
- return task;
- }
-
- void destroy() {
- onDestroyModel();
- for (ThreadUtils.Task task : mTasks) {
- if (task == null) continue;
- task.cancel();
- ToastUtils.showLong("Mvp Task Canceled.");
- }
+ @CallSuper
+ public void onDestroy() {
+ Log.i(TAG, "destroy model: " + getClass().getSimpleName());
}
}
diff --git a/lib/base/src/main/java/com/blankj/base/mvp/BasePresenter.java b/lib/base/src/main/java/com/blankj/base/mvp/BasePresenter.java
index 93e3223324..32e672417b 100644
--- a/lib/base/src/main/java/com/blankj/base/mvp/BasePresenter.java
+++ b/lib/base/src/main/java/com/blankj/base/mvp/BasePresenter.java
@@ -1,16 +1,14 @@
package com.blankj.base.mvp;
-import android.arch.lifecycle.Lifecycle;
-import android.arch.lifecycle.LifecycleObserver;
-import android.arch.lifecycle.LifecycleOwner;
-import android.arch.lifecycle.OnLifecycleEvent;
-import android.support.annotation.CallSuper;
-
-import com.blankj.utilcode.util.LogUtils;
+import android.util.Log;
import java.util.HashMap;
import java.util.Map;
+import androidx.annotation.CallSuper;
+import androidx.lifecycle.ViewModel;
+import androidx.lifecycle.ViewModelProvider;
+
/**
*
* author: blankj
@@ -19,16 +17,19 @@
* desc :
*
*/
-public abstract class BasePresenter implements LifecycleObserver {
+public abstract class BasePresenter {
- private V mView;
- private Map mModelMap = new HashMap<>();
+ private static final String TAG = BaseView.TAG;
- public abstract void onAttachView();
+ private V mView;
+ private Map, BaseModel> mModelMap = new HashMap<>();
+ private boolean isAlive = true;
+
+ public abstract void onBindView();
void bindView(V view) {
this.mView = view;
- onAttachView();
+ onBindView();
}
public V getView() {
@@ -44,34 +45,29 @@ public M getModel(Class modelClass) {
try {
M model = modelClass.newInstance();
mModelMap.put(modelClass, model);
- model.onCreateModel();
+ model.onCreate();
return model;
} catch (IllegalAccessException e) {
- e.printStackTrace();
+ Log.e("BasePresenter", "getModel", e);
} catch (InstantiationException e) {
- e.printStackTrace();
+ Log.e("BasePresenter", "getModel", e);
}
return null;
}
@CallSuper
- @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
- public void onDestroyPresenter() {
- if (mView != null) {
- mView.mPresenterMap.remove(this.getClass());
- mView.onDestroyView();
- }
+ public void onDestroy() {
+ Log.i(TAG, "destroy presenter: " + getClass().getSimpleName());
+ isAlive = false;
for (BaseModel model : mModelMap.values()) {
if (model != null) {
- model.destroy();
+ model.onDestroy();
}
}
mModelMap.clear();
- LogUtils.e("onDestroyPresenter");
}
- @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
- public void onLifecycleChanged(LifecycleOwner owner, Lifecycle.Event event) {
- LogUtils.e(event.toString());
+ public boolean isAlive() {
+ return isAlive;
}
}
diff --git a/lib/base/src/main/java/com/blankj/base/mvp/BaseView.java b/lib/base/src/main/java/com/blankj/base/mvp/BaseView.java
index 1e725be0b0..a68909d01f 100644
--- a/lib/base/src/main/java/com/blankj/base/mvp/BaseView.java
+++ b/lib/base/src/main/java/com/blankj/base/mvp/BaseView.java
@@ -1,12 +1,17 @@
package com.blankj.base.mvp;
-import android.arch.lifecycle.Lifecycle;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentActivity;
+import android.util.Log;
import java.util.HashMap;
import java.util.Map;
+import androidx.annotation.CallSuper;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleObserver;
+import androidx.lifecycle.OnLifecycleEvent;
+
/**
*
* author: blankj
@@ -15,51 +20,95 @@
* desc :
*
*/
-public abstract class BaseView {
+public class BaseView implements LifecycleObserver {
+
+ public static final String TAG = "UtilsMVP";
- private FragmentActivity mActivity;
- private Fragment mFragment;
- private Lifecycle mLifecycle;
- Map> mPresenterMap = new HashMap<>();
+ private FragmentActivity mActivity;
+ private Fragment mFragment;
+ private Lifecycle mLifecycle;
+ private Map, BasePresenter> mPresenterMap = new HashMap<>();
- public abstract void onDestroyView();
+ public BaseView(Fragment fragment) {
+ mFragment = fragment;
+ mActivity = fragment.getActivity();
+ mLifecycle = mFragment.getLifecycle();
+ addLifecycle(this);
+ }
public BaseView(FragmentActivity activity) {
mActivity = activity;
- mLifecycle = activity.getLifecycle();
+ mLifecycle = mActivity.getLifecycle();
+ addLifecycle(this);
}
- public BaseView(Fragment fragment) {
- mFragment = fragment;
- mActivity = fragment.getActivity();
- mLifecycle = fragment.getLifecycle();
+ public BaseView(Lifecycle lifecycle) {
+ mLifecycle = lifecycle;
+ addLifecycle(this);
}
public T getActivity() {
+ if (mActivity == null) {
+ return null;
+ }
//noinspection unchecked
return (T) mActivity;
}
public T getFragment() {
+ if (mFragment == null) {
+ return null;
+ }
//noinspection unchecked
return (T) mFragment;
}
- public void addPresenter(BasePresenter presenter) {
+ public V addPresenter(BasePresenter presenter) {
+ if (presenter == null) return (V) this;
mPresenterMap.put(presenter.getClass(), presenter);
//noinspection unchecked
presenter.bindView((V) this);
- if (mLifecycle != null) {
- mLifecycle.addObserver(presenter);
- }
+ return (V) this;
}
public > P getPresenter(Class
presenterClass) {
+ if (presenterClass == null) {
+ throw new IllegalArgumentException("presenterClass is null!");
+ }
BasePresenter basePresenter = mPresenterMap.get(presenterClass);
- if (basePresenter != null) {
- //noinspection unchecked
- return (P) basePresenter;
+ if (basePresenter == null) {
+ throw new IllegalArgumentException("presenter of <" + presenterClass.getSimpleName() + "> is not added!");
+ }
+ //noinspection unchecked
+ return (P) basePresenter;
+ }
+
+ @CallSuper
+ @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
+ public void onDestroy() {
+ Log.i(TAG, "destroy view: " + getClass().getSimpleName());
+ removeLifecycle(this);
+ for (BasePresenter presenter : mPresenterMap.values()) {
+ if (presenter != null) {
+ presenter.onDestroy();
+ }
+ }
+ mPresenterMap.clear();
+ }
+
+ private void addLifecycle(LifecycleObserver observer) {
+ if (mLifecycle == null) {
+ Log.w(TAG, "addLifecycle: mLifecycle is null");
+ return;
+ }
+ mLifecycle.addObserver(observer);
+ }
+
+ private void removeLifecycle(LifecycleObserver observer) {
+ if (mLifecycle == null) {
+ Log.w(TAG, "removeLifecycle: mLifecycle is null");
+ return;
}
- return null;
+ mLifecycle.removeObserver(observer);
}
}
diff --git a/lib/base/src/main/java/com/blankj/base/rv/BaseItem.java b/lib/base/src/main/java/com/blankj/base/rv/BaseItem.java
index 7ca2a573d4..b0d6de04fa 100644
--- a/lib/base/src/main/java/com/blankj/base/rv/BaseItem.java
+++ b/lib/base/src/main/java/com/blankj/base/rv/BaseItem.java
@@ -1,14 +1,17 @@
package com.blankj.base.rv;
-import android.support.annotation.LayoutRes;
-import android.support.annotation.NonNull;
-import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.util.SparseIntArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import java.util.List;
+
+import androidx.annotation.LayoutRes;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
/**
*
* author: Blankj
@@ -21,6 +24,7 @@ public abstract class BaseItem {
private static final SparseIntArray LAYOUT_SPARSE_ARRAY = new SparseIntArray();
private static final SparseArray VIEW_SPARSE_ARRAY = new SparseArray<>();
+ public boolean isBindViewHolder = false;
static ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
int layoutByType = LAYOUT_SPARSE_ARRAY.get(viewType, -1);
@@ -36,7 +40,11 @@ static ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType
public abstract void bind(@NonNull final ItemViewHolder holder, final int position);
+ public void partialUpdate(List
*
*
- * ArrayUtils.add(null, 0, null) = [null]
- * ArrayUtils.add(null, 0, "a") = ["a"]
- * ArrayUtils.add(["a"], 1, null) = ["a", null]
- * ArrayUtils.add(["a"], 1, "b") = ["a", "b"]
- * ArrayUtils.add(["a", "b"], 3, "c") = ["a", "b", "c"]
+ * ArrayUtils.add(null, 0, null) = null
+ * ArrayUtils.add(null, 0, ["a"]) = ["a"]
+ * ArrayUtils.add(["a"], 1, null) = ["a"]
+ * ArrayUtils.add(["a"], 1, ["b"]) = ["a", "b"]
+ * ArrayUtils.add(["a", "b"], 2, ["c"]) = ["a", "b", "c"]
*
*
* @param array1 the array to realAdd the element to, may be null
@@ -633,51 +685,76 @@ private static Object realAddArr(Object array1, Object array2) {
* @throws IndexOutOfBoundsException if the index is out of range
* (index < 0 || index > array.length).
*/
- public static T[] add(T[] array1, int index, T[] array2) {
+ @Nullable
+ public static T[] add(@Nullable T[] array1, int index, @Nullable T[] array2) {
Class clss;
if (array1 != null) {
clss = array1.getClass().getComponentType();
} else if (array2 != null) {
clss = array2.getClass().getComponentType();
} else {
- return (T[]) new Object[]{null};
+ return null;
}
return (T[]) realAddArr(array1, index, array2, clss);
}
- public static boolean[] add(boolean[] array1, int index, boolean[] array2) {
- return (boolean[]) realAddArr(array1, index, array2, Boolean.TYPE);
+ @Nullable
+ public static boolean[] add(@Nullable boolean[] array1, int index, @Nullable boolean[] array2) {
+ Object result = realAddArr(array1, index, array2, Boolean.TYPE);
+ if (result == null) return null;
+ return (boolean[]) result;
}
- public static char[] add(char[] array1, int index, char[] array2) {
- return (char[]) realAddArr(array1, index, array2, Character.TYPE);
+ public static char[] add(@Nullable char[] array1, int index, @Nullable char[] array2) {
+ Object result = realAddArr(array1, index, array2, Character.TYPE);
+ if (result == null) return null;
+ return (char[]) result;
}
- public static byte[] add(byte[] array1, int index, byte[] array2) {
- return (byte[]) realAddArr(array1, index, array2, Byte.TYPE);
+ @Nullable
+ public static byte[] add(@Nullable byte[] array1, int index, @Nullable byte[] array2) {
+ Object result = realAddArr(array1, index, array2, Byte.TYPE);
+ if (result == null) return null;
+ return (byte[]) result;
}
- public static short[] add(short[] array1, int index, short[] array2) {
- return (short[]) realAddArr(array1, index, array2, Short.TYPE);
+ @Nullable
+ public static short[] add(@Nullable short[] array1, int index, @Nullable short[] array2) {
+ Object result = realAddArr(array1, index, array2, Short.TYPE);
+ if (result == null) return null;
+ return (short[]) result;
}
- public static int[] add(int[] array1, int index, int[] array2) {
- return (int[]) realAddArr(array1, index, array2, Integer.TYPE);
+ @Nullable
+ public static int[] add(@Nullable int[] array1, int index, @Nullable int[] array2) {
+ Object result = realAddArr(array1, index, array2, Integer.TYPE);
+ if (result == null) return null;
+ return (int[]) result;
}
- public static long[] add(long[] array1, int index, long[] array2) {
- return (long[]) realAddArr(array1, index, array2, Long.TYPE);
+ @Nullable
+ public static long[] add(@Nullable long[] array1, int index, @Nullable long[] array2) {
+ Object result = realAddArr(array1, index, array2, Long.TYPE);
+ if (result == null) return null;
+ return (long[]) result;
}
- public static float[] add(float[] array1, int index, float[] array2) {
- return (float[]) realAddArr(array1, index, array2, Float.TYPE);
+ @Nullable
+ public static float[] add(@Nullable float[] array1, int index, @Nullable float[] array2) {
+ Object result = realAddArr(array1, index, array2, Float.TYPE);
+ if (result == null) return null;
+ return (float[]) result;
}
- public static double[] add(double[] array1, int index, double[] array2) {
- return (double[]) realAddArr(array1, index, array2, Double.TYPE);
+ @Nullable
+ public static double[] add(@Nullable double[] array1, int index, @Nullable double[] array2) {
+ Object result = realAddArr(array1, index, array2, Double.TYPE);
+ if (result == null) return null;
+ return (double[]) result;
}
- private static Object realAddArr(Object array1, int index, Object array2, Class clss) {
+ @Nullable
+ private static Object realAddArr(@Nullable Object array1, int index, @Nullable Object array2, Class clss) {
if (array1 == null && array2 == null) return null;
int len1 = getLength(array1);
int len2 = getLength(array2);
@@ -736,7 +813,8 @@ private static Object realAddArr(Object array1, int index, Object array2, Class
* @throws IndexOutOfBoundsException if the index is out of range
* (index < 0 || index > array.length).
*/
- public static T[] add(T[] array, int index, T element) {
+ @NonNull
+ public static T[] add(@Nullable T[] array, int index, @Nullable T element) {
Class clss;
if (array != null) {
clss = array.getClass().getComponentType();
@@ -748,39 +826,48 @@ public static T[] add(T[] array, int index, T element) {
return (T[]) realAdd(array, index, element, clss);
}
- public static boolean[] add(boolean[] array, int index, boolean element) {
+ @NonNull
+ public static boolean[] add(@Nullable boolean[] array, int index, boolean element) {
return (boolean[]) realAdd(array, index, element, Boolean.TYPE);
}
- public static char[] add(char[] array, int index, char element) {
+ @NonNull
+ public static char[] add(@Nullable char[] array, int index, char element) {
return (char[]) realAdd(array, index, element, Character.TYPE);
}
- public static byte[] add(byte[] array, int index, byte element) {
+ @NonNull
+ public static byte[] add(@Nullable byte[] array, int index, byte element) {
return (byte[]) realAdd(array, index, element, Byte.TYPE);
}
- public static short[] add(short[] array, int index, short element) {
+ @NonNull
+ public static short[] add(@Nullable short[] array, int index, short element) {
return (short[]) realAdd(array, index, element, Short.TYPE);
}
- public static int[] add(int[] array, int index, int element) {
+ @NonNull
+ public static int[] add(@Nullable int[] array, int index, int element) {
return (int[]) realAdd(array, index, element, Integer.TYPE);
}
- public static long[] add(long[] array, int index, long element) {
+ @NonNull
+ public static long[] add(@Nullable long[] array, int index, long element) {
return (long[]) realAdd(array, index, element, Long.TYPE);
}
- public static float[] add(float[] array, int index, float element) {
+ @NonNull
+ public static float[] add(@Nullable float[] array, int index, float element) {
return (float[]) realAdd(array, index, element, Float.TYPE);
}
- public static double[] add(double[] array, int index, double element) {
+ @NonNull
+ public static double[] add(@Nullable double[] array, int index, double element) {
return (double[]) realAdd(array, index, element, Double.TYPE);
}
- private static Object realAdd(Object array, int index, Object element, Class clss) {
+ @NonNull
+ private static Object realAdd(@Nullable Object array, int index, @Nullable Object element, Class clss) {
if (array == null) {
if (index != 0) {
throw new IndexOutOfBoundsException("Index: " + index + ", Length: 0");
@@ -826,15 +913,16 @@ private static Object realAdd(Object array, int index, Object element, Class cls
* ArrayUtils.remove(["a", "b", "c"], 1) = ["a", "c"]
*
*
- * @param array the array to remove the element from, may not be null
+ * @param array the array to remove the element from, may be null
* @param index the position of the element to be removed
* @return A new array containing the existing elements except the element
* at the specified position.
* @throws IndexOutOfBoundsException if the index is out of range
- * (index < 0 || index >= array.length), or if the array is null.
- * @since 2.1
+ * (index < 0 || index >= array.length)
*/
- public static Object[] remove(Object[] array, int index) {
+ @Nullable
+ public static Object[] remove(@Nullable Object[] array, int index) {
+ if (array == null) return null;
return (Object[]) remove((Object) array, index);
}
@@ -861,9 +949,9 @@ public static Object[] remove(Object[] array, int index) {
* @param element the element to be removed
* @return A new array containing the existing elements except the first
* occurrence of the specified element.
- * @since 2.1
*/
- public static Object[] removeElement(Object[] array, Object element) {
+ @Nullable
+ public static Object[] removeElement(@Nullable Object[] array, @Nullable Object element) {
int index = indexOf(array, element);
if (index == INDEX_NOT_FOUND) {
return copy(array);
@@ -871,11 +959,14 @@ public static Object[] removeElement(Object[] array, Object element) {
return remove(array, index);
}
- public static boolean[] remove(boolean[] array, int index) {
+ @Nullable
+ public static boolean[] remove(@Nullable boolean[] array, int index) {
+ if (array == null) return null;
return (boolean[]) remove((Object) array, index);
}
- public static boolean[] removeElement(boolean[] array, boolean element) {
+ @Nullable
+ public static boolean[] removeElement(@Nullable boolean[] array, boolean element) {
int index = indexOf(array, element);
if (index == INDEX_NOT_FOUND) {
return copy(array);
@@ -883,11 +974,14 @@ public static boolean[] removeElement(boolean[] array, boolean element) {
return remove(array, index);
}
- public static byte[] remove(byte[] array, int index) {
+ @Nullable
+ public static byte[] remove(@Nullable byte[] array, int index) {
+ if (array == null) return null;
return (byte[]) remove((Object) array, index);
}
- public static byte[] removeElement(byte[] array, byte element) {
+ @Nullable
+ public static byte[] removeElement(@Nullable byte[] array, byte element) {
int index = indexOf(array, element);
if (index == INDEX_NOT_FOUND) {
return copy(array);
@@ -895,11 +989,14 @@ public static byte[] removeElement(byte[] array, byte element) {
return remove(array, index);
}
- public static char[] remove(char[] array, int index) {
+ @Nullable
+ public static char[] remove(@Nullable char[] array, int index) {
+ if (array == null) return null;
return (char[]) remove((Object) array, index);
}
- public static char[] removeElement(char[] array, char element) {
+ @Nullable
+ public static char[] removeElement(@Nullable char[] array, char element) {
int index = indexOf(array, element);
if (index == INDEX_NOT_FOUND) {
return copy(array);
@@ -907,23 +1004,30 @@ public static char[] removeElement(char[] array, char element) {
return remove(array, index);
}
- public static double[] remove(double[] array, int index) {
+ @Nullable
+ public static double[] remove(@Nullable double[] array, int index) {
+ if (array == null) return null;
return (double[]) remove((Object) array, index);
}
- public static double[] removeElement(double[] array, double element) {
+ @Nullable
+ public static double[] removeElement(@Nullable double[] array, double element) {
int index = indexOf(array, element);
if (index == INDEX_NOT_FOUND) {
return copy(array);
}
+ //noinspection ConstantConditions
return remove(array, index);
}
- public static float[] remove(float[] array, int index) {
+ @Nullable
+ public static float[] remove(@Nullable float[] array, int index) {
+ if (array == null) return null;
return (float[]) remove((Object) array, index);
}
- public static float[] removeElement(float[] array, float element) {
+ @Nullable
+ public static float[] removeElement(@Nullable float[] array, float element) {
int index = indexOf(array, element);
if (index == INDEX_NOT_FOUND) {
return copy(array);
@@ -931,11 +1035,14 @@ public static float[] removeElement(float[] array, float element) {
return remove(array, index);
}
- public static int[] remove(int[] array, int index) {
+ @Nullable
+ public static int[] remove(@Nullable int[] array, int index) {
+ if (array == null) return null;
return (int[]) remove((Object) array, index);
}
- public static int[] removeElement(int[] array, int element) {
+ @Nullable
+ public static int[] removeElement(@Nullable int[] array, int element) {
int index = indexOf(array, element);
if (index == INDEX_NOT_FOUND) {
return copy(array);
@@ -943,11 +1050,14 @@ public static int[] removeElement(int[] array, int element) {
return remove(array, index);
}
- public static long[] remove(long[] array, int index) {
+ @Nullable
+ public static long[] remove(@Nullable long[] array, int index) {
+ if (array == null) return null;
return (long[]) remove((Object) array, index);
}
- public static long[] removeElement(long[] array, long element) {
+ @Nullable
+ public static long[] removeElement(@Nullable long[] array, long element) {
int index = indexOf(array, element);
if (index == INDEX_NOT_FOUND) {
return copy(array);
@@ -955,11 +1065,14 @@ public static long[] removeElement(long[] array, long element) {
return remove(array, index);
}
- public static short[] remove(short[] array, int index) {
+ @Nullable
+ public static short[] remove(@Nullable short[] array, int index) {
+ if (array == null) return null;
return (short[]) remove((Object) array, index);
}
- public static short[] removeElement(short[] array, short element) {
+ @Nullable
+ public static short[] removeElement(@Nullable short[] array, short element) {
int index = indexOf(array, element);
if (index == INDEX_NOT_FOUND) {
return copy(array);
@@ -967,7 +1080,8 @@ public static short[] removeElement(short[] array, short element) {
return remove(array, index);
}
- private static Object remove(Object array, int index) {
+ @NonNull
+ private static Object remove(@NonNull Object array, int index) {
int length = getLength(array);
if (index < 0 || index >= length) {
throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
@@ -986,11 +1100,11 @@ private static Object remove(Object array, int index) {
// object indexOf
///////////////////////////////////////////////////////////////////////////
- public static int indexOf(Object[] array, Object objectToFind) {
+ public static int indexOf(@Nullable Object[] array, @Nullable Object objectToFind) {
return indexOf(array, objectToFind, 0);
}
- public static int indexOf(Object[] array, final Object objectToFind, int startIndex) {
+ public static int indexOf(@Nullable Object[] array, @Nullable final Object objectToFind, int startIndex) {
if (array == null) {
return INDEX_NOT_FOUND;
}
@@ -1013,11 +1127,11 @@ public static int indexOf(Object[] array, final Object objectToFind, int startIn
return INDEX_NOT_FOUND;
}
- public static int lastIndexOf(Object[] array, Object objectToFind) {
+ public static int lastIndexOf(@Nullable Object[] array, @Nullable Object objectToFind) {
return lastIndexOf(array, objectToFind, Integer.MAX_VALUE);
}
- public static int lastIndexOf(Object[] array, Object objectToFind, int startIndex) {
+ public static int lastIndexOf(@Nullable Object[] array, @Nullable Object objectToFind, int startIndex) {
if (array == null) {
return INDEX_NOT_FOUND;
}
@@ -1042,7 +1156,7 @@ public static int lastIndexOf(Object[] array, Object objectToFind, int startInde
return INDEX_NOT_FOUND;
}
- public static boolean contains(Object[] array, Object objectToFind) {
+ public static boolean contains(@Nullable Object[] array, @Nullable Object objectToFind) {
return indexOf(array, objectToFind) != INDEX_NOT_FOUND;
}
@@ -1050,11 +1164,11 @@ public static boolean contains(Object[] array, Object objectToFind) {
// long indexOf
///////////////////////////////////////////////////////////////////////////
- public static int indexOf(long[] array, long valueToFind) {
+ public static int indexOf(@Nullable long[] array, long valueToFind) {
return indexOf(array, valueToFind, 0);
}
- public static int indexOf(long[] array, long valueToFind, int startIndex) {
+ public static int indexOf(@Nullable long[] array, long valueToFind, int startIndex) {
if (array == null) {
return INDEX_NOT_FOUND;
}
@@ -1069,11 +1183,11 @@ public static int indexOf(long[] array, long valueToFind, int startIndex) {
return INDEX_NOT_FOUND;
}
- public static int lastIndexOf(long[] array, long valueToFind) {
+ public static int lastIndexOf(@Nullable long[] array, long valueToFind) {
return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
}
- public static int lastIndexOf(long[] array, long valueToFind, int startIndex) {
+ public static int lastIndexOf(@Nullable long[] array, long valueToFind, int startIndex) {
if (array == null) {
return INDEX_NOT_FOUND;
}
@@ -1090,7 +1204,7 @@ public static int lastIndexOf(long[] array, long valueToFind, int startIndex) {
return INDEX_NOT_FOUND;
}
- public static boolean contains(long[] array, long valueToFind) {
+ public static boolean contains(@Nullable long[] array, long valueToFind) {
return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
}
@@ -1098,11 +1212,11 @@ public static boolean contains(long[] array, long valueToFind) {
// int indexOf
///////////////////////////////////////////////////////////////////////////
- public static int indexOf(int[] array, int valueToFind) {
+ public static int indexOf(@Nullable int[] array, int valueToFind) {
return indexOf(array, valueToFind, 0);
}
- public static int indexOf(int[] array, int valueToFind, int startIndex) {
+ public static int indexOf(@Nullable int[] array, int valueToFind, int startIndex) {
if (array == null) {
return INDEX_NOT_FOUND;
}
@@ -1117,11 +1231,11 @@ public static int indexOf(int[] array, int valueToFind, int startIndex) {
return INDEX_NOT_FOUND;
}
- public static int lastIndexOf(int[] array, int valueToFind) {
+ public static int lastIndexOf(@Nullable int[] array, int valueToFind) {
return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
}
- public static int lastIndexOf(int[] array, int valueToFind, int startIndex) {
+ public static int lastIndexOf(@Nullable int[] array, int valueToFind, int startIndex) {
if (array == null) {
return INDEX_NOT_FOUND;
}
@@ -1138,7 +1252,7 @@ public static int lastIndexOf(int[] array, int valueToFind, int startIndex) {
return INDEX_NOT_FOUND;
}
- public static boolean contains(int[] array, int valueToFind) {
+ public static boolean contains(@Nullable int[] array, int valueToFind) {
return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
}
@@ -1146,11 +1260,11 @@ public static boolean contains(int[] array, int valueToFind) {
// short indexOf
///////////////////////////////////////////////////////////////////////////
- public static int indexOf(short[] array, short valueToFind) {
+ public static int indexOf(@Nullable short[] array, short valueToFind) {
return indexOf(array, valueToFind, 0);
}
- public static int indexOf(short[] array, short valueToFind, int startIndex) {
+ public static int indexOf(@Nullable short[] array, short valueToFind, int startIndex) {
if (array == null) {
return INDEX_NOT_FOUND;
}
@@ -1165,11 +1279,11 @@ public static int indexOf(short[] array, short valueToFind, int startIndex) {
return INDEX_NOT_FOUND;
}
- public static int lastIndexOf(short[] array, short valueToFind) {
+ public static int lastIndexOf(@Nullable short[] array, short valueToFind) {
return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
}
- public static int lastIndexOf(short[] array, short valueToFind, int startIndex) {
+ public static int lastIndexOf(@Nullable short[] array, short valueToFind, int startIndex) {
if (array == null) {
return INDEX_NOT_FOUND;
}
@@ -1186,7 +1300,7 @@ public static int lastIndexOf(short[] array, short valueToFind, int startIndex)
return INDEX_NOT_FOUND;
}
- public static boolean contains(short[] array, short valueToFind) {
+ public static boolean contains(@Nullable short[] array, short valueToFind) {
return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
}
@@ -1194,11 +1308,11 @@ public static boolean contains(short[] array, short valueToFind) {
// char indexOf
///////////////////////////////////////////////////////////////////////////
- public static int indexOf(char[] array, char valueToFind) {
+ public static int indexOf(@Nullable char[] array, char valueToFind) {
return indexOf(array, valueToFind, 0);
}
- public static int indexOf(char[] array, char valueToFind, int startIndex) {
+ public static int indexOf(@Nullable char[] array, char valueToFind, int startIndex) {
if (array == null) {
return INDEX_NOT_FOUND;
}
@@ -1213,11 +1327,11 @@ public static int indexOf(char[] array, char valueToFind, int startIndex) {
return INDEX_NOT_FOUND;
}
- public static int lastIndexOf(char[] array, char valueToFind) {
+ public static int lastIndexOf(@Nullable char[] array, char valueToFind) {
return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
}
- public static int lastIndexOf(char[] array, char valueToFind, int startIndex) {
+ public static int lastIndexOf(@Nullable char[] array, char valueToFind, int startIndex) {
if (array == null) {
return INDEX_NOT_FOUND;
}
@@ -1234,7 +1348,7 @@ public static int lastIndexOf(char[] array, char valueToFind, int startIndex) {
return INDEX_NOT_FOUND;
}
- public static boolean contains(char[] array, char valueToFind) {
+ public static boolean contains(@Nullable char[] array, char valueToFind) {
return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
}
@@ -1242,11 +1356,11 @@ public static boolean contains(char[] array, char valueToFind) {
// byte indexOf
///////////////////////////////////////////////////////////////////////////
- public static int indexOf(byte[] array, byte valueToFind) {
+ public static int indexOf(@Nullable byte[] array, byte valueToFind) {
return indexOf(array, valueToFind, 0);
}
- public static int indexOf(byte[] array, byte valueToFind, int startIndex) {
+ public static int indexOf(@Nullable byte[] array, byte valueToFind, int startIndex) {
if (array == null) {
return INDEX_NOT_FOUND;
}
@@ -1261,11 +1375,11 @@ public static int indexOf(byte[] array, byte valueToFind, int startIndex) {
return INDEX_NOT_FOUND;
}
- public static int lastIndexOf(byte[] array, byte valueToFind) {
+ public static int lastIndexOf(@Nullable byte[] array, byte valueToFind) {
return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
}
- public static int lastIndexOf(byte[] array, byte valueToFind, int startIndex) {
+ public static int lastIndexOf(@Nullable byte[] array, byte valueToFind, int startIndex) {
if (array == null) {
return INDEX_NOT_FOUND;
}
@@ -1282,7 +1396,7 @@ public static int lastIndexOf(byte[] array, byte valueToFind, int startIndex) {
return INDEX_NOT_FOUND;
}
- public static boolean contains(byte[] array, byte valueToFind) {
+ public static boolean contains(@Nullable byte[] array, byte valueToFind) {
return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
}
@@ -1290,15 +1404,15 @@ public static boolean contains(byte[] array, byte valueToFind) {
// double indexOf
///////////////////////////////////////////////////////////////////////////
- public static int indexOf(double[] array, double valueToFind) {
+ public static int indexOf(@Nullable double[] array, double valueToFind) {
return indexOf(array, valueToFind, 0);
}
- public static int indexOf(double[] array, double valueToFind, double tolerance) {
+ public static int indexOf(@Nullable double[] array, double valueToFind, double tolerance) {
return indexOf(array, valueToFind, 0, tolerance);
}
- public static int indexOf(double[] array, double valueToFind, int startIndex) {
+ public static int indexOf(@Nullable double[] array, double valueToFind, int startIndex) {
if (ArrayUtils.isEmpty(array)) {
return INDEX_NOT_FOUND;
}
@@ -1313,7 +1427,7 @@ public static int indexOf(double[] array, double valueToFind, int startIndex) {
return INDEX_NOT_FOUND;
}
- public static int indexOf(double[] array, double valueToFind, int startIndex, double tolerance) {
+ public static int indexOf(@Nullable double[] array, double valueToFind, int startIndex, double tolerance) {
if (ArrayUtils.isEmpty(array)) {
return INDEX_NOT_FOUND;
}
@@ -1330,15 +1444,15 @@ public static int indexOf(double[] array, double valueToFind, int startIndex, do
return INDEX_NOT_FOUND;
}
- public static int lastIndexOf(double[] array, double valueToFind) {
+ public static int lastIndexOf(@Nullable double[] array, double valueToFind) {
return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
}
- public static int lastIndexOf(double[] array, double valueToFind, double tolerance) {
+ public static int lastIndexOf(@Nullable double[] array, double valueToFind, double tolerance) {
return lastIndexOf(array, valueToFind, Integer.MAX_VALUE, tolerance);
}
- public static int lastIndexOf(double[] array, double valueToFind, int startIndex) {
+ public static int lastIndexOf(@Nullable double[] array, double valueToFind, int startIndex) {
if (ArrayUtils.isEmpty(array)) {
return INDEX_NOT_FOUND;
}
@@ -1355,7 +1469,7 @@ public static int lastIndexOf(double[] array, double valueToFind, int startIndex
return INDEX_NOT_FOUND;
}
- public static int lastIndexOf(double[] array, double valueToFind, int startIndex, double tolerance) {
+ public static int lastIndexOf(@Nullable double[] array, double valueToFind, int startIndex, double tolerance) {
if (ArrayUtils.isEmpty(array)) {
return INDEX_NOT_FOUND;
}
@@ -1374,11 +1488,11 @@ public static int lastIndexOf(double[] array, double valueToFind, int startIndex
return INDEX_NOT_FOUND;
}
- public static boolean contains(double[] array, double valueToFind) {
+ public static boolean contains(@Nullable double[] array, double valueToFind) {
return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
}
- public static boolean contains(double[] array, double valueToFind, double tolerance) {
+ public static boolean contains(@Nullable double[] array, double valueToFind, double tolerance) {
return indexOf(array, valueToFind, 0, tolerance) != INDEX_NOT_FOUND;
}
@@ -1386,11 +1500,11 @@ public static boolean contains(double[] array, double valueToFind, double tolera
// float indexOf
///////////////////////////////////////////////////////////////////////////
- public static int indexOf(float[] array, float valueToFind) {
+ public static int indexOf(@Nullable float[] array, float valueToFind) {
return indexOf(array, valueToFind, 0);
}
- public static int indexOf(float[] array, float valueToFind, int startIndex) {
+ public static int indexOf(@Nullable float[] array, float valueToFind, int startIndex) {
if (ArrayUtils.isEmpty(array)) {
return INDEX_NOT_FOUND;
}
@@ -1405,11 +1519,11 @@ public static int indexOf(float[] array, float valueToFind, int startIndex) {
return INDEX_NOT_FOUND;
}
- public static int lastIndexOf(float[] array, float valueToFind) {
+ public static int lastIndexOf(@Nullable float[] array, float valueToFind) {
return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
}
- public static int lastIndexOf(float[] array, float valueToFind, int startIndex) {
+ public static int lastIndexOf(@Nullable float[] array, float valueToFind, int startIndex) {
if (ArrayUtils.isEmpty(array)) {
return INDEX_NOT_FOUND;
}
@@ -1426,7 +1540,7 @@ public static int lastIndexOf(float[] array, float valueToFind, int startIndex)
return INDEX_NOT_FOUND;
}
- public static boolean contains(float[] array, float valueToFind) {
+ public static boolean contains(@Nullable float[] array, float valueToFind) {
return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
}
@@ -1434,11 +1548,11 @@ public static boolean contains(float[] array, float valueToFind) {
// bool indexOf
///////////////////////////////////////////////////////////////////////////
- public static int indexOf(boolean[] array, boolean valueToFind) {
+ public static int indexOf(@Nullable boolean[] array, boolean valueToFind) {
return indexOf(array, valueToFind, 0);
}
- public static int indexOf(boolean[] array, boolean valueToFind, int startIndex) {
+ public static int indexOf(@Nullable boolean[] array, boolean valueToFind, int startIndex) {
if (ArrayUtils.isEmpty(array)) {
return INDEX_NOT_FOUND;
}
@@ -1453,11 +1567,11 @@ public static int indexOf(boolean[] array, boolean valueToFind, int startIndex)
return INDEX_NOT_FOUND;
}
- public static int lastIndexOf(boolean[] array, boolean valueToFind) {
+ public static int lastIndexOf(@Nullable boolean[] array, boolean valueToFind) {
return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
}
- public static int lastIndexOf(boolean[] array, boolean valueToFind, int startIndex) {
+ public static int lastIndexOf(@Nullable boolean[] array, boolean valueToFind, int startIndex) {
if (ArrayUtils.isEmpty(array)) {
return INDEX_NOT_FOUND;
}
@@ -1474,7 +1588,7 @@ public static int lastIndexOf(boolean[] array, boolean valueToFind, int startInd
return INDEX_NOT_FOUND;
}
- public static boolean contains(boolean[] array, boolean valueToFind) {
+ public static boolean contains(@Nullable boolean[] array, boolean valueToFind) {
return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
}
@@ -1482,7 +1596,8 @@ public static boolean contains(boolean[] array, boolean valueToFind) {
// char converters
///////////////////////////////////////////////////////////////////////////
- public static char[] toPrimitive(Character[] array) {
+ @Nullable
+ public static char[] toPrimitive(@Nullable Character[] array) {
if (array == null) {
return null;
} else if (array.length == 0) {
@@ -1495,7 +1610,8 @@ public static char[] toPrimitive(Character[] array) {
return result;
}
- public static char[] toPrimitive(Character[] array, char valueForNull) {
+ @Nullable
+ public static char[] toPrimitive(@Nullable Character[] array, char valueForNull) {
if (array == null) {
return null;
} else if (array.length == 0) {
@@ -1509,7 +1625,8 @@ public static char[] toPrimitive(Character[] array, char valueForNull) {
return result;
}
- public static Character[] toObject(char[] array) {
+ @Nullable
+ public static Character[] toObject(@Nullable char[] array) {
if (array == null) {
return null;
} else if (array.length == 0) {
@@ -1526,7 +1643,8 @@ public static Character[] toObject(char[] array) {
// long converters
///////////////////////////////////////////////////////////////////////////
- public static long[] toPrimitive(Long[] array) {
+ @Nullable
+ public static long[] toPrimitive(@Nullable Long[] array) {
if (array == null) {
return null;
} else if (array.length == 0) {
@@ -1539,7 +1657,8 @@ public static long[] toPrimitive(Long[] array) {
return result;
}
- public static long[] toPrimitive(Long[] array, long valueForNull) {
+ @Nullable
+ public static long[] toPrimitive(@Nullable Long[] array, long valueForNull) {
if (array == null) {
return null;
} else if (array.length == 0) {
@@ -1553,7 +1672,8 @@ public static long[] toPrimitive(Long[] array, long valueForNull) {
return result;
}
- public static Long[] toObject(long[] array) {
+ @Nullable
+ public static Long[] toObject(@Nullable long[] array) {
if (array == null) {
return null;
} else if (array.length == 0) {
@@ -1570,7 +1690,8 @@ public static Long[] toObject(long[] array) {
// int converters
///////////////////////////////////////////////////////////////////////////
- public static int[] toPrimitive(Integer[] array) {
+ @Nullable
+ public static int[] toPrimitive(@Nullable Integer[] array) {
if (array == null) {
return null;
} else if (array.length == 0) {
@@ -1583,7 +1704,8 @@ public static int[] toPrimitive(Integer[] array) {
return result;
}
- public static int[] toPrimitive(Integer[] array, int valueForNull) {
+ @Nullable
+ public static int[] toPrimitive(@Nullable Integer[] array, int valueForNull) {
if (array == null) {
return null;
} else if (array.length == 0) {
@@ -1597,7 +1719,8 @@ public static int[] toPrimitive(Integer[] array, int valueForNull) {
return result;
}
- public static Integer[] toObject(int[] array) {
+ @Nullable
+ public static Integer[] toObject(@Nullable int[] array) {
if (array == null) {
return null;
} else if (array.length == 0) {
@@ -1614,7 +1737,8 @@ public static Integer[] toObject(int[] array) {
// short converters
///////////////////////////////////////////////////////////////////////////
- public static short[] toPrimitive(Short[] array) {
+ @Nullable
+ public static short[] toPrimitive(@Nullable Short[] array) {
if (array == null) {
return null;
} else if (array.length == 0) {
@@ -1627,7 +1751,8 @@ public static short[] toPrimitive(Short[] array) {
return result;
}
- public static short[] toPrimitive(Short[] array, short valueForNull) {
+ @Nullable
+ public static short[] toPrimitive(@Nullable Short[] array, short valueForNull) {
if (array == null) {
return null;
} else if (array.length == 0) {
@@ -1641,7 +1766,8 @@ public static short[] toPrimitive(Short[] array, short valueForNull) {
return result;
}
- public static Short[] toObject(short[] array) {
+ @Nullable
+ public static Short[] toObject(@Nullable short[] array) {
if (array == null) {
return null;
} else if (array.length == 0) {
@@ -1658,7 +1784,8 @@ public static Short[] toObject(short[] array) {
// byte converters
///////////////////////////////////////////////////////////////////////////
- public static byte[] toPrimitive(Byte[] array) {
+ @Nullable
+ public static byte[] toPrimitive(@Nullable Byte[] array) {
if (array == null) {
return null;
} else if (array.length == 0) {
@@ -1671,7 +1798,8 @@ public static byte[] toPrimitive(Byte[] array) {
return result;
}
- public static byte[] toPrimitive(Byte[] array, byte valueForNull) {
+ @Nullable
+ public static byte[] toPrimitive(@Nullable Byte[] array, byte valueForNull) {
if (array == null) {
return null;
} else if (array.length == 0) {
@@ -1685,7 +1813,8 @@ public static byte[] toPrimitive(Byte[] array, byte valueForNull) {
return result;
}
- public static Byte[] toObject(byte[] array) {
+ @Nullable
+ public static Byte[] toObject(@Nullable byte[] array) {
if (array == null) {
return null;
} else if (array.length == 0) {
@@ -1702,7 +1831,8 @@ public static Byte[] toObject(byte[] array) {
// double converters
///////////////////////////////////////////////////////////////////////////
- public static double[] toPrimitive(Double[] array) {
+ @Nullable
+ public static double[] toPrimitive(@Nullable Double[] array) {
if (array == null) {
return null;
} else if (array.length == 0) {
@@ -1715,7 +1845,8 @@ public static double[] toPrimitive(Double[] array) {
return result;
}
- public static double[] toPrimitive(Double[] array, double valueForNull) {
+ @Nullable
+ public static double[] toPrimitive(@Nullable Double[] array, double valueForNull) {
if (array == null) {
return null;
} else if (array.length == 0) {
@@ -1729,7 +1860,8 @@ public static double[] toPrimitive(Double[] array, double valueForNull) {
return result;
}
- public static Double[] toObject(double[] array) {
+ @Nullable
+ public static Double[] toObject(@Nullable double[] array) {
if (array == null) {
return null;
} else if (array.length == 0) {
@@ -1746,7 +1878,8 @@ public static Double[] toObject(double[] array) {
// float converters
///////////////////////////////////////////////////////////////////////////
- public static float[] toPrimitive(Float[] array) {
+ @Nullable
+ public static float[] toPrimitive(@Nullable Float[] array) {
if (array == null) {
return null;
} else if (array.length == 0) {
@@ -1759,7 +1892,8 @@ public static float[] toPrimitive(Float[] array) {
return result;
}
- public static float[] toPrimitive(Float[] array, float valueForNull) {
+ @Nullable
+ public static float[] toPrimitive(@Nullable Float[] array, float valueForNull) {
if (array == null) {
return null;
} else if (array.length == 0) {
@@ -1773,7 +1907,8 @@ public static float[] toPrimitive(Float[] array, float valueForNull) {
return result;
}
- public static Float[] toObject(float[] array) {
+ @Nullable
+ public static Float[] toObject(@Nullable float[] array) {
if (array == null) {
return null;
} else if (array.length == 0) {
@@ -1790,7 +1925,8 @@ public static Float[] toObject(float[] array) {
// boolean converters
///////////////////////////////////////////////////////////////////////////
- public static boolean[] toPrimitive(Boolean[] array) {
+ @Nullable
+ public static boolean[] toPrimitive(@Nullable Boolean[] array) {
if (array == null) {
return null;
} else if (array.length == 0) {
@@ -1803,7 +1939,8 @@ public static boolean[] toPrimitive(Boolean[] array) {
return result;
}
- public static boolean[] toPrimitive(Boolean[] array, boolean valueForNull) {
+ @Nullable
+ public static boolean[] toPrimitive(@Nullable Boolean[] array, boolean valueForNull) {
if (array == null) {
return null;
} else if (array.length == 0) {
@@ -1817,7 +1954,8 @@ public static boolean[] toPrimitive(Boolean[] array, boolean valueForNull) {
return result;
}
- public static Boolean[] toObject(boolean[] array) {
+ @Nullable
+ public static Boolean[] toObject(@Nullable boolean[] array) {
if (array == null) {
return null;
} else if (array.length == 0) {
@@ -1830,67 +1968,71 @@ public static Boolean[] toObject(boolean[] array) {
return result;
}
- public static List asList(T... array) {
+ @NonNull
+ public static List asList(@Nullable T... array) {
if (array == null || array.length == 0) {
return Collections.emptyList();
}
return Arrays.asList(array);
}
- public static List asUnmodifiableList(T... array) {
+ @NonNull
+ public static List asUnmodifiableList(@Nullable T... array) {
return Collections.unmodifiableList(asList(array));
}
- public static List asArrayList(T... array) {
+ @NonNull
+ public static List asArrayList(@Nullable T... array) {
List list = new ArrayList<>();
if (array == null || array.length == 0) return list;
list.addAll(Arrays.asList(array));
return list;
}
- public static List asLinkedList(T... array) {
+ @NonNull
+ public static List asLinkedList(@Nullable T... array) {
List list = new LinkedList<>();
if (array == null || array.length == 0) return list;
list.addAll(Arrays.asList(array));
return list;
}
- public static void sort(T[] array, Comparator super T> c) {
+ public static void sort(@Nullable T[] array, Comparator super T> c) {
if (array == null || array.length < 2) return;
Arrays.sort(array, c);
}
- public static void sort(byte[] array) {
+ public static void sort(@Nullable byte[] array) {
if (array == null || array.length < 2) return;
Arrays.sort(array);
}
- public static void sort(char[] array) {
+ public static void sort(@Nullable char[] array) {
if (array == null || array.length < 2) return;
Arrays.sort(array);
}
- public static void sort(double[] array) {
+ public static void sort(@Nullable double[] array) {
if (array == null || array.length < 2) return;
Arrays.sort(array);
}
- public static void sort(float[] array) {
+ public static void sort(@Nullable float[] array) {
if (array == null || array.length < 2) return;
Arrays.sort(array);
}
- public static void sort(int[] array) {
+ public static void sort(@Nullable int[] array) {
if (array == null || array.length < 2) return;
Arrays.sort(array);
}
- public static void sort(long[] array) {
+ public static void sort(@Nullable long[] array) {
if (array == null || array.length < 2) return;
Arrays.sort(array);
}
- public static void sort(short[] array) {
+ public static void sort(@Nullable short[] array) {
if (array == null || array.length < 2) return;
Arrays.sort(array);
}
@@ -1903,7 +2045,7 @@ public static void sort(short[] array) {
* @param array The array.
* @param closure the closure to perform, may be null
*/
- public static void forAllDo(Object array, Closure closure) {
+ public static void forAllDo(@Nullable Object array, @Nullable Closure closure) {
if (array == null || closure == null) return;
if (array instanceof Object[]) {
Object[] objects = (Object[]) array;
@@ -1970,7 +2112,8 @@ public static void forAllDo(Object array, Closure closure) {
* @param array The array.
* @return the string of array
*/
- public static String toString(Object array) {
+ @NonNull
+ public static String toString(@Nullable Object array) {
if (array == null) return "null";
if (array instanceof Object[]) {
return Arrays.deepToString((Object[]) array);
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/BarUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/BarUtils.java
index c6427c9cb8..e8cacc5f0c 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/BarUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/BarUtils.java
@@ -1,19 +1,15 @@
package com.blankj.utilcode.util;
+import static android.Manifest.permission.EXPAND_STATUS_BAR;
+
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
-import android.content.ContextWrapper;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Point;
import android.os.Build;
-import android.support.annotation.ColorInt;
-import android.support.annotation.NonNull;
-import android.support.annotation.RequiresApi;
-import android.support.annotation.RequiresPermission;
-import android.support.v4.widget.DrawerLayout;
-import android.util.Log;
+import android.provider.Settings;
import android.util.TypedValue;
import android.view.Display;
import android.view.KeyCharacterMap;
@@ -25,9 +21,13 @@
import android.view.Window;
import android.view.WindowManager;
-import java.lang.reflect.Method;
+import androidx.annotation.ColorInt;
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+import androidx.annotation.RequiresPermission;
+import androidx.drawerlayout.widget.DrawerLayout;
-import static android.Manifest.permission.EXPAND_STATUS_BAR;
+import java.lang.reflect.Method;
/**
*
@@ -44,8 +44,8 @@ public final class BarUtils {
///////////////////////////////////////////////////////////////////////////
private static final String TAG_STATUS_BAR = "TAG_STATUS_BAR";
- private static final String TAG_OFFSET = "TAG_OFFSET";
- private static final int KEY_OFFSET = -123;
+ private static final String TAG_OFFSET = "TAG_OFFSET";
+ private static final int KEY_OFFSET = -123;
private BarUtils() {
throw new UnsupportedOperationException("u can't instantiate me...");
@@ -57,7 +57,7 @@ private BarUtils() {
* @return the status bar's height
*/
public static int getStatusBarHeight() {
- Resources resources = Utils.getApp().getResources();
+ Resources resources = Resources.getSystem();
int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
return resources.getDimensionPixelSize(resourceId);
}
@@ -194,14 +194,14 @@ public static void subtractMarginTopEqualStatusBarHeight(@NonNull View view) {
view.setTag(KEY_OFFSET, false);
}
- private static void addMarginTopEqualStatusBarHeight(final Window window) {
+ private static void addMarginTopEqualStatusBarHeight(@NonNull final Window window) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return;
View withTag = window.getDecorView().findViewWithTag(TAG_OFFSET);
if (withTag == null) return;
addMarginTopEqualStatusBarHeight(withTag);
}
- private static void subtractMarginTopEqualStatusBarHeight(final Window window) {
+ private static void subtractMarginTopEqualStatusBarHeight(@NonNull final Window window) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return;
View withTag = window.getDecorView().findViewWithTag(TAG_OFFSET);
if (withTag == null) return;
@@ -272,7 +272,7 @@ public static View setStatusBarColor(@NonNull final Window window,
public static void setStatusBarColor(@NonNull final View fakeStatusBar,
@ColorInt final int color) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return;
- Activity activity = getActivityByView(fakeStatusBar);
+ Activity activity = UtilsBridge.getActivityByContext(fakeStatusBar.getContext());
if (activity == null) return;
transparentStatusBar(activity);
fakeStatusBar.setVisibility(View.VISIBLE);
@@ -289,7 +289,7 @@ public static void setStatusBarColor(@NonNull final View fakeStatusBar,
*/
public static void setStatusBarCustom(@NonNull final View fakeStatusBar) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return;
- Activity activity = getActivityByView(fakeStatusBar);
+ Activity activity = UtilsBridge.getActivityByContext(fakeStatusBar.getContext());
if (activity == null) return;
transparentStatusBar(activity);
fakeStatusBar.setVisibility(View.VISIBLE);
@@ -334,7 +334,7 @@ public static void setStatusBarColor4Drawer(@NonNull final DrawerLayout drawer,
@ColorInt final int color,
final boolean isTop) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return;
- Activity activity = getActivityByView(fakeStatusBar);
+ Activity activity = UtilsBridge.getActivityByContext(fakeStatusBar.getContext());
if (activity == null) return;
transparentStatusBar(activity);
drawer.setFitsSystemWindows(false);
@@ -349,13 +349,13 @@ public static void setStatusBarColor4Drawer(@NonNull final DrawerLayout drawer,
}
}
- private static View applyStatusBarColor(final Activity activity,
+ private static View applyStatusBarColor(@NonNull final Activity activity,
final int color,
boolean isDecor) {
return applyStatusBarColor(activity.getWindow(), color, isDecor);
}
- private static View applyStatusBarColor(final Window window,
+ private static View applyStatusBarColor(@NonNull final Window window,
final int color,
boolean isDecor) {
ViewGroup parent = isDecor ?
@@ -374,25 +374,25 @@ private static View applyStatusBarColor(final Window window,
return fakeStatusBarView;
}
- private static void hideStatusBarView(final Activity activity) {
+ private static void hideStatusBarView(@NonNull final Activity activity) {
hideStatusBarView(activity.getWindow());
}
- private static void hideStatusBarView(final Window window) {
+ private static void hideStatusBarView(@NonNull final Window window) {
ViewGroup decorView = (ViewGroup) window.getDecorView();
View fakeStatusBarView = decorView.findViewWithTag(TAG_STATUS_BAR);
if (fakeStatusBarView == null) return;
fakeStatusBarView.setVisibility(View.GONE);
}
- private static void showStatusBarView(final Window window) {
+ private static void showStatusBarView(@NonNull final Window window) {
ViewGroup decorView = (ViewGroup) window.getDecorView();
View fakeStatusBarView = decorView.findViewWithTag(TAG_STATUS_BAR);
if (fakeStatusBarView == null) return;
fakeStatusBarView.setVisibility(View.VISIBLE);
}
- private static View createStatusBarView(final Context context,
+ private static View createStatusBarView(@NonNull final Context context,
final int color) {
View statusBarView = new View(context);
statusBarView.setLayoutParams(new ViewGroup.LayoutParams(
@@ -402,11 +402,11 @@ private static View createStatusBarView(final Context context,
return statusBarView;
}
- public static void transparentStatusBar(final Activity activity) {
+ public static void transparentStatusBar(@NonNull final Activity activity) {
transparentStatusBar(activity.getWindow());
}
- public static void transparentStatusBar(final Window window) {
+ public static void transparentStatusBar(@NonNull final Window window) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) return;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
@@ -483,7 +483,7 @@ private static void invokePanels(final String methodName) {
* @return the navigation bar's height
*/
public static int getNavBarHeight() {
- Resources res = Utils.getApp().getResources();
+ Resources res = Resources.getSystem();
int resourceId = res.getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId != 0) {
return res.getDimensionPixelSize(resourceId);
@@ -517,9 +517,7 @@ public static void setNavBarVisibility(@NonNull final Window window, boolean isV
final View child = decorView.getChildAt(i);
final int id = child.getId();
if (id != View.NO_ID) {
- String resourceEntryName = Utils.getApp()
- .getResources()
- .getResourceEntryName(id);
+ String resourceEntryName = getResNameById(id);
if ("navigationBarBackground".equals(resourceEntryName)) {
child.setVisibility(isVisible ? View.VISIBLE : View.INVISIBLE);
}
@@ -560,9 +558,7 @@ public static boolean isNavBarVisible(@NonNull final Window window) {
final View child = decorView.getChildAt(i);
final int id = child.getId();
if (id != View.NO_ID) {
- String resourceEntryName = Utils.getApp()
- .getResources()
- .getResourceEntryName(id);
+ String resourceEntryName = getResNameById(id);
if ("navigationBarBackground".equals(resourceEntryName)
&& child.getVisibility() == View.VISIBLE) {
isVisible = true;
@@ -571,12 +567,33 @@ public static boolean isNavBarVisible(@NonNull final Window window) {
}
}
if (isVisible) {
+ // 对于三星手机,android10以下非OneUI2的版本,比如 s8,note8 等设备上,
+ // 导航栏显示存在bug:"当用户隐藏导航栏时显示输入法的时候导航栏会跟随显示",会导致隐藏输入法之后判断错误
+ // 这个问题在 OneUI 2 & android 10 版本已修复
+ if (UtilsBridge.isSamsung()
+ && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1
+ && Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+ try {
+ return Settings.Global.getInt(Utils.getApp().getContentResolver(), "navigationbar_hide_bar_enabled") == 0;
+ } catch (Exception ignore) {
+ }
+ }
+
int visibility = decorView.getSystemUiVisibility();
isVisible = (visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
}
+
return isVisible;
}
+ private static String getResNameById(int id) {
+ try {
+ return Utils.getApp().getResources().getResourceEntryName(id);
+ } catch (Exception ignore) {
+ return "";
+ }
+ }
+
/**
* Set the navigation bar's color.
*
@@ -651,7 +668,7 @@ public static boolean isSupportNavBar() {
*/
public static void setNavBarLightMode(@NonNull final Activity activity,
final boolean isLightMode) {
- setStatusBarLightMode(activity.getWindow(), isLightMode);
+ setNavBarLightMode(activity.getWindow(), isLightMode);
}
/**
@@ -681,7 +698,7 @@ public static void setNavBarLightMode(@NonNull final Window window,
* @return {@code true}: yes
{@code false}: no
*/
public static boolean isNavBarLightMode(@NonNull final Activity activity) {
- return isStatusBarLightMode(activity.getWindow());
+ return isNavBarLightMode(activity.getWindow());
}
/**
@@ -699,15 +716,25 @@ public static boolean isNavBarLightMode(@NonNull final Window window) {
return false;
}
- private static Activity getActivityByView(@NonNull final View view) {
- Context context = view.getContext();
- while (context instanceof ContextWrapper) {
- if (context instanceof Activity) {
- return (Activity) context;
+ public static void transparentNavBar(@NonNull final Activity activity) {
+ transparentNavBar(activity.getWindow());
+ }
+
+ public static void transparentNavBar(@NonNull final Window window) {
+ if (Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) return;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ window.setNavigationBarContrastEnforced(false);
+ }
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ window.setNavigationBarColor(Color.TRANSPARENT);
+ } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ if ((window.getAttributes().flags & WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION) == 0) {
+ window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
- context = ((ContextWrapper) context).getBaseContext();
}
- Log.e("BarUtils", "the view's Context is not an Activity.");
- return null;
+ View decorView = window.getDecorView();
+ int vis = decorView.getSystemUiVisibility();
+ int option = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
+ decorView.setSystemUiVisibility(vis | option);
}
}
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/BrightnessUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/BrightnessUtils.java
index f9344b0a59..08dd46ff9b 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/BrightnessUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/BrightnessUtils.java
@@ -2,11 +2,12 @@
import android.content.ContentResolver;
import android.provider.Settings;
-import android.support.annotation.IntRange;
-import android.support.annotation.NonNull;
import android.view.Window;
import android.view.WindowManager;
+import androidx.annotation.IntRange;
+import androidx.annotation.NonNull;
+
/**
*
* author: Blankj
@@ -105,7 +106,7 @@ public static void setWindowBrightness(@NonNull final Window window,
* @param window 窗口
* @return 屏幕亮度 0-255
*/
- public static int getWindowBrightness(final Window window) {
+ public static int getWindowBrightness(@NonNull final Window window) {
WindowManager.LayoutParams lp = window.getAttributes();
float brightness = lp.screenBrightness;
if (brightness < 0) return getBrightness();
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/BusUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/BusUtils.java
index 269c384d3b..537a55fd92 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/BusUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/BusUtils.java
@@ -8,8 +8,6 @@
import java.lang.annotation.Target;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -18,6 +16,9 @@
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
/**
*
* author: Blankj
@@ -31,10 +32,9 @@ public final class BusUtils {
private static final Object NULL = "nULl";
private static final String TAG = "BusUtils";
- private final Map> mTag_BusInfoListMap = new HashMap<>();
-
+ private final Map> mTag_BusInfoListMap = new ConcurrentHashMap<>();
private final Map> mClassName_BusesMap = new ConcurrentHashMap<>();
- private final Map> mClassName_TagsMap = new HashMap<>();
+ private final Map> mClassName_TagsMap = new ConcurrentHashMap<>();
private final Map> mClassName_Tag_Arg4StickyMap = new ConcurrentHashMap<>();
private BusUtils() {
@@ -58,33 +58,33 @@ private void registerBus(String tag,
boolean sticky, String threadMode, int priority) {
List busInfoList = mTag_BusInfoListMap.get(tag);
if (busInfoList == null) {
- busInfoList = new ArrayList<>();
+ busInfoList = new CopyOnWriteArrayList<>();
mTag_BusInfoListMap.put(tag, busInfoList);
}
- busInfoList.add(new BusInfo(className, funName, paramType, paramName, sticky, threadMode, priority));
+ busInfoList.add(new BusInfo(tag, className, funName, paramType, paramName, sticky, threadMode, priority));
}
- public static void register(final Object bus) {
+ public static void register(@Nullable final Object bus) {
getInstance().registerInner(bus);
}
- public static void unregister(final Object bus) {
+ public static void unregister(@Nullable final Object bus) {
getInstance().unregisterInner(bus);
}
- public static void post(final String tag) {
+ public static void post(@NonNull final String tag) {
post(tag, NULL);
}
- public static void post(final String tag, final Object arg) {
+ public static void post(@NonNull final String tag, @NonNull final Object arg) {
getInstance().postInner(tag, arg);
}
- public static void postSticky(final String tag) {
+ public static void postSticky(@NonNull final String tag) {
postSticky(tag, NULL);
}
- public static void postSticky(final String tag, final Object arg) {
+ public static void postSticky(@NonNull final String tag, final Object arg) {
getInstance().postStickyInner(tag, arg);
}
@@ -105,30 +105,44 @@ private static BusUtils getInstance() {
return LazyHolder.INSTANCE;
}
- private void registerInner(final Object bus) {
+ private void registerInner(@Nullable final Object bus) {
if (bus == null) return;
- Class aClass = bus.getClass();
+ Class> aClass = bus.getClass();
String className = aClass.getName();
+ boolean isNeedRecordTags = false;
synchronized (mClassName_BusesMap) {
Set buses = mClassName_BusesMap.get(className);
if (buses == null) {
buses = new CopyOnWriteArraySet<>();
mClassName_BusesMap.put(className, buses);
+ isNeedRecordTags = true;
}
- buses.add(bus);
+ if (buses.contains(bus)) {
+ Log.w(TAG, "The bus of <" + bus + "> already registered.");
+ return;
+ } else {
+ buses.add(bus);
+ }
+ }
+ if (isNeedRecordTags) {
+ recordTags(aClass, className);
}
+ consumeStickyIfExist(bus);
+ }
+
+ private void recordTags(Class> aClass, String className) {
List tags = mClassName_TagsMap.get(className);
if (tags == null) {
synchronized (mClassName_TagsMap) {
tags = mClassName_TagsMap.get(className);
if (tags == null) {
- tags = new ArrayList<>();
+ tags = new CopyOnWriteArrayList<>();
for (Map.Entry> entry : mTag_BusInfoListMap.entrySet()) {
for (BusInfo busInfo : entry.getValue()) {
try {
if (Class.forName(busInfo.className).isAssignableFrom(aClass)) {
tags.add(entry.getKey());
- busInfo.classNames.add(className);
+ busInfo.subClassNames.add(className);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
@@ -139,15 +153,38 @@ private void registerInner(final Object bus) {
}
}
}
- processSticky(bus);
}
- private void processSticky(final Object bus) {
+ private void consumeStickyIfExist(final Object bus) {
Map tagArgMap = mClassName_Tag_Arg4StickyMap.get(bus.getClass().getName());
if (tagArgMap == null) return;
synchronized (mClassName_Tag_Arg4StickyMap) {
for (Map.Entry tagArgEntry : tagArgMap.entrySet()) {
- postInner(tagArgEntry.getKey(), tagArgEntry.getValue());
+ consumeSticky(bus, tagArgEntry.getKey(), tagArgEntry.getValue());
+ }
+ }
+ }
+
+ private void consumeSticky(final Object bus, final String tag, final Object arg) {
+ List busInfoList = mTag_BusInfoListMap.get(tag);
+ if (busInfoList == null) {
+ Log.e(TAG, "The bus of tag <" + tag + "> is not exists.");
+ return;
+ }
+ for (BusInfo busInfo : busInfoList) {
+ if (!busInfo.subClassNames.contains(bus.getClass().getName())) {
+ continue;
+ }
+ if (!busInfo.sticky) {
+ continue;
+ }
+
+ synchronized (mClassName_Tag_Arg4StickyMap) {
+ Map tagArgMap = mClassName_Tag_Arg4StickyMap.get(busInfo.className);
+ if (tagArgMap == null || !tagArgMap.containsKey(tag)) {
+ continue;
+ }
+ invokeBus(bus, arg, busInfo, true);
}
}
}
@@ -173,18 +210,29 @@ private void postInner(final String tag, final Object arg, final boolean sticky)
List busInfoList = mTag_BusInfoListMap.get(tag);
if (busInfoList == null) {
Log.e(TAG, "The bus of tag <" + tag + "> is not exists.");
+ if (mTag_BusInfoListMap.isEmpty()) {
+ Log.e(TAG, "Please check whether the bus plugin is applied.");
+ }
return;
}
for (BusInfo busInfo : busInfoList) {
- if (busInfo.method == null) {
- Method method = getMethodByBusInfo(busInfo);
- if (method == null) {
- return;
- }
- busInfo.method = method;
+ invokeBus(arg, busInfo, sticky);
+ }
+ }
+
+ private void invokeBus(Object arg, BusInfo busInfo, boolean sticky) {
+ invokeBus(null, arg, busInfo, sticky);
+ }
+
+ private void invokeBus(Object bus, Object arg, BusInfo busInfo, boolean sticky) {
+ if (busInfo.method == null) {
+ Method method = getMethodByBusInfo(busInfo);
+ if (method == null) {
+ return;
}
- invokeMethod(tag, arg, busInfo, sticky);
+ busInfo.method = method;
}
+ invokeMethod(bus, arg, busInfo, sticky);
}
private Method getMethodByBusInfo(BusInfo busInfo) {
@@ -225,16 +273,20 @@ private Class getClassName(String paramType) throws ClassNotFoundException {
}
}
- private void invokeMethod(final String tag, final Object arg, final BusInfo busInfo, final boolean sticky) {
+ private void invokeMethod(final Object arg, final BusInfo busInfo, final boolean sticky) {
+ invokeMethod(null, arg, busInfo, sticky);
+ }
+
+ private void invokeMethod(final Object bus, final Object arg, final BusInfo busInfo, final boolean sticky) {
Runnable runnable = new Runnable() {
@Override
public void run() {
- realInvokeMethod(tag, arg, busInfo, sticky);
+ realInvokeMethod(bus, arg, busInfo, sticky);
}
};
switch (busInfo.threadMode) {
case "MAIN":
- Utils.runOnUiThread(runnable);
+ ThreadUtils.runOnUiThread(runnable);
return;
case "IO":
ThreadUtils.getIoPool().execute(runnable);
@@ -253,22 +305,28 @@ public void run() {
}
}
- private void realInvokeMethod(final String tag, Object arg, BusInfo busInfo, boolean sticky) {
+ private void realInvokeMethod(Object bus, Object arg, BusInfo busInfo, boolean sticky) {
Set buses = new HashSet<>();
- for (String className : busInfo.classNames) {
- Set subBuses = mClassName_BusesMap.get(className);
- if (subBuses != null && !subBuses.isEmpty()) {
- buses.addAll(subBuses);
+ if (bus == null) {
+ for (String subClassName : busInfo.subClassNames) {
+ Set subBuses = mClassName_BusesMap.get(subClassName);
+ if (subBuses != null && !subBuses.isEmpty()) {
+ buses.addAll(subBuses);
+ }
}
- }
- if (buses.size() == 0) {
- if (!sticky) {
- Log.e(TAG, "The bus of tag <" + tag + "> was not registered before.");
- return;
- } else {
+ if (buses.size() == 0) {
+ if (!sticky) {
+ Log.e(TAG, "The " + busInfo + " was not registered before.");
+ }
return;
}
+ } else {
+ buses.add(bus);
}
+ invokeBuses(arg, busInfo, buses);
+ }
+
+ private void invokeBuses(Object arg, BusInfo busInfo, Set buses) {
try {
if (arg == NULL) {
for (Object bus : buses) {
@@ -292,20 +350,21 @@ private void postStickyInner(final String tag, final Object arg) {
Log.e(TAG, "The bus of tag <" + tag + "> is not exists.");
return;
}
+ // 获取多对象,然后消费各个 busInfoList
for (BusInfo busInfo : busInfoList) {
if (!busInfo.sticky) { // not sticky bus will post directly.
- postInner(tag, arg);
- return;
+ invokeBus(arg, busInfo, false);
+ continue;
}
synchronized (mClassName_Tag_Arg4StickyMap) {
Map tagArgMap = mClassName_Tag_Arg4StickyMap.get(busInfo.className);
if (tagArgMap == null) {
- tagArgMap = new HashMap<>();
+ tagArgMap = new ConcurrentHashMap<>();
mClassName_Tag_Arg4StickyMap.put(busInfo.className, tagArgMap);
}
tagArgMap.put(tag, arg);
}
- postInner(tag, arg, true);
+ invokeBus(arg, busInfo, true);
}
}
@@ -317,13 +376,11 @@ private void removeStickyInner(final String tag) {
}
for (BusInfo busInfo : busInfoList) {
if (!busInfo.sticky) {
- Log.e(TAG, "The bus of tag <" + tag + "> is not sticky.");
- return;
+ continue;
}
synchronized (mClassName_Tag_Arg4StickyMap) {
Map tagArgMap = mClassName_Tag_Arg4StickyMap.get(busInfo.className);
if (tagArgMap == null || !tagArgMap.containsKey(tag)) {
- Log.e(TAG, "The sticky bus of tag <" + tag + "> didn't post.");
return;
}
tagArgMap.remove(tag);
@@ -331,8 +388,15 @@ private void removeStickyInner(final String tag) {
}
}
+ static void registerBus4Test(String tag,
+ String className, String funName, String paramType, String paramName,
+ boolean sticky, String threadMode, int priority) {
+ getInstance().registerBus(tag, className, funName, paramType, paramName, sticky, threadMode, priority);
+ }
+
private static final class BusInfo {
+ String tag;
String className;
String funName;
String paramType;
@@ -341,10 +405,11 @@ private static final class BusInfo {
String threadMode;
int priority;
Method method;
- List classNames;
+ List subClassNames;
- BusInfo(String className, String funName, String paramType, String paramName,
+ BusInfo(String tag, String className, String funName, String paramType, String paramName,
boolean sticky, String threadMode, int priority) {
+ this.tag = tag;
this.className = className;
this.funName = funName;
this.paramType = paramType;
@@ -352,19 +417,24 @@ private static final class BusInfo {
this.sticky = sticky;
this.threadMode = threadMode;
this.priority = priority;
- this.classNames = new CopyOnWriteArrayList<>();
+ this.subClassNames = new CopyOnWriteArrayList<>();
}
@Override
public String toString() {
- return "BusInfo { desc: " + className + "#" + funName +
- ("".equals(paramType) ? "()" : ("(" + paramType + " " + paramName + ")")) +
+ return "BusInfo { tag : " + tag +
+ ", desc: " + getDesc() +
", sticky: " + sticky +
", threadMode: " + threadMode +
", method: " + method +
", priority: " + priority +
" }";
}
+
+ private String getDesc() {
+ return className + "#" + funName +
+ ("".equals(paramType) ? "()" : ("(" + paramType + " " + paramName + ")"));
+ }
}
public enum ThreadMode {
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/CacheDiskStaticUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/CacheDiskStaticUtils.java
index bb48a4b5cf..23100f60b0 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/CacheDiskStaticUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/CacheDiskStaticUtils.java
@@ -3,13 +3,15 @@
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Parcelable;
-import android.support.annotation.NonNull;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.Serializable;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
/**
*
* author: Blankj
@@ -27,7 +29,7 @@ public final class CacheDiskStaticUtils {
*
* @param cacheDiskUtils The default instance of {@link CacheDiskUtils}.
*/
- public static void setDefaultCacheDiskUtils(final CacheDiskUtils cacheDiskUtils) {
+ public static void setDefaultCacheDiskUtils(@Nullable final CacheDiskUtils cacheDiskUtils) {
sDefaultCacheDiskUtils = cacheDiskUtils;
}
@@ -37,7 +39,7 @@ public static void setDefaultCacheDiskUtils(final CacheDiskUtils cacheDiskUtils)
* @param key The key of cache.
* @param value The value of cache.
*/
- public static void put(@NonNull final String key, final byte[] value) {
+ public static void put(@NonNull final String key, @Nullable final byte[] value) {
put(key, value, getDefaultCacheDiskUtils());
}
@@ -48,7 +50,7 @@ public static void put(@NonNull final String key, final byte[] value) {
* @param value The value of cache.
* @param saveTime The save time of cache, in seconds.
*/
- public static void put(@NonNull final String key, final byte[] value, final int saveTime) {
+ public static void put(@NonNull final String key, @Nullable final byte[] value, final int saveTime) {
put(key, value, saveTime, getDefaultCacheDiskUtils());
}
@@ -69,7 +71,7 @@ public static byte[] getBytes(@NonNull final String key) {
* @param defaultValue The default value if the cache doesn't exist.
* @return the bytes if cache exists or defaultValue otherwise
*/
- public static byte[] getBytes(@NonNull final String key, final byte[] defaultValue) {
+ public static byte[] getBytes(@NonNull final String key, @Nullable final byte[] defaultValue) {
return getBytes(key, defaultValue, getDefaultCacheDiskUtils());
}
@@ -83,7 +85,7 @@ public static byte[] getBytes(@NonNull final String key, final byte[] defaultVal
* @param key The key of cache.
* @param value The value of cache.
*/
- public static void put(@NonNull final String key, final String value) {
+ public static void put(@NonNull final String key, @Nullable final String value) {
put(key, value, getDefaultCacheDiskUtils());
}
@@ -94,7 +96,7 @@ public static void put(@NonNull final String key, final String value) {
* @param value The value of cache.
* @param saveTime The save time of cache, in seconds.
*/
- public static void put(@NonNull final String key, final String value, final int saveTime) {
+ public static void put(@NonNull final String key, @Nullable final String value, final int saveTime) {
put(key, value, saveTime, getDefaultCacheDiskUtils());
}
@@ -115,7 +117,7 @@ public static String getString(@NonNull final String key) {
* @param defaultValue The default value if the cache doesn't exist.
* @return the string value if cache exists or defaultValue otherwise
*/
- public static String getString(@NonNull final String key, final String defaultValue) {
+ public static String getString(@NonNull final String key, @Nullable final String defaultValue) {
return getString(key, defaultValue, getDefaultCacheDiskUtils());
}
@@ -129,7 +131,7 @@ public static String getString(@NonNull final String key, final String defaultVa
* @param key The key of cache.
* @param value The value of cache.
*/
- public static void put(@NonNull final String key, final JSONObject value) {
+ public static void put(@NonNull final String key, @Nullable final JSONObject value) {
put(key, value, getDefaultCacheDiskUtils());
}
@@ -141,7 +143,7 @@ public static void put(@NonNull final String key, final JSONObject value) {
* @param saveTime The save time of cache, in seconds.
*/
public static void put(@NonNull final String key,
- final JSONObject value,
+ @Nullable final JSONObject value,
final int saveTime) {
put(key, value, saveTime, getDefaultCacheDiskUtils());
}
@@ -163,7 +165,7 @@ public static JSONObject getJSONObject(@NonNull final String key) {
* @param defaultValue The default value if the cache doesn't exist.
* @return the JSONObject if cache exists or defaultValue otherwise
*/
- public static JSONObject getJSONObject(@NonNull final String key, final JSONObject defaultValue) {
+ public static JSONObject getJSONObject(@NonNull final String key, @Nullable final JSONObject defaultValue) {
return getJSONObject(key, defaultValue, getDefaultCacheDiskUtils());
}
@@ -178,7 +180,7 @@ public static JSONObject getJSONObject(@NonNull final String key, final JSONObje
* @param key The key of cache.
* @param value The value of cache.
*/
- public static void put(@NonNull final String key, final JSONArray value) {
+ public static void put(@NonNull final String key, @Nullable final JSONArray value) {
put(key, value, getDefaultCacheDiskUtils());
}
@@ -189,7 +191,7 @@ public static void put(@NonNull final String key, final JSONArray value) {
* @param value The value of cache.
* @param saveTime The save time of cache, in seconds.
*/
- public static void put(@NonNull final String key, final JSONArray value, final int saveTime) {
+ public static void put(@NonNull final String key, @Nullable final JSONArray value, final int saveTime) {
put(key, value, saveTime, getDefaultCacheDiskUtils());
}
@@ -210,7 +212,7 @@ public static JSONArray getJSONArray(@NonNull final String key) {
* @param defaultValue The default value if the cache doesn't exist.
* @return the JSONArray if cache exists or defaultValue otherwise
*/
- public static JSONArray getJSONArray(@NonNull final String key, final JSONArray defaultValue) {
+ public static JSONArray getJSONArray(@NonNull final String key, @Nullable final JSONArray defaultValue) {
return getJSONArray(key, defaultValue, getDefaultCacheDiskUtils());
}
@@ -225,7 +227,7 @@ public static JSONArray getJSONArray(@NonNull final String key, final JSONArray
* @param key The key of cache.
* @param value The value of cache.
*/
- public static void put(@NonNull final String key, final Bitmap value) {
+ public static void put(@NonNull final String key, @Nullable final Bitmap value) {
put(key, value, getDefaultCacheDiskUtils());
}
@@ -236,7 +238,7 @@ public static void put(@NonNull final String key, final Bitmap value) {
* @param value The value of cache.
* @param saveTime The save time of cache, in seconds.
*/
- public static void put(@NonNull final String key, final Bitmap value, final int saveTime) {
+ public static void put(@NonNull final String key, @Nullable final Bitmap value, final int saveTime) {
put(key, value, saveTime, getDefaultCacheDiskUtils());
}
@@ -257,7 +259,7 @@ public static Bitmap getBitmap(@NonNull final String key) {
* @param defaultValue The default value if the cache doesn't exist.
* @return the bitmap if cache exists or defaultValue otherwise
*/
- public static Bitmap getBitmap(@NonNull final String key, final Bitmap defaultValue) {
+ public static Bitmap getBitmap(@NonNull final String key, @Nullable final Bitmap defaultValue) {
return getBitmap(key, defaultValue, getDefaultCacheDiskUtils());
}
@@ -271,7 +273,7 @@ public static Bitmap getBitmap(@NonNull final String key, final Bitmap defaultVa
* @param key The key of cache.
* @param value The value of cache.
*/
- public static void put(@NonNull final String key, final Drawable value) {
+ public static void put(@NonNull final String key, @Nullable final Drawable value) {
put(key, value, getDefaultCacheDiskUtils());
}
@@ -282,7 +284,7 @@ public static void put(@NonNull final String key, final Drawable value) {
* @param value The value of cache.
* @param saveTime The save time of cache, in seconds.
*/
- public static void put(@NonNull final String key, final Drawable value, final int saveTime) {
+ public static void put(@NonNull final String key, @Nullable final Drawable value, final int saveTime) {
put(key, value, saveTime, getDefaultCacheDiskUtils());
}
@@ -303,7 +305,7 @@ public static Drawable getDrawable(@NonNull final String key) {
* @param defaultValue The default value if the cache doesn't exist.
* @return the drawable if cache exists or defaultValue otherwise
*/
- public static Drawable getDrawable(@NonNull final String key, final Drawable defaultValue) {
+ public static Drawable getDrawable(@NonNull final String key, final @Nullable Drawable defaultValue) {
return getDrawable(key, defaultValue, getDefaultCacheDiskUtils());
}
@@ -317,7 +319,7 @@ public static Drawable getDrawable(@NonNull final String key, final Drawable def
* @param key The key of cache.
* @param value The value of cache.
*/
- public static void put(@NonNull final String key, final Parcelable value) {
+ public static void put(@NonNull final String key, @Nullable final Parcelable value) {
put(key, value, getDefaultCacheDiskUtils());
}
@@ -328,7 +330,7 @@ public static void put(@NonNull final String key, final Parcelable value) {
* @param value The value of cache.
* @param saveTime The save time of cache, in seconds.
*/
- public static void put(@NonNull final String key, final Parcelable value, final int saveTime) {
+ public static void put(@NonNull final String key, @Nullable final Parcelable value, final int saveTime) {
put(key, value, saveTime, getDefaultCacheDiskUtils());
}
@@ -356,7 +358,7 @@ public static T getParcelable(@NonNull final String key,
*/
public static T getParcelable(@NonNull final String key,
@NonNull final Parcelable.Creator creator,
- final T defaultValue) {
+ @Nullable final T defaultValue) {
return getParcelable(key, creator, defaultValue, getDefaultCacheDiskUtils());
}
@@ -370,7 +372,7 @@ public static T getParcelable(@NonNull final String key,
* @param key The key of cache.
* @param value The value of cache.
*/
- public static void put(@NonNull final String key, final Serializable value) {
+ public static void put(@NonNull final String key, @Nullable final Serializable value) {
put(key, value, getDefaultCacheDiskUtils());
}
@@ -381,7 +383,7 @@ public static void put(@NonNull final String key, final Serializable value) {
* @param value The value of cache.
* @param saveTime The save time of cache, in seconds.
*/
- public static void put(@NonNull final String key, final Serializable value, final int saveTime) {
+ public static void put(@NonNull final String key, @Nullable final Serializable value, final int saveTime) {
put(key, value, saveTime, getDefaultCacheDiskUtils());
}
@@ -402,7 +404,7 @@ public static Object getSerializable(@NonNull final String key) {
* @param defaultValue The default value if the cache doesn't exist.
* @return the bitmap if cache exists or defaultValue otherwise
*/
- public static Object getSerializable(@NonNull final String key, final Object defaultValue) {
+ public static Object getSerializable(@NonNull final String key, @Nullable final Object defaultValue) {
return getSerializable(key, defaultValue, getDefaultCacheDiskUtils());
}
@@ -455,7 +457,7 @@ public static boolean clear() {
* @param cacheDiskUtils The instance of {@link CacheDiskUtils}.
*/
public static void put(@NonNull final String key,
- final byte[] value,
+ @Nullable final byte[] value,
@NonNull final CacheDiskUtils cacheDiskUtils) {
cacheDiskUtils.put(key, value);
}
@@ -469,7 +471,7 @@ public static void put(@NonNull final String key,
* @param cacheDiskUtils The instance of {@link CacheDiskUtils}.
*/
public static void put(@NonNull final String key,
- final byte[] value,
+ @Nullable final byte[] value,
final int saveTime,
@NonNull final CacheDiskUtils cacheDiskUtils) {
cacheDiskUtils.put(key, value, saveTime);
@@ -495,7 +497,7 @@ public static byte[] getBytes(@NonNull final String key, @NonNull final CacheDis
* @return the bytes if cache exists or defaultValue otherwise
*/
public static byte[] getBytes(@NonNull final String key,
- final byte[] defaultValue,
+ @Nullable final byte[] defaultValue,
@NonNull final CacheDiskUtils cacheDiskUtils) {
return cacheDiskUtils.getBytes(key, defaultValue);
}
@@ -512,7 +514,7 @@ public static byte[] getBytes(@NonNull final String key,
* @param cacheDiskUtils The instance of {@link CacheDiskUtils}.
*/
public static void put(@NonNull final String key,
- final String value,
+ @Nullable final String value,
@NonNull final CacheDiskUtils cacheDiskUtils) {
cacheDiskUtils.put(key, value);
}
@@ -526,7 +528,7 @@ public static void put(@NonNull final String key,
* @param cacheDiskUtils The instance of {@link CacheDiskUtils}.
*/
public static void put(@NonNull final String key,
- final String value,
+ @Nullable final String value,
final int saveTime,
@NonNull final CacheDiskUtils cacheDiskUtils) {
cacheDiskUtils.put(key, value, saveTime);
@@ -552,7 +554,7 @@ public static String getString(@NonNull final String key, @NonNull final CacheDi
* @return the string value if cache exists or defaultValue otherwise
*/
public static String getString(@NonNull final String key,
- final String defaultValue,
+ @Nullable final String defaultValue,
@NonNull final CacheDiskUtils cacheDiskUtils) {
return cacheDiskUtils.getString(key, defaultValue);
}
@@ -569,7 +571,7 @@ public static String getString(@NonNull final String key,
* @param cacheDiskUtils The instance of {@link CacheDiskUtils}.
*/
public static void put(@NonNull final String key,
- final JSONObject value,
+ @Nullable final JSONObject value,
@NonNull final CacheDiskUtils cacheDiskUtils) {
cacheDiskUtils.put(key, value);
}
@@ -583,7 +585,7 @@ public static void put(@NonNull final String key,
* @param cacheDiskUtils The instance of {@link CacheDiskUtils}.
*/
public static void put(@NonNull final String key,
- final JSONObject value,
+ @Nullable final JSONObject value,
final int saveTime,
@NonNull final CacheDiskUtils cacheDiskUtils) {
cacheDiskUtils.put(key, value, saveTime);
@@ -609,7 +611,7 @@ public static JSONObject getJSONObject(@NonNull final String key, @NonNull final
* @return the JSONObject if cache exists or defaultValue otherwise
*/
public static JSONObject getJSONObject(@NonNull final String key,
- final JSONObject defaultValue,
+ @Nullable final JSONObject defaultValue,
@NonNull final CacheDiskUtils cacheDiskUtils) {
return cacheDiskUtils.getJSONObject(key, defaultValue);
}
@@ -627,7 +629,7 @@ public static JSONObject getJSONObject(@NonNull final String key,
* @param cacheDiskUtils The instance of {@link CacheDiskUtils}.
*/
public static void put(@NonNull final String key,
- final JSONArray value,
+ @Nullable final JSONArray value,
@NonNull final CacheDiskUtils cacheDiskUtils) {
cacheDiskUtils.put(key, value);
}
@@ -641,7 +643,7 @@ public static void put(@NonNull final String key,
* @param cacheDiskUtils The instance of {@link CacheDiskUtils}.
*/
public static void put(@NonNull final String key,
- final JSONArray value,
+ @Nullable final JSONArray value,
final int saveTime,
@NonNull final CacheDiskUtils cacheDiskUtils) {
cacheDiskUtils.put(key, value, saveTime);
@@ -667,7 +669,7 @@ public static JSONArray getJSONArray(@NonNull final String key, @NonNull final C
* @return the JSONArray if cache exists or defaultValue otherwise
*/
public static JSONArray getJSONArray(@NonNull final String key,
- final JSONArray defaultValue,
+ @Nullable final JSONArray defaultValue,
@NonNull final CacheDiskUtils cacheDiskUtils) {
return cacheDiskUtils.getJSONArray(key, defaultValue);
}
@@ -685,7 +687,7 @@ public static JSONArray getJSONArray(@NonNull final String key,
* @param cacheDiskUtils The instance of {@link CacheDiskUtils}.
*/
public static void put(@NonNull final String key,
- final Bitmap value,
+ @Nullable final Bitmap value,
@NonNull final CacheDiskUtils cacheDiskUtils) {
cacheDiskUtils.put(key, value);
}
@@ -699,7 +701,7 @@ public static void put(@NonNull final String key,
* @param cacheDiskUtils The instance of {@link CacheDiskUtils}.
*/
public static void put(@NonNull final String key,
- final Bitmap value,
+ @Nullable final Bitmap value,
final int saveTime,
@NonNull final CacheDiskUtils cacheDiskUtils) {
cacheDiskUtils.put(key, value, saveTime);
@@ -725,7 +727,7 @@ public static Bitmap getBitmap(@NonNull final String key, @NonNull final CacheDi
* @return the bitmap if cache exists or defaultValue otherwise
*/
public static Bitmap getBitmap(@NonNull final String key,
- final Bitmap defaultValue,
+ @Nullable final Bitmap defaultValue,
@NonNull final CacheDiskUtils cacheDiskUtils) {
return cacheDiskUtils.getBitmap(key, defaultValue);
}
@@ -742,7 +744,7 @@ public static Bitmap getBitmap(@NonNull final String key,
* @param cacheDiskUtils The instance of {@link CacheDiskUtils}.
*/
public static void put(@NonNull final String key,
- final Drawable value,
+ @Nullable final Drawable value,
@NonNull final CacheDiskUtils cacheDiskUtils) {
cacheDiskUtils.put(key, value);
}
@@ -756,7 +758,7 @@ public static void put(@NonNull final String key,
* @param cacheDiskUtils The instance of {@link CacheDiskUtils}.
*/
public static void put(@NonNull final String key,
- final Drawable value,
+ @Nullable final Drawable value,
final int saveTime,
@NonNull final CacheDiskUtils cacheDiskUtils) {
cacheDiskUtils.put(key, value, saveTime);
@@ -782,7 +784,7 @@ public static Drawable getDrawable(@NonNull final String key, @NonNull final Cac
* @return the drawable if cache exists or defaultValue otherwise
*/
public static Drawable getDrawable(@NonNull final String key,
- final Drawable defaultValue,
+ @Nullable final Drawable defaultValue,
@NonNull final CacheDiskUtils cacheDiskUtils) {
return cacheDiskUtils.getDrawable(key, defaultValue);
}
@@ -799,7 +801,7 @@ public static Drawable getDrawable(@NonNull final String key,
* @param cacheDiskUtils The instance of {@link CacheDiskUtils}.
*/
public static void put(@NonNull final String key,
- final Parcelable value,
+ @Nullable final Parcelable value,
@NonNull final CacheDiskUtils cacheDiskUtils) {
cacheDiskUtils.put(key, value);
}
@@ -813,7 +815,7 @@ public static void put(@NonNull final String key,
* @param cacheDiskUtils The instance of {@link CacheDiskUtils}.
*/
public static void put(@NonNull final String key,
- final Parcelable value,
+ @Nullable final Parcelable value,
final int saveTime,
@NonNull final CacheDiskUtils cacheDiskUtils) {
cacheDiskUtils.put(key, value, saveTime);
@@ -846,7 +848,7 @@ public static T getParcelable(@NonNull final String key,
*/
public static T getParcelable(@NonNull final String key,
@NonNull final Parcelable.Creator creator,
- final T defaultValue,
+ @Nullable final T defaultValue,
@NonNull final CacheDiskUtils cacheDiskUtils) {
return cacheDiskUtils.getParcelable(key, creator, defaultValue);
}
@@ -863,7 +865,7 @@ public static T getParcelable(@NonNull final String key,
* @param cacheDiskUtils The instance of {@link CacheDiskUtils}.
*/
public static void put(@NonNull final String key,
- final Serializable value,
+ @Nullable final Serializable value,
@NonNull final CacheDiskUtils cacheDiskUtils) {
cacheDiskUtils.put(key, value);
}
@@ -877,7 +879,7 @@ public static void put(@NonNull final String key,
* @param cacheDiskUtils The instance of {@link CacheDiskUtils}.
*/
public static void put(@NonNull final String key,
- final Serializable value,
+ @Nullable final Serializable value,
final int saveTime,
@NonNull final CacheDiskUtils cacheDiskUtils) {
cacheDiskUtils.put(key, value, saveTime);
@@ -903,7 +905,7 @@ public static Object getSerializable(@NonNull final String key, @NonNull final C
* @return the bitmap if cache exists or defaultValue otherwise
*/
public static Object getSerializable(@NonNull final String key,
- final Object defaultValue,
+ @Nullable final Object defaultValue,
@NonNull final CacheDiskUtils cacheDiskUtils) {
return cacheDiskUtils.getSerializable(key, defaultValue);
}
@@ -949,6 +951,7 @@ public static boolean clear(@NonNull final CacheDiskUtils cacheDiskUtils) {
return cacheDiskUtils.clear();
}
+ @NonNull
private static CacheDiskUtils getDefaultCacheDiskUtils() {
return sDefaultCacheDiskUtils != null ? sDefaultCacheDiskUtils : CacheDiskUtils.getInstance();
}
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/CacheDiskUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/CacheDiskUtils.java
index 67e6b3fb0e..773e550a16 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/CacheDiskUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/CacheDiskUtils.java
@@ -1,34 +1,20 @@
package com.blankj.utilcode.util;
import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.PixelFormat;
-import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
-import android.os.Parcel;
import android.os.Parcelable;
-import android.support.annotation.NonNull;
import android.util.Log;
+import androidx.annotation.NonNull;
+
import com.blankj.utilcode.constant.CacheConstants;
import org.json.JSONArray;
import org.json.JSONObject;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
import java.io.File;
-import java.io.FileOutputStream;
import java.io.FilenameFilter;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.RandomAccessFile;
import java.io.Serializable;
-import java.nio.ByteBuffer;
-import java.nio.MappedByteBuffer;
-import java.nio.channels.FileChannel;
import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
@@ -114,7 +100,7 @@ public static CacheDiskUtils getInstance(final long maxSize, final int maxCount)
* @return the single {@link CacheDiskUtils} instance
*/
public static CacheDiskUtils getInstance(String cacheName, final long maxSize, final int maxCount) {
- if (isSpace(cacheName)) cacheName = "cacheUtils";
+ if (UtilsBridge.isSpace(cacheName)) cacheName = "cacheUtils";
File file = new File(Utils.getApp().getCacheDir(), cacheName);
return getInstance(file, maxSize, maxCount);
}
@@ -217,7 +203,7 @@ private void realPutBytes(final String key, byte[] value, int saveTime) {
if (diskCacheManager == null) return;
if (saveTime >= 0) value = DiskCacheHelper.newByteArrayWithTime(saveTime, value);
File file = diskCacheManager.getFileBeforePut(key);
- writeFileFromBytes(file, value);
+ UtilsBridge.writeFileFromBytes(file, value);
diskCacheManager.updateModify(file);
diskCacheManager.put(file);
}
@@ -253,7 +239,7 @@ private byte[] realGetBytes(@NonNull final String key, final byte[] defaultValue
if (diskCacheManager == null) return defaultValue;
final File file = diskCacheManager.getFileIfExists(key);
if (file == null) return defaultValue;
- byte[] data = readFile2Bytes(file);
+ byte[] data = UtilsBridge.readFile2Bytes(file);
if (DiskCacheHelper.isDue(data)) {
diskCacheManager.removeByKey(key);
return defaultValue;
@@ -284,7 +270,7 @@ public void put(@NonNull final String key, final String value) {
* @param saveTime The save time of cache, in seconds.
*/
public void put(@NonNull final String key, final String value, final int saveTime) {
- realPutBytes(TYPE_STRING + key, string2Bytes(value), saveTime);
+ realPutBytes(TYPE_STRING + key, UtilsBridge.string2Bytes(value), saveTime);
}
/**
@@ -307,7 +293,7 @@ public String getString(@NonNull final String key) {
public String getString(@NonNull final String key, final String defaultValue) {
byte[] bytes = realGetBytes(TYPE_STRING + key);
if (bytes == null) return defaultValue;
- return bytes2String(bytes);
+ return UtilsBridge.bytes2String(bytes);
}
///////////////////////////////////////////////////////////////////////////
@@ -334,7 +320,7 @@ public void put(@NonNull final String key, final JSONObject value) {
public void put(@NonNull final String key,
final JSONObject value,
final int saveTime) {
- realPutBytes(TYPE_JSON_OBJECT + key, jsonObject2Bytes(value), saveTime);
+ realPutBytes(TYPE_JSON_OBJECT + key, UtilsBridge.jsonObject2Bytes(value), saveTime);
}
/**
@@ -357,7 +343,7 @@ public JSONObject getJSONObject(@NonNull final String key) {
public JSONObject getJSONObject(@NonNull final String key, final JSONObject defaultValue) {
byte[] bytes = realGetBytes(TYPE_JSON_OBJECT + key);
if (bytes == null) return defaultValue;
- return bytes2JSONObject(bytes);
+ return UtilsBridge.bytes2JSONObject(bytes);
}
@@ -383,7 +369,7 @@ public void put(@NonNull final String key, final JSONArray value) {
* @param saveTime The save time of cache, in seconds.
*/
public void put(@NonNull final String key, final JSONArray value, final int saveTime) {
- realPutBytes(TYPE_JSON_ARRAY + key, jsonArray2Bytes(value), saveTime);
+ realPutBytes(TYPE_JSON_ARRAY + key, UtilsBridge.jsonArray2Bytes(value), saveTime);
}
/**
@@ -406,7 +392,7 @@ public JSONArray getJSONArray(@NonNull final String key) {
public JSONArray getJSONArray(@NonNull final String key, final JSONArray defaultValue) {
byte[] bytes = realGetBytes(TYPE_JSON_ARRAY + key);
if (bytes == null) return defaultValue;
- return bytes2JSONArray(bytes);
+ return UtilsBridge.bytes2JSONArray(bytes);
}
@@ -432,7 +418,7 @@ public void put(@NonNull final String key, final Bitmap value) {
* @param saveTime The save time of cache, in seconds.
*/
public void put(@NonNull final String key, final Bitmap value, final int saveTime) {
- realPutBytes(TYPE_BITMAP + key, bitmap2Bytes(value), saveTime);
+ realPutBytes(TYPE_BITMAP + key, UtilsBridge.bitmap2Bytes(value), saveTime);
}
/**
@@ -455,7 +441,7 @@ public Bitmap getBitmap(@NonNull final String key) {
public Bitmap getBitmap(@NonNull final String key, final Bitmap defaultValue) {
byte[] bytes = realGetBytes(TYPE_BITMAP + key);
if (bytes == null) return defaultValue;
- return bytes2Bitmap(bytes);
+ return UtilsBridge.bytes2Bitmap(bytes);
}
///////////////////////////////////////////////////////////////////////////
@@ -480,7 +466,7 @@ public void put(@NonNull final String key, final Drawable value) {
* @param saveTime The save time of cache, in seconds.
*/
public void put(@NonNull final String key, final Drawable value, final int saveTime) {
- realPutBytes(TYPE_DRAWABLE + key, drawable2Bytes(value), saveTime);
+ realPutBytes(TYPE_DRAWABLE + key, UtilsBridge.drawable2Bytes(value), saveTime);
}
/**
@@ -503,7 +489,7 @@ public Drawable getDrawable(@NonNull final String key) {
public Drawable getDrawable(@NonNull final String key, final Drawable defaultValue) {
byte[] bytes = realGetBytes(TYPE_DRAWABLE + key);
if (bytes == null) return defaultValue;
- return bytes2Drawable(bytes);
+ return UtilsBridge.bytes2Drawable(bytes);
}
///////////////////////////////////////////////////////////////////////////
@@ -528,7 +514,7 @@ public void put(@NonNull final String key, final Parcelable value) {
* @param saveTime The save time of cache, in seconds.
*/
public void put(@NonNull final String key, final Parcelable value, final int saveTime) {
- realPutBytes(TYPE_PARCELABLE + key, parcelable2Bytes(value), saveTime);
+ realPutBytes(TYPE_PARCELABLE + key, UtilsBridge.parcelable2Bytes(value), saveTime);
}
/**
@@ -558,7 +544,7 @@ public T getParcelable(@NonNull final String key,
final T defaultValue) {
byte[] bytes = realGetBytes(TYPE_PARCELABLE + key);
if (bytes == null) return defaultValue;
- return bytes2Parcelable(bytes, creator);
+ return UtilsBridge.bytes2Parcelable(bytes, creator);
}
///////////////////////////////////////////////////////////////////////////
@@ -583,7 +569,7 @@ public void put(@NonNull final String key, final Serializable value) {
* @param saveTime The save time of cache, in seconds.
*/
public void put(@NonNull final String key, final Serializable value, final int saveTime) {
- realPutBytes(TYPE_SERIALIZABLE + key, serializable2Bytes(value), saveTime);
+ realPutBytes(TYPE_SERIALIZABLE + key, UtilsBridge.serializable2Bytes(value), saveTime);
}
/**
@@ -606,7 +592,7 @@ public Object getSerializable(@NonNull final String key) {
public Object getSerializable(@NonNull final String key, final Object defaultValue) {
byte[] bytes = realGetBytes(TYPE_SERIALIZABLE + key);
if (bytes == null) return defaultValue;
- return bytes2Object(bytes);
+ return UtilsBridge.bytes2Object(bytes);
}
/**
@@ -886,221 +872,4 @@ private static boolean hasTimeInfo(final byte[] data) {
&& data[13] == '_';
}
}
-
- ///////////////////////////////////////////////////////////////////////////
- // other utils methods
- ///////////////////////////////////////////////////////////////////////////
-
- private static byte[] string2Bytes(final String string) {
- if (string == null) return null;
- return string.getBytes();
- }
-
- private static String bytes2String(final byte[] bytes) {
- if (bytes == null) return null;
- return new String(bytes);
- }
-
- private static byte[] jsonObject2Bytes(final JSONObject jsonObject) {
- if (jsonObject == null) return null;
- return jsonObject.toString().getBytes();
- }
-
- private static JSONObject bytes2JSONObject(final byte[] bytes) {
- if (bytes == null) return null;
- try {
- return new JSONObject(new String(bytes));
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- }
-
- private static byte[] jsonArray2Bytes(final JSONArray jsonArray) {
- if (jsonArray == null) return null;
- return jsonArray.toString().getBytes();
- }
-
- private static JSONArray bytes2JSONArray(final byte[] bytes) {
- if (bytes == null) return null;
- try {
- return new JSONArray(new String(bytes));
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- }
-
- private static byte[] parcelable2Bytes(final Parcelable parcelable) {
- if (parcelable == null) return null;
- Parcel parcel = Parcel.obtain();
- parcelable.writeToParcel(parcel, 0);
- byte[] bytes = parcel.marshall();
- parcel.recycle();
- return bytes;
- }
-
- private static T bytes2Parcelable(final byte[] bytes,
- final Parcelable.Creator creator) {
- if (bytes == null) return null;
- Parcel parcel = Parcel.obtain();
- parcel.unmarshall(bytes, 0, bytes.length);
- parcel.setDataPosition(0);
- T result = creator.createFromParcel(parcel);
- parcel.recycle();
- return result;
- }
-
- private static byte[] serializable2Bytes(final Serializable serializable) {
- if (serializable == null) return null;
- ByteArrayOutputStream baos;
- ObjectOutputStream oos = null;
- try {
- oos = new ObjectOutputStream(baos = new ByteArrayOutputStream());
- oos.writeObject(serializable);
- return baos.toByteArray();
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- } finally {
- try {
- if (oos != null) {
- oos.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
-
- private static Object bytes2Object(final byte[] bytes) {
- if (bytes == null) return null;
- ObjectInputStream ois = null;
- try {
- ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
- return ois.readObject();
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- } finally {
- try {
- if (ois != null) {
- ois.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
-
- private static byte[] bitmap2Bytes(final Bitmap bitmap) {
- if (bitmap == null) return null;
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
- return baos.toByteArray();
- }
-
- private static Bitmap bytes2Bitmap(final byte[] bytes) {
- return (bytes == null || bytes.length <= 0)
- ? null
- : BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
- }
-
- private static byte[] drawable2Bytes(final Drawable drawable) {
- return drawable == null ? null : bitmap2Bytes(drawable2Bitmap(drawable));
- }
-
- private static Drawable bytes2Drawable(final byte[] bytes) {
- return bytes == null ? null : bitmap2Drawable(bytes2Bitmap(bytes));
- }
-
- private static Bitmap drawable2Bitmap(final Drawable drawable) {
- if (drawable instanceof BitmapDrawable) {
- BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
- if (bitmapDrawable.getBitmap() != null) {
- return bitmapDrawable.getBitmap();
- }
- }
- Bitmap bitmap;
- if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
- bitmap = Bitmap.createBitmap(
- 1,
- 1,
- drawable.getOpacity() != PixelFormat.OPAQUE
- ? Bitmap.Config.ARGB_8888
- : Bitmap.Config.RGB_565
- );
- } else {
- bitmap = Bitmap.createBitmap(
- drawable.getIntrinsicWidth(),
- drawable.getIntrinsicHeight(),
- drawable.getOpacity() != PixelFormat.OPAQUE
- ? Bitmap.Config.ARGB_8888
- : Bitmap.Config.RGB_565
- );
- }
- Canvas canvas = new Canvas(bitmap);
- drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
- drawable.draw(canvas);
- return bitmap;
- }
-
- private static Drawable bitmap2Drawable(final Bitmap bitmap) {
- return bitmap == null
- ? null
- : new BitmapDrawable(Utils.getApp().getResources(), bitmap);
- }
-
-
- private static void writeFileFromBytes(final File file, final byte[] bytes) {
- FileChannel fc = null;
- try {
- fc = new FileOutputStream(file, false).getChannel();
- fc.write(ByteBuffer.wrap(bytes));
- fc.force(true);
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- try {
- if (fc != null) {
- fc.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
-
- private static byte[] readFile2Bytes(final File file) {
- FileChannel fc = null;
- try {
- fc = new RandomAccessFile(file, "r").getChannel();
- int size = (int) fc.size();
- MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, size).load();
- byte[] data = new byte[size];
- mbb.get(data, 0, size);
- return data;
- } catch (IOException e) {
- e.printStackTrace();
- return null;
- } finally {
- try {
- if (fc != null) {
- fc.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
-
- private static boolean isSpace(final String s) {
- if (s == null) return true;
- for (int i = 0, len = s.length(); i < len; ++i) {
- if (!Character.isWhitespace(s.charAt(i))) {
- return false;
- }
- }
- return true;
- }
}
\ No newline at end of file
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/CacheDoubleStaticUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/CacheDoubleStaticUtils.java
index 2ef267bd01..6dbb9f7475 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/CacheDoubleStaticUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/CacheDoubleStaticUtils.java
@@ -3,13 +3,14 @@
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Parcelable;
-import android.support.annotation.NonNull;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.Serializable;
+import androidx.annotation.NonNull;
+
/**
*
* author: Blankj
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/CacheDoubleUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/CacheDoubleUtils.java
index c800423c78..c39c9ef9d4 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/CacheDoubleUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/CacheDoubleUtils.java
@@ -3,7 +3,7 @@
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Parcelable;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
import com.blankj.utilcode.constant.CacheConstants;
@@ -113,7 +113,12 @@ public byte[] getBytes(@NonNull final String key) {
public byte[] getBytes(@NonNull final String key, final byte[] defaultValue) {
byte[] obj = mCacheMemoryUtils.get(key);
if (obj != null) return obj;
- return mCacheDiskUtils.getBytes(key, defaultValue);
+ byte[] bytes = mCacheDiskUtils.getBytes(key);
+ if (bytes != null) {
+ mCacheMemoryUtils.put(key, bytes);
+ return bytes;
+ }
+ return defaultValue;
}
///////////////////////////////////////////////////////////////////////////
@@ -162,7 +167,12 @@ public String getString(@NonNull final String key) {
public String getString(@NonNull final String key, final String defaultValue) {
String obj = mCacheMemoryUtils.get(key);
if (obj != null) return obj;
- return mCacheDiskUtils.getString(key, defaultValue);
+ String string = mCacheDiskUtils.getString(key);
+ if (string != null) {
+ mCacheMemoryUtils.put(key, string);
+ return string;
+ }
+ return defaultValue;
}
///////////////////////////////////////////////////////////////////////////
@@ -213,7 +223,12 @@ public JSONObject getJSONObject(@NonNull final String key) {
public JSONObject getJSONObject(@NonNull final String key, final JSONObject defaultValue) {
JSONObject obj = mCacheMemoryUtils.get(key);
if (obj != null) return obj;
- return mCacheDiskUtils.getJSONObject(key, defaultValue);
+ JSONObject jsonObject = mCacheDiskUtils.getJSONObject(key);
+ if (jsonObject != null) {
+ mCacheMemoryUtils.put(key, jsonObject);
+ return jsonObject;
+ }
+ return defaultValue;
}
@@ -263,7 +278,12 @@ public JSONArray getJSONArray(@NonNull final String key) {
public JSONArray getJSONArray(@NonNull final String key, final JSONArray defaultValue) {
JSONArray obj = mCacheMemoryUtils.get(key);
if (obj != null) return obj;
- return mCacheDiskUtils.getJSONArray(key, defaultValue);
+ JSONArray jsonArray = mCacheDiskUtils.getJSONArray(key);
+ if (jsonArray != null) {
+ mCacheMemoryUtils.put(key, jsonArray);
+ return jsonArray;
+ }
+ return defaultValue;
}
///////////////////////////////////////////////////////////////////////////
@@ -312,7 +332,12 @@ public Bitmap getBitmap(@NonNull final String key) {
public Bitmap getBitmap(@NonNull final String key, final Bitmap defaultValue) {
Bitmap obj = mCacheMemoryUtils.get(key);
if (obj != null) return obj;
- return mCacheDiskUtils.getBitmap(key, defaultValue);
+ Bitmap bitmap = mCacheDiskUtils.getBitmap(key);
+ if (bitmap != null) {
+ mCacheMemoryUtils.put(key, bitmap);
+ return bitmap;
+ }
+ return defaultValue;
}
///////////////////////////////////////////////////////////////////////////
@@ -361,7 +386,12 @@ public Drawable getDrawable(@NonNull final String key) {
public Drawable getDrawable(@NonNull final String key, final Drawable defaultValue) {
Drawable obj = mCacheMemoryUtils.get(key);
if (obj != null) return obj;
- return mCacheDiskUtils.getDrawable(key, defaultValue);
+ Drawable drawable = mCacheDiskUtils.getDrawable(key);
+ if (drawable != null) {
+ mCacheMemoryUtils.put(key, drawable);
+ return drawable;
+ }
+ return defaultValue;
}
///////////////////////////////////////////////////////////////////////////
@@ -417,7 +447,12 @@ public T getParcelable(@NonNull final String key,
final T defaultValue) {
T value = mCacheMemoryUtils.get(key);
if (value != null) return value;
- return mCacheDiskUtils.getParcelable(key, creator, defaultValue);
+ T val = mCacheDiskUtils.getParcelable(key, creator);
+ if (val != null) {
+ mCacheMemoryUtils.put(key, val);
+ return val;
+ }
+ return defaultValue;
}
///////////////////////////////////////////////////////////////////////////
@@ -466,7 +501,12 @@ public Object getSerializable(@NonNull final String key) {
public Object getSerializable(@NonNull final String key, final Object defaultValue) {
Object obj = mCacheMemoryUtils.get(key);
if (obj != null) return obj;
- return mCacheDiskUtils.getSerializable(key, defaultValue);
+ Object serializable = mCacheDiskUtils.getSerializable(key);
+ if (serializable != null) {
+ mCacheMemoryUtils.put(key, serializable);
+ return serializable;
+ }
+ return defaultValue;
}
/**
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/CacheMemoryStaticUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/CacheMemoryStaticUtils.java
index 56abfba117..aedcfa7fc4 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/CacheMemoryStaticUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/CacheMemoryStaticUtils.java
@@ -1,6 +1,6 @@
package com.blankj.utilcode.util;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
/**
*
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/CacheMemoryUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/CacheMemoryUtils.java
index d0e06e394d..ddaa2baed9 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/CacheMemoryUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/CacheMemoryUtils.java
@@ -1,7 +1,7 @@
package com.blankj.utilcode.util;
-import android.support.annotation.NonNull;
-import android.support.v4.util.LruCache;
+import androidx.annotation.NonNull;
+import androidx.collection.LruCache;
import com.blankj.utilcode.constant.CacheConstants;
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/CleanUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/CleanUtils.java
index 2af0f22310..7db3edbd6a 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/CleanUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/CleanUtils.java
@@ -1,9 +1,14 @@
package com.blankj.utilcode.util;
+import android.app.ActivityManager;
+import android.content.Context;
+import android.os.Build;
import android.os.Environment;
import java.io.File;
+import androidx.annotation.RequiresApi;
+
/**
*
* author: Blankj
@@ -25,7 +30,7 @@ private CleanUtils() {
* @return {@code true}: success
{@code false}: fail
*/
public static boolean cleanInternalCache() {
- return deleteFilesInDir(Utils.getApp().getCacheDir());
+ return UtilsBridge.deleteAllInDir(Utils.getApp().getCacheDir());
}
/**
@@ -35,7 +40,7 @@ public static boolean cleanInternalCache() {
* @return {@code true}: success
{@code false}: fail
*/
public static boolean cleanInternalFiles() {
- return deleteFilesInDir(Utils.getApp().getFilesDir());
+ return UtilsBridge.deleteAllInDir(Utils.getApp().getFilesDir());
}
/**
@@ -45,7 +50,7 @@ public static boolean cleanInternalFiles() {
* @return {@code true}: success
{@code false}: fail
*/
public static boolean cleanInternalDbs() {
- return deleteFilesInDir(new File(Utils.getApp().getFilesDir().getParent(), "databases"));
+ return UtilsBridge.deleteAllInDir(new File(Utils.getApp().getFilesDir().getParent(), "databases"));
}
/**
@@ -66,7 +71,7 @@ public static boolean cleanInternalDbByName(final String dbName) {
* @return {@code true}: success
{@code false}: fail
*/
public static boolean cleanInternalSp() {
- return deleteFilesInDir(new File(Utils.getApp().getFilesDir().getParent(), "shared_prefs"));
+ return UtilsBridge.deleteAllInDir(new File(Utils.getApp().getFilesDir().getParent(), "shared_prefs"));
}
/**
@@ -77,7 +82,7 @@ public static boolean cleanInternalSp() {
*/
public static boolean cleanExternalCache() {
return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
- && deleteFilesInDir(Utils.getApp().getExternalCacheDir());
+ && UtilsBridge.deleteAllInDir(Utils.getApp().getExternalCacheDir());
}
/**
@@ -87,76 +92,13 @@ public static boolean cleanExternalCache() {
* @return {@code true}: success
{@code false}: fail
*/
public static boolean cleanCustomDir(final String dirPath) {
- return deleteFilesInDir(dirPath);
- }
-
- /**
- * Clean the custom directory.
- *
- * @param dir The directory.
- * @return {@code true}: success
{@code false}: fail
- */
- public static boolean cleanCustomDir(final File dir) {
- return deleteFilesInDir(dir);
- }
-
- public static boolean deleteFilesInDir(final String dirPath) {
- return deleteFilesInDir(getFileByPath(dirPath));
- }
-
- ///////////////////////////////////////////////////////////////////////////
- // other utils methods
- ///////////////////////////////////////////////////////////////////////////
-
- private static boolean deleteFilesInDir(final File dir) {
- if (dir == null) return false;
- // dir doesn't exist then return true
- if (!dir.exists()) return true;
- // dir isn't a directory then return false
- if (!dir.isDirectory()) return false;
- File[] files = dir.listFiles();
- if (files != null && files.length != 0) {
- for (File file : files) {
- if (file.isFile()) {
- if (!file.delete()) return false;
- } else if (file.isDirectory()) {
- if (!deleteDir(file)) return false;
- }
- }
- }
- return true;
- }
-
- private static boolean deleteDir(final File dir) {
- if (dir == null) return false;
- // dir doesn't exist then return true
- if (!dir.exists()) return true;
- // dir isn't a directory then return false
- if (!dir.isDirectory()) return false;
- File[] files = dir.listFiles();
- if (files != null && files.length != 0) {
- for (File file : files) {
- if (file.isFile()) {
- if (!file.delete()) return false;
- } else if (file.isDirectory()) {
- if (!deleteDir(file)) return false;
- }
- }
- }
- return dir.delete();
- }
-
- private static File getFileByPath(final String filePath) {
- return isSpace(filePath) ? null : new File(filePath);
+ return UtilsBridge.deleteAllInDir(UtilsBridge.getFileByPath(dirPath));
}
- private static boolean isSpace(final String s) {
- if (s == null) return true;
- for (int i = 0, len = s.length(); i < len; ++i) {
- if (!Character.isWhitespace(s.charAt(i))) {
- return false;
- }
- }
- return true;
+ @RequiresApi(api = Build.VERSION_CODES.KITKAT)
+ public static void cleanAppUserData() {
+ ActivityManager am = (ActivityManager) Utils.getApp().getSystemService(Context.ACTIVITY_SERVICE);
+ //noinspection ConstantConditions
+ am.clearApplicationUserData();
}
}
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/ClickUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/ClickUtils.java
index 1f0b5b5e9c..8f73792f8f 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/ClickUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/ClickUtils.java
@@ -3,20 +3,27 @@
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.ColorFilter;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
+import android.graphics.Paint;
+import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
import android.os.Build;
-import android.support.annotation.IntRange;
-import android.support.annotation.NonNull;
-import android.support.v4.view.ViewCompat;
+import android.os.SystemClock;
+import android.util.Log;
import android.util.StateSet;
import android.view.MotionEvent;
+import android.view.TouchDelegate;
import android.view.View;
+import androidx.annotation.IntRange;
+import androidx.annotation.NonNull;
+import androidx.core.view.ViewCompat;
+
/**
*
* author: Blankj
@@ -40,8 +47,7 @@ public class ClickUtils {
private static final int PRESSED_BG_DARK_STYLE = 5;
private static final float PRESSED_BG_DARK_DEFAULT_VALUE = 0.9f;
- private static final int DEBOUNCING_TAG = -7;
- private static final long DEBOUNCING_DEFAULT_VALUE = 200;
+ private static final long DEBOUNCING_DEFAULT_VALUE = 1000;
private ClickUtils() {
throw new UnsupportedOperationException("u can't instantiate me...");
@@ -198,7 +204,7 @@ private static Drawable createStyleDrawable(Drawable src, int style, float value
}
Drawable disable = src.getConstantState().newDrawable().mutate();
- disable = createAlphaDrawable(pressed, 0.5f);
+ disable = createAlphaDrawable(disable, 0.5f);
StateListDrawable drawable = new StateListDrawable();
drawable.addState(new int[]{android.R.attr.state_pressed}, pressed);
@@ -208,30 +214,15 @@ private static Drawable createStyleDrawable(Drawable src, int style, float value
}
private static Drawable createAlphaDrawable(Drawable drawable, float alpha) {
- if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT
- && !(drawable instanceof ColorDrawable)) {
- Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
- Canvas myCanvas = new Canvas(bitmap);
- drawable.setAlpha((int) (alpha * 255));
- drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
- drawable.draw(myCanvas);
- return new BitmapDrawable(Resources.getSystem(), bitmap);
- }
- drawable.setAlpha((int) (alpha * 255));
- return drawable;
+ ClickDrawableWrapper drawableWrapper = new ClickDrawableWrapper(drawable);
+ drawableWrapper.setAlpha((int) (alpha * 255));
+ return drawableWrapper;
}
private static Drawable createDarkDrawable(Drawable drawable, float alpha) {
- if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT && !(drawable instanceof ColorDrawable)) {
- Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
- Canvas myCanvas = new Canvas(bitmap);
- drawable.setColorFilter(getDarkColorFilter(alpha));
- drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
- drawable.draw(myCanvas);
- return new BitmapDrawable(Resources.getSystem(), bitmap);
- }
- drawable.setColorFilter(getDarkColorFilter(alpha));
- return drawable;
+ ClickDrawableWrapper drawableWrapper = new ClickDrawableWrapper(drawable);
+ drawableWrapper.setColorFilter(getDarkColorFilter(alpha));
+ return drawableWrapper;
}
private static ColorMatrixColorFilter getDarkColorFilter(float darkAlpha) {
@@ -350,9 +341,82 @@ public void onDebouncingClick(View v) {
}
}
- private static int dp2px(final float dpValue) {
- final float scale = Resources.getSystem().getDisplayMetrics().density;
- return (int) (dpValue * scale + 0.5f);
+ /**
+ * Expand the click area of the view
+ *
+ * @param view The view.
+ * @param expandSize The size.
+ */
+ public static void expandClickArea(@NonNull final View view, final int expandSize) {
+ expandClickArea(view, expandSize, expandSize, expandSize, expandSize);
+ }
+
+ public static void expandClickArea(@NonNull final View view,
+ final int expandSizeTop,
+ final int expandSizeLeft,
+ final int expandSizeRight,
+ final int expandSizeBottom) {
+ final View parentView = (View) view.getParent();
+ if (parentView == null) {
+ Log.e("ClickUtils", "expandClickArea must have parent view.");
+ return;
+ }
+ parentView.post(new Runnable() {
+ @Override
+ public void run() {
+ final Rect rect = new Rect();
+ view.getHitRect(rect);
+ rect.top -= expandSizeTop;
+ rect.bottom += expandSizeBottom;
+ rect.left -= expandSizeLeft;
+ rect.right += expandSizeRight;
+ parentView.setTouchDelegate(new TouchDelegate(rect, view));
+ }
+ });
+ }
+
+ private static final long TIP_DURATION = 2000L;
+ private static long sLastClickMillis;
+ private static int sClickCount;
+
+ public static void back2HomeFriendly(final CharSequence tip) {
+ back2HomeFriendly(tip, TIP_DURATION, Back2HomeFriendlyListener.DEFAULT);
+ }
+
+ public static void back2HomeFriendly(@NonNull final CharSequence tip,
+ final long duration,
+ @NonNull Back2HomeFriendlyListener listener) {
+ long nowMillis = SystemClock.elapsedRealtime();
+ if (Math.abs(nowMillis - sLastClickMillis) < duration) {
+ sClickCount++;
+ if (sClickCount == 2) {
+ UtilsBridge.startHomeActivity();
+ listener.dismiss();
+ sLastClickMillis = 0;
+ }
+ } else {
+ sClickCount = 1;
+ listener.show(tip, duration);
+ sLastClickMillis = nowMillis;
+ }
+ }
+
+ public interface Back2HomeFriendlyListener {
+ Back2HomeFriendlyListener DEFAULT = new Back2HomeFriendlyListener() {
+ @Override
+ public void show(CharSequence text, long duration) {
+ UtilsBridge.toastShowShort(text);
+ }
+
+ @Override
+ public void dismiss() {
+ UtilsBridge.toastCancel();
+ }
+ };
+
+ void show(CharSequence text, long duration);
+
+ void dismiss();
}
public static abstract class OnDebouncingClickListener implements View.OnClickListener {
@@ -367,16 +431,7 @@ public void run() {
};
private static boolean isValid(@NonNull final View view, final long duration) {
- long curTime = System.currentTimeMillis();
- Object tag = view.getTag(DEBOUNCING_TAG);
- if (!(tag instanceof Long)) {
- view.setTag(DEBOUNCING_TAG, curTime);
- return true;
- }
- long preTime = (Long) tag;
- if (curTime - preTime <= duration) return false;
- view.setTag(DEBOUNCING_TAG, curTime);
- return true;
+ return UtilsBridge.isValid(view, duration);
}
private long mDuration;
@@ -509,4 +564,58 @@ private static class LazyHolder {
private static final OnUtilsTouchListener INSTANCE = new OnUtilsTouchListener();
}
}
+
+ static class ClickDrawableWrapper extends ShadowUtils.DrawableWrapper {
+
+ private BitmapDrawable mBitmapDrawable = null;
+
+ // 低版本ColorDrawable.setColorFilter无效,这里直接用画笔画上
+ private Paint mColorPaint = null;
+
+ public ClickDrawableWrapper(Drawable drawable) {
+ super(drawable);
+ if (drawable instanceof ColorDrawable) {
+ mColorPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
+ mColorPaint.setColor(((ColorDrawable) drawable).getColor());
+ }
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter cf) {
+ super.setColorFilter(cf);
+ // 低版本 StateListDrawable.selectDrawable 会重置 ColorFilter
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
+ if (mColorPaint != null) {
+ mColorPaint.setColorFilter(cf);
+ }
+ }
+ }
+
+ @Override
+ public void setAlpha(int alpha) {
+ super.setAlpha(alpha);
+ // 低版本 StateListDrawable.selectDrawable 会重置 Alpha
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
+ if (mColorPaint != null) {
+ mColorPaint.setColor(((ColorDrawable) getWrappedDrawable()).getColor());
+ }
+ }
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ if (mBitmapDrawable == null) {
+ Bitmap bitmap = Bitmap.createBitmap(getBounds().width(), getBounds().height(), Bitmap.Config.ARGB_8888);
+ Canvas myCanvas = new Canvas(bitmap);
+ if (mColorPaint != null) {
+ myCanvas.drawRect(getBounds(), mColorPaint);
+ } else {
+ super.draw(myCanvas);
+ }
+ mBitmapDrawable = new BitmapDrawable(Resources.getSystem(), bitmap);
+ mBitmapDrawable.setBounds(getBounds());
+ }
+ mBitmapDrawable.draw(canvas);
+ }
+ }
}
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/ClipboardUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/ClipboardUtils.java
new file mode 100644
index 0000000000..82127b4847
--- /dev/null
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/ClipboardUtils.java
@@ -0,0 +1,109 @@
+package com.blankj.utilcode.util;
+
+import android.content.ClipData;
+import android.content.ClipDescription;
+import android.content.ClipboardManager;
+import android.content.Context;
+
+/**
+ *
+ * author: Blankj
+ * blog : http://blankj.com
+ * time : 2016/09/25
+ * desc : utils about clipboard
+ *
+ */
+public final class ClipboardUtils {
+
+ private ClipboardUtils() {
+ throw new UnsupportedOperationException("u can't instantiate me...");
+ }
+
+ /**
+ * Copy the text to clipboard.
+ * The label equals name of package.
+ *
+ * @param text The text.
+ */
+ public static void copyText(final CharSequence text) {
+ ClipboardManager cm = (ClipboardManager) Utils.getApp().getSystemService(Context.CLIPBOARD_SERVICE);
+ //noinspection ConstantConditions
+ cm.setPrimaryClip(ClipData.newPlainText(Utils.getApp().getPackageName(), text));
+ }
+
+ /**
+ * Copy the text to clipboard.
+ *
+ * @param label The label.
+ * @param text The text.
+ */
+ public static void copyText(final CharSequence label, final CharSequence text) {
+ ClipboardManager cm = (ClipboardManager) Utils.getApp().getSystemService(Context.CLIPBOARD_SERVICE);
+ //noinspection ConstantConditions
+ cm.setPrimaryClip(ClipData.newPlainText(label, text));
+ }
+
+ /**
+ * Clear the clipboard.
+ */
+ public static void clear() {
+ ClipboardManager cm = (ClipboardManager) Utils.getApp().getSystemService(Context.CLIPBOARD_SERVICE);
+ //noinspection ConstantConditions
+ cm.setPrimaryClip(ClipData.newPlainText(null, ""));
+ }
+
+ /**
+ * Return the label for clipboard.
+ *
+ * @return the label for clipboard
+ */
+ public static CharSequence getLabel() {
+ ClipboardManager cm = (ClipboardManager) Utils.getApp().getSystemService(Context.CLIPBOARD_SERVICE);
+ //noinspection ConstantConditions
+ ClipDescription des = cm.getPrimaryClipDescription();
+ if (des == null) {
+ return "";
+ }
+ CharSequence label = des.getLabel();
+ if (label == null) {
+ return "";
+ }
+ return label;
+ }
+
+ /**
+ * Return the text for clipboard.
+ *
+ * @return the text for clipboard
+ */
+ public static CharSequence getText() {
+ ClipboardManager cm = (ClipboardManager) Utils.getApp().getSystemService(Context.CLIPBOARD_SERVICE);
+ //noinspection ConstantConditions
+ ClipData clip = cm.getPrimaryClip();
+ if (clip != null && clip.getItemCount() > 0) {
+ CharSequence text = clip.getItemAt(0).coerceToText(Utils.getApp());
+ if (text != null) {
+ return text;
+ }
+ }
+ return "";
+ }
+
+ /**
+ * Add the clipboard changed listener.
+ */
+ public static void addChangedListener(final ClipboardManager.OnPrimaryClipChangedListener listener) {
+ ClipboardManager cm = (ClipboardManager) Utils.getApp().getSystemService(Context.CLIPBOARD_SERVICE);
+ //noinspection ConstantConditions
+ cm.addPrimaryClipChangedListener(listener);
+ }
+
+ /**
+ * Remove the clipboard changed listener.
+ */
+ public static void removeChangedListener(final ClipboardManager.OnPrimaryClipChangedListener listener) {
+ ClipboardManager cm = (ClipboardManager) Utils.getApp().getSystemService(Context.CLIPBOARD_SERVICE);
+ //noinspection ConstantConditions
+ cm.removePrimaryClipChangedListener(listener);
+ }
+}
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/CloneUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/CloneUtils.java
index 93a4b720e4..108c73e6d2 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/CloneUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/CloneUtils.java
@@ -1,7 +1,5 @@
package com.blankj.utilcode.util;
-import com.google.gson.Gson;
-
import java.lang.reflect.Type;
/**
@@ -28,8 +26,7 @@ private CloneUtils() {
*/
public static T deepClone(final T data, final Type type) {
try {
- Gson gson = new Gson();
- return gson.fromJson(gson.toJson(data), type);
+ return UtilsBridge.fromJson(UtilsBridge.toJson(data), type);
} catch (Exception e) {
e.printStackTrace();
return null;
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/CollectionUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/CollectionUtils.java
index 33a9504348..2fcdbd18ed 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/CollectionUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/CollectionUtils.java
@@ -79,7 +79,7 @@ public static ArrayList newArrayListNotNull(E... array) {
}
@SafeVarargs
- public static List newLinkedList(E... array) {
+ public static LinkedList newLinkedList(E... array) {
LinkedList list = new LinkedList<>();
if (array == null || array.length == 0) return list;
for (E e : array) {
@@ -89,7 +89,7 @@ public static List newLinkedList(E... array) {
}
@SafeVarargs
- public static List newLinkedListNotNull(E... array) {
+ public static LinkedList newLinkedListNotNull(E... array) {
LinkedList list = new LinkedList<>();
if (array == null || array.length == 0) return list;
for (E e : array) {
@@ -373,7 +373,7 @@ public static boolean isSubCollection(final Collection a, final Collection b) {
*/
public static boolean isProperSubCollection(final Collection a, final Collection b) {
if (a == null || b == null) return false;
- return a.size() < b.size() && CollectionUtils.isSubCollection(a, b);
+ return a.size() < b.size() && isSubCollection(a, b);
}
/**
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/ColorUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/ColorUtils.java
index 93763b470b..c75e866124 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/ColorUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/ColorUtils.java
@@ -1,12 +1,12 @@
package com.blankj.utilcode.util;
import android.graphics.Color;
-import android.support.annotation.ColorInt;
-import android.support.annotation.ColorRes;
-import android.support.annotation.FloatRange;
-import android.support.annotation.IntRange;
-import android.support.annotation.NonNull;
-import android.support.v4.content.ContextCompat;
+import androidx.annotation.ColorInt;
+import androidx.annotation.ColorRes;
+import androidx.annotation.FloatRange;
+import androidx.annotation.IntRange;
+import androidx.annotation.NonNull;
+import androidx.core.content.ContextCompat;
/**
*
@@ -204,4 +204,14 @@ public static int getRandomColor(final boolean supportAlpha) {
int high = supportAlpha ? (int) (Math.random() * 0x100) << 24 : 0xFF000000;
return high | (int) (Math.random() * 0x1000000);
}
+
+ /**
+ * Return whether the color is light.
+ *
+ * @param color The color.
+ * @return {@code true}: yes
{@code false}: no
+ */
+ public static boolean isLightColor(@ColorInt int color) {
+ return 0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color) >= 127.5;
+ }
}
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/ConvertUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/ConvertUtils.java
index eaee41381e..d6f9eaafaf 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/ConvertUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/ConvertUtils.java
@@ -1,24 +1,32 @@
package com.blankj.utilcode.util;
import android.annotation.SuppressLint;
-import android.content.res.Resources;
import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.PixelFormat;
-import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.view.View;
import com.blankj.utilcode.constant.MemoryConstants;
import com.blankj.utilcode.constant.TimeConstants;
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
import java.io.OutputStream;
+import java.io.Serializable;
import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.List;
/**
*
@@ -30,12 +38,35 @@
*/
public final class ConvertUtils {
+ private static final int BUFFER_SIZE = 8192;
+ private static final char[] HEX_DIGITS_UPPER =
+ {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+ private static final char[] HEX_DIGITS_LOWER =
+ {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+
private ConvertUtils() {
throw new UnsupportedOperationException("u can't instantiate me...");
}
- private static final char[] hexDigits =
- {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+ /**
+ * Int to hex string.
+ *
+ * @param num The int number.
+ * @return the hex string
+ */
+ public static String int2HexString(int num) {
+ return Integer.toHexString(num);
+ }
+
+ /**
+ * Hex string to int.
+ *
+ * @param hexString The hex string.
+ * @return the int
+ */
+ public static int hexString2Int(String hexString) {
+ return Integer.parseInt(hexString, 16);
+ }
/**
* Bytes to bits.
@@ -121,7 +152,20 @@ public static byte[] chars2Bytes(final char[] chars) {
* @return hex string
*/
public static String bytes2HexString(final byte[] bytes) {
+ return bytes2HexString(bytes, true);
+ }
+
+ /**
+ * Bytes to hex string.
+ * e.g. bytes2HexString(new byte[] { 0, (byte) 0xa8 }, true) returns "00A8"
+ *
+ * @param bytes The bytes.
+ * @param isUpperCase True to use upper case, false otherwise.
+ * @return hex string
+ */
+ public static String bytes2HexString(final byte[] bytes, boolean isUpperCase) {
if (bytes == null) return "";
+ char[] hexDigits = isUpperCase ? HEX_DIGITS_UPPER : HEX_DIGITS_LOWER;
int len = bytes.length;
if (len <= 0) return "";
char[] ret = new char[len << 1];
@@ -140,7 +184,7 @@ public static String bytes2HexString(final byte[] bytes) {
* @return the bytes
*/
public static byte[] hexString2Bytes(String hexString) {
- if (isSpace(hexString)) return null;
+ if (UtilsBridge.isSpace(hexString)) return new byte[0];
int len = hexString.length();
if (len % 2 != 0) {
hexString = "0" + hexString;
@@ -149,12 +193,12 @@ public static byte[] hexString2Bytes(String hexString) {
char[] hexBytes = hexString.toUpperCase().toCharArray();
byte[] ret = new byte[len >> 1];
for (int i = 0; i < len; i += 2) {
- ret[i >> 1] = (byte) (hex2Int(hexBytes[i]) << 4 | hex2Int(hexBytes[i + 1]));
+ ret[i >> 1] = (byte) (hex2Dec(hexBytes[i]) << 4 | hex2Dec(hexBytes[i + 1]));
}
return ret;
}
- private static int hex2Int(final char hexChar) {
+ private static int hex2Dec(final char hexChar) {
if (hexChar >= '0' && hexChar <= '9') {
return hexChar - '0';
} else if (hexChar >= 'A' && hexChar <= 'F') {
@@ -164,6 +208,204 @@ private static int hex2Int(final char hexChar) {
}
}
+ /**
+ * Bytes to string.
+ */
+ public static String bytes2String(final byte[] bytes) {
+ return bytes2String(bytes, "");
+ }
+
+ /**
+ * Bytes to string.
+ */
+ public static String bytes2String(final byte[] bytes, final String charsetName) {
+ if (bytes == null) return null;
+ try {
+ return new String(bytes, getSafeCharset(charsetName));
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ return new String(bytes);
+ }
+ }
+
+ /**
+ * String to bytes.
+ */
+ public static byte[] string2Bytes(final String string) {
+ return string2Bytes(string, "");
+ }
+
+ /**
+ * String to bytes.
+ */
+ public static byte[] string2Bytes(final String string, final String charsetName) {
+ if (string == null) return null;
+ try {
+ return string.getBytes(getSafeCharset(charsetName));
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ return string.getBytes();
+ }
+ }
+
+ /**
+ * Bytes to JSONObject.
+ */
+ public static JSONObject bytes2JSONObject(final byte[] bytes) {
+ if (bytes == null) return null;
+ try {
+ return new JSONObject(new String(bytes));
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * JSONObject to bytes.
+ */
+ public static byte[] jsonObject2Bytes(final JSONObject jsonObject) {
+ if (jsonObject == null) return null;
+ return jsonObject.toString().getBytes();
+ }
+
+ /**
+ * Bytes to JSONArray.
+ */
+ public static JSONArray bytes2JSONArray(final byte[] bytes) {
+ if (bytes == null) return null;
+ try {
+ return new JSONArray(new String(bytes));
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * JSONArray to bytes.
+ */
+ public static byte[] jsonArray2Bytes(final JSONArray jsonArray) {
+ if (jsonArray == null) return null;
+ return jsonArray.toString().getBytes();
+ }
+
+ /**
+ * Bytes to Parcelable
+ */
+ public static T bytes2Parcelable(final byte[] bytes,
+ final Parcelable.Creator creator) {
+ if (bytes == null) return null;
+ Parcel parcel = Parcel.obtain();
+ parcel.unmarshall(bytes, 0, bytes.length);
+ parcel.setDataPosition(0);
+ T result = creator.createFromParcel(parcel);
+ parcel.recycle();
+ return result;
+ }
+
+ /**
+ * Parcelable to bytes.
+ */
+ public static byte[] parcelable2Bytes(final Parcelable parcelable) {
+ if (parcelable == null) return null;
+ Parcel parcel = Parcel.obtain();
+ parcelable.writeToParcel(parcel, 0);
+ byte[] bytes = parcel.marshall();
+ parcel.recycle();
+ return bytes;
+ }
+
+ /**
+ * Bytes to Serializable.
+ */
+ public static Object bytes2Object(final byte[] bytes) {
+ if (bytes == null) return null;
+ ObjectInputStream ois = null;
+ try {
+ ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
+ return ois.readObject();
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ } finally {
+ try {
+ if (ois != null) {
+ ois.close();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * Serializable to bytes.
+ */
+ public static byte[] serializable2Bytes(final Serializable serializable) {
+ if (serializable == null) return null;
+ ByteArrayOutputStream baos;
+ ObjectOutputStream oos = null;
+ try {
+ oos = new ObjectOutputStream(baos = new ByteArrayOutputStream());
+ oos.writeObject(serializable);
+ return baos.toByteArray();
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ } finally {
+ try {
+ if (oos != null) {
+ oos.close();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * Bytes to bitmap.
+ */
+ public static Bitmap bytes2Bitmap(final byte[] bytes) {
+ return UtilsBridge.bytes2Bitmap(bytes);
+ }
+
+ /**
+ * Bitmap to bytes.
+ */
+ public static byte[] bitmap2Bytes(final Bitmap bitmap) {
+ return UtilsBridge.bitmap2Bytes(bitmap);
+ }
+
+ /**
+ * Bitmap to bytes.
+ */
+ public static byte[] bitmap2Bytes(final Bitmap bitmap, final Bitmap.CompressFormat format, int quality) {
+ return UtilsBridge.bitmap2Bytes(bitmap, format, quality);
+ }
+
+ /**
+ * Bytes to drawable.
+ */
+ public static Drawable bytes2Drawable(final byte[] bytes) {
+ return UtilsBridge.bytes2Drawable(bytes);
+ }
+
+ /**
+ * Drawable to bytes.
+ */
+ public static byte[] drawable2Bytes(final Drawable drawable) {
+ return UtilsBridge.drawable2Bytes(drawable);
+ }
+
+ /**
+ * Drawable to bytes.
+ */
+ public static byte[] drawable2Bytes(final Drawable drawable, final Bitmap.CompressFormat format, int quality) {
+ return UtilsBridge.drawable2Bytes(drawable, format, quality);
+ }
+
/**
* Size of memory in unit to size of byte.
*
@@ -211,16 +453,32 @@ public static double byte2MemorySize(final long byteSize,
*/
@SuppressLint("DefaultLocale")
public static String byte2FitMemorySize(final long byteSize) {
+ return byte2FitMemorySize(byteSize, 3);
+ }
+
+ /**
+ * Size of byte to fit size of memory.
+ * to three decimal places
+ *
+ * @param byteSize Size of byte.
+ * @param precision The precision
+ * @return fit size of memory
+ */
+ @SuppressLint("DefaultLocale")
+ public static String byte2FitMemorySize(final long byteSize, int precision) {
+ if (precision < 0) {
+ throw new IllegalArgumentException("precision shouldn't be less than zero!");
+ }
if (byteSize < 0) {
- return "shouldn't be less than zero!";
+ throw new IllegalArgumentException("byteSize shouldn't be less than zero!");
} else if (byteSize < MemoryConstants.KB) {
- return String.format("%.3fB", (double) byteSize);
+ return String.format("%." + precision + "fB", (double) byteSize);
} else if (byteSize < MemoryConstants.MB) {
- return String.format("%.3fKB", (double) byteSize / MemoryConstants.KB);
+ return String.format("%." + precision + "fKB", (double) byteSize / MemoryConstants.KB);
} else if (byteSize < MemoryConstants.GB) {
- return String.format("%.3fMB", (double) byteSize / MemoryConstants.MB);
+ return String.format("%." + precision + "fMB", (double) byteSize / MemoryConstants.MB);
} else {
- return String.format("%.3fGB", (double) byteSize / MemoryConstants.GB);
+ return String.format("%." + precision + "fGB", (double) byteSize / MemoryConstants.GB);
}
}
@@ -276,36 +534,20 @@ public static long millis2TimeSpan(final long millis, @TimeConstants.Unit final
*
* @return fit time span
*/
- @SuppressLint("DefaultLocale")
public static String millis2FitTimeSpan(long millis, int precision) {
- if (millis <= 0 || precision <= 0) return null;
- StringBuilder sb = new StringBuilder();
- String[] units = {"天", "小时", "分钟", "秒", "毫秒"};
- int[] unitLen = {86400000, 3600000, 60000, 1000, 1};
- precision = Math.min(precision, 5);
- for (int i = 0; i < precision; i++) {
- if (millis >= unitLen[i]) {
- long mode = millis / unitLen[i];
- millis -= mode * unitLen[i];
- sb.append(mode).append(units[i]);
- }
- }
- return sb.toString();
+ return UtilsBridge.millis2FitTimeSpan(millis, precision);
}
/**
* Input stream to output stream.
- *
- * @param is The input stream.
- * @return output stream
*/
public static ByteArrayOutputStream input2OutputStream(final InputStream is) {
if (is == null) return null;
try {
ByteArrayOutputStream os = new ByteArrayOutputStream();
- byte[] b = new byte[MemoryConstants.KB];
+ byte[] b = new byte[BUFFER_SIZE];
int len;
- while ((len = is.read(b, 0, MemoryConstants.KB)) != -1) {
+ while ((len = is.read(b, 0, BUFFER_SIZE)) != -1) {
os.write(b, 0, len);
}
return os;
@@ -323,20 +565,14 @@ public static ByteArrayOutputStream input2OutputStream(final InputStream is) {
/**
* Output stream to input stream.
- *
- * @param out The output stream.
- * @return input stream
*/
- public ByteArrayInputStream output2InputStream(final OutputStream out) {
+ public static ByteArrayInputStream output2InputStream(final OutputStream out) {
if (out == null) return null;
return new ByteArrayInputStream(((ByteArrayOutputStream) out).toByteArray());
}
/**
* Input stream to bytes.
- *
- * @param is The input stream.
- * @return bytes
*/
public static byte[] inputStream2Bytes(final InputStream is) {
if (is == null) return null;
@@ -345,9 +581,6 @@ public static byte[] inputStream2Bytes(final InputStream is) {
/**
* Bytes to input stream.
- *
- * @param bytes The bytes.
- * @return input stream
*/
public static InputStream bytes2InputStream(final byte[] bytes) {
if (bytes == null || bytes.length <= 0) return null;
@@ -356,9 +589,6 @@ public static InputStream bytes2InputStream(final byte[] bytes) {
/**
* Output stream to bytes.
- *
- * @param out The output stream.
- * @return bytes
*/
public static byte[] outputStream2Bytes(final OutputStream out) {
if (out == null) return null;
@@ -367,9 +597,6 @@ public static byte[] outputStream2Bytes(final OutputStream out) {
/**
* Bytes to output stream.
- *
- * @param bytes The bytes.
- * @return output stream
*/
public static OutputStream bytes2OutputStream(final byte[] bytes) {
if (bytes == null || bytes.length <= 0) return null;
@@ -394,17 +621,13 @@ public static OutputStream bytes2OutputStream(final byte[] bytes) {
/**
* Input stream to string.
- *
- * @param is The input stream.
- * @param charsetName The name of charset.
- * @return string
*/
public static String inputStream2String(final InputStream is, final String charsetName) {
- if (is == null || isSpace(charsetName)) return "";
+ if (is == null) return "";
try {
ByteArrayOutputStream baos = input2OutputStream(is);
if (baos == null) return "";
- return baos.toString(charsetName);
+ return baos.toString(getSafeCharset(charsetName));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return "";
@@ -413,15 +636,11 @@ public static String inputStream2String(final InputStream is, final String chars
/**
* String to input stream.
- *
- * @param string The string.
- * @param charsetName The name of charset.
- * @return input stream
*/
public static InputStream string2InputStream(final String string, final String charsetName) {
- if (string == null || isSpace(charsetName)) return null;
+ if (string == null) return null;
try {
- return new ByteArrayInputStream(string.getBytes(charsetName));
+ return new ByteArrayInputStream(string.getBytes(getSafeCharset(charsetName)));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
@@ -430,15 +649,11 @@ public static InputStream string2InputStream(final String string, final String c
/**
* Output stream to string.
- *
- * @param out The output stream.
- * @param charsetName The name of charset.
- * @return string
*/
public static String outputStream2String(final OutputStream out, final String charsetName) {
- if (out == null || isSpace(charsetName)) return "";
+ if (out == null) return "";
try {
- return new String(outputStream2Bytes(out), charsetName);
+ return new String(outputStream2Bytes(out), getSafeCharset(charsetName));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return "";
@@ -447,193 +662,100 @@ public static String outputStream2String(final OutputStream out, final String ch
/**
* String to output stream.
- *
- * @param string The string.
- * @param charsetName The name of charset.
- * @return output stream
*/
public static OutputStream string2OutputStream(final String string, final String charsetName) {
- if (string == null || isSpace(charsetName)) return null;
+ if (string == null) return null;
try {
- return bytes2OutputStream(string.getBytes(charsetName));
+ return bytes2OutputStream(string.getBytes(getSafeCharset(charsetName)));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
- /**
- * Bitmap to bytes.
- *
- * @param bitmap The bitmap.
- * @param format The format of bitmap.
- * @return bytes
- */
- public static byte[] bitmap2Bytes(final Bitmap bitmap, final Bitmap.CompressFormat format) {
- if (bitmap == null) return null;
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- bitmap.compress(format, 100, baos);
- return baos.toByteArray();
+ public static List inputStream2Lines(final InputStream is) {
+ return inputStream2Lines(is, "");
}
- /**
- * Bytes to bitmap.
- *
- * @param bytes The bytes.
- * @return bitmap
- */
- public static Bitmap bytes2Bitmap(final byte[] bytes) {
- return (bytes == null || bytes.length == 0)
- ? null
- : BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
+ public static List inputStream2Lines(final InputStream is,
+ final String charsetName) {
+ BufferedReader reader = null;
+ try {
+ List list = new ArrayList<>();
+ reader = new BufferedReader(new InputStreamReader(is, getSafeCharset(charsetName)));
+ String line;
+ while ((line = reader.readLine()) != null) {
+ list.add(line);
+ }
+ return list;
+ } catch (IOException e) {
+ e.printStackTrace();
+ return null;
+ } finally {
+ try {
+ if (reader != null) {
+ reader.close();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
}
/**
* Drawable to bitmap.
- *
- * @param drawable The drawable.
- * @return bitmap
*/
public static Bitmap drawable2Bitmap(final Drawable drawable) {
- if (drawable instanceof BitmapDrawable) {
- BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
- if (bitmapDrawable.getBitmap() != null) {
- return bitmapDrawable.getBitmap();
- }
- }
- Bitmap bitmap;
- if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
- bitmap = Bitmap.createBitmap(1, 1,
- drawable.getOpacity() != PixelFormat.OPAQUE
- ? Bitmap.Config.ARGB_8888
- : Bitmap.Config.RGB_565);
- } else {
- bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
- drawable.getIntrinsicHeight(),
- drawable.getOpacity() != PixelFormat.OPAQUE
- ? Bitmap.Config.ARGB_8888
- : Bitmap.Config.RGB_565);
- }
- Canvas canvas = new Canvas(bitmap);
- drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
- drawable.draw(canvas);
- return bitmap;
+ return UtilsBridge.drawable2Bitmap(drawable);
}
/**
* Bitmap to drawable.
- *
- * @param bitmap The bitmap.
- * @return drawable
*/
public static Drawable bitmap2Drawable(final Bitmap bitmap) {
- return bitmap == null ? null : new BitmapDrawable(Utils.getApp().getResources(), bitmap);
- }
-
- /**
- * Drawable to bytes.
- *
- * @param drawable The drawable.
- * @param format The format of bitmap.
- * @return bytes
- */
- public static byte[] drawable2Bytes(final Drawable drawable,
- final Bitmap.CompressFormat format) {
- return drawable == null ? null : bitmap2Bytes(drawable2Bitmap(drawable), format);
- }
-
- /**
- * Bytes to drawable.
- *
- * @param bytes The bytes.
- * @return drawable
- */
- public static Drawable bytes2Drawable(final byte[] bytes) {
- return bytes == null ? null : bitmap2Drawable(bytes2Bitmap(bytes));
+ return UtilsBridge.bitmap2Drawable(bitmap);
}
/**
* View to bitmap.
- *
- * @param view The view.
- * @return bitmap
*/
public static Bitmap view2Bitmap(final View view) {
- if (view == null) return null;
- boolean drawingCacheEnabled = view.isDrawingCacheEnabled();
- boolean willNotCacheDrawing = view.willNotCacheDrawing();
- view.setDrawingCacheEnabled(true);
- view.setWillNotCacheDrawing(false);
- final Bitmap drawingCache = view.getDrawingCache();
- Bitmap bitmap;
- if (null == drawingCache) {
- view.layout(0, 0, view.getWidth(), view.getHeight());
- view.buildDrawingCache();
- bitmap = Bitmap.createBitmap(view.getDrawingCache());
- } else {
- bitmap = Bitmap.createBitmap(drawingCache);
- }
- view.destroyDrawingCache();
- view.setWillNotCacheDrawing(willNotCacheDrawing);
- view.setDrawingCacheEnabled(drawingCacheEnabled);
- return bitmap;
+ return UtilsBridge.view2Bitmap(view);
}
/**
* Value of dp to value of px.
- *
- * @param dpValue The value of dp.
- * @return value of px
*/
public static int dp2px(final float dpValue) {
- final float scale = Resources.getSystem().getDisplayMetrics().density;
- return (int) (dpValue * scale + 0.5f);
+ return UtilsBridge.dp2px(dpValue);
}
/**
* Value of px to value of dp.
- *
- * @param pxValue The value of px.
- * @return value of dp
*/
public static int px2dp(final float pxValue) {
- final float scale = Resources.getSystem().getDisplayMetrics().density;
- return (int) (pxValue / scale + 0.5f);
+ return UtilsBridge.px2dp(pxValue);
}
/**
* Value of sp to value of px.
- *
- * @param spValue The value of sp.
- * @return value of px
*/
public static int sp2px(final float spValue) {
- final float fontScale = Resources.getSystem().getDisplayMetrics().scaledDensity;
- return (int) (spValue * fontScale + 0.5f);
+ return UtilsBridge.sp2px(spValue);
}
/**
* Value of px to value of sp.
- *
- * @param pxValue The value of px.
- * @return value of sp
*/
public static int px2sp(final float pxValue) {
- final float fontScale = Resources.getSystem().getDisplayMetrics().scaledDensity;
- return (int) (pxValue / fontScale + 0.5f);
+ return UtilsBridge.px2sp(pxValue);
}
- ///////////////////////////////////////////////////////////////////////////
- // other utils methods
- ///////////////////////////////////////////////////////////////////////////
-
- private static boolean isSpace(final String s) {
- if (s == null) return true;
- for (int i = 0, len = s.length(); i < len; ++i) {
- if (!Character.isWhitespace(s.charAt(i))) {
- return false;
- }
+ private static String getSafeCharset(String charsetName) {
+ String cn = charsetName;
+ if (UtilsBridge.isSpace(charsetName) || !Charset.isSupported(charsetName)) {
+ cn = "UTF-8";
}
- return true;
+ return cn;
}
}
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/CrashUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/CrashUtils.java
index 66e44e982e..598f7fdbac 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/CrashUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/CrashUtils.java
@@ -1,30 +1,11 @@
package com.blankj.utilcode.util;
-import android.annotation.SuppressLint;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.os.Build;
-import android.os.Environment;
-import android.support.annotation.NonNull;
-import android.support.annotation.RequiresPermission;
-import android.util.Log;
-
-import java.io.BufferedWriter;
+import androidx.annotation.NonNull;
import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
import java.lang.Thread.UncaughtExceptionHandler;
-import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Date;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-
-import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
+import java.util.Map;
/**
*
@@ -36,78 +17,10 @@
*/
public final class CrashUtils {
- private static String defaultDir;
- private static String dir;
- private static String versionName;
- private static int versionCode;
-
private static final String FILE_SEP = System.getProperty("file.separator");
- @SuppressLint("SimpleDateFormat")
- private static final Format FORMAT = new SimpleDateFormat("MM-dd_HH-mm-ss");
-
- private static final UncaughtExceptionHandler DEFAULT_UNCAUGHT_EXCEPTION_HANDLER;
- private static final UncaughtExceptionHandler UNCAUGHT_EXCEPTION_HANDLER;
-
- private static OnCrashListener sOnCrashListener;
-
- static {
- try {
- PackageInfo pi = Utils.getApp()
- .getPackageManager()
- .getPackageInfo(Utils.getApp().getPackageName(), 0);
- if (pi != null) {
- versionName = pi.versionName;
- versionCode = pi.versionCode;
- }
- } catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- }
- DEFAULT_UNCAUGHT_EXCEPTION_HANDLER = Thread.getDefaultUncaughtExceptionHandler();
-
- UNCAUGHT_EXCEPTION_HANDLER = new UncaughtExceptionHandler() {
- @Override
- public void uncaughtException(final Thread t, final Throwable e) {
- if (e == null) {
- if (DEFAULT_UNCAUGHT_EXCEPTION_HANDLER != null) {
- DEFAULT_UNCAUGHT_EXCEPTION_HANDLER.uncaughtException(t, null);
- } else {
- android.os.Process.killProcess(android.os.Process.myPid());
- System.exit(1);
- }
- return;
- }
-
- final String time = FORMAT.format(new Date(System.currentTimeMillis()));
- final StringBuilder sb = new StringBuilder();
- final String head = "************* Log Head ****************" +
- "\nTime Of Crash : " + time +
- "\nDevice Manufacturer: " + Build.MANUFACTURER +
- "\nDevice Model : " + Build.MODEL +
- "\nAndroid Version : " + Build.VERSION.RELEASE +
- "\nAndroid SDK : " + Build.VERSION.SDK_INT +
- "\nApp VersionName : " + versionName +
- "\nApp VersionCode : " + versionCode +
- "\n************* Log Head ****************\n\n";
- sb.append(head)
- .append(ThrowableUtils.getFullStackTrace(e));
- final String crashInfo = sb.toString();
- final String fullPath = (dir == null ? defaultDir : dir) + time + ".txt";
- if (createOrExistsFile(fullPath)) {
- input2File(crashInfo, fullPath);
- } else {
- Log.e("CrashUtils", "create " + fullPath + " failed!");
- }
-
- if (sOnCrashListener != null) {
- sOnCrashListener.onCrash(crashInfo, e);
- }
- if (DEFAULT_UNCAUGHT_EXCEPTION_HANDLER != null) {
- DEFAULT_UNCAUGHT_EXCEPTION_HANDLER.uncaughtException(t, e);
- }
- }
- };
- }
+ private static final UncaughtExceptionHandler DEFAULT_UNCAUGHT_EXCEPTION_HANDLER =
+ Thread.getDefaultUncaughtExceptionHandler();
private CrashUtils() {
throw new UnsupportedOperationException("u can't instantiate me...");
@@ -115,80 +28,88 @@ private CrashUtils() {
/**
* Initialization.
- * Must hold {@code }
*/
- @SuppressLint("MissingPermission")
public static void init() {
init("");
}
/**
* Initialization
- * Must hold {@code }
*
* @param crashDir The directory of saving crash information.
*/
- @RequiresPermission(WRITE_EXTERNAL_STORAGE)
public static void init(@NonNull final File crashDir) {
init(crashDir.getAbsolutePath(), null);
}
/**
* Initialization
- * Must hold {@code }
*
* @param crashDirPath The directory's path of saving crash information.
*/
- @RequiresPermission(WRITE_EXTERNAL_STORAGE)
public static void init(final String crashDirPath) {
init(crashDirPath, null);
}
/**
* Initialization
- * Must hold {@code }
*
* @param onCrashListener The crash listener.
*/
- @SuppressLint("MissingPermission")
public static void init(final OnCrashListener onCrashListener) {
init("", onCrashListener);
}
/**
* Initialization
- * Must hold {@code }
*
- * @param crashDir The directory of saving crash information.
+ * @param crashDir The directory of saving crash information.
* @param onCrashListener The crash listener.
*/
- @RequiresPermission(WRITE_EXTERNAL_STORAGE)
public static void init(@NonNull final File crashDir, final OnCrashListener onCrashListener) {
init(crashDir.getAbsolutePath(), onCrashListener);
}
/**
* Initialization
- * Must hold {@code }
*
- * @param crashDirPath The directory's path of saving crash information.
+ * @param crashDirPath The directory's path of saving crash information.
* @param onCrashListener The crash listener.
*/
- @RequiresPermission(WRITE_EXTERNAL_STORAGE)
public static void init(final String crashDirPath, final OnCrashListener onCrashListener) {
- if (isSpace(crashDirPath)) {
- dir = null;
+ String dirPath;
+ if (UtilsBridge.isSpace(crashDirPath)) {
+ if (UtilsBridge.isSDCardEnableByEnvironment()
+ && Utils.getApp().getExternalFilesDir(null) != null) {
+ dirPath = Utils.getApp().getExternalFilesDir(null) + FILE_SEP + "crash" + FILE_SEP;
+ } else {
+ dirPath = Utils.getApp().getFilesDir() + FILE_SEP + "crash" + FILE_SEP;
+ }
} else {
- dir = crashDirPath.endsWith(FILE_SEP) ? crashDirPath : crashDirPath + FILE_SEP;
+ dirPath = crashDirPath.endsWith(FILE_SEP) ? crashDirPath : crashDirPath + FILE_SEP;
}
- if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
- && Utils.getApp().getExternalCacheDir() != null)
- defaultDir = Utils.getApp().getExternalCacheDir() + FILE_SEP + "crash" + FILE_SEP;
- else {
- defaultDir = Utils.getApp().getCacheDir() + FILE_SEP + "crash" + FILE_SEP;
- }
- sOnCrashListener = onCrashListener;
- Thread.setDefaultUncaughtExceptionHandler(UNCAUGHT_EXCEPTION_HANDLER);
+ Thread.setDefaultUncaughtExceptionHandler(
+ getUncaughtExceptionHandler(dirPath, onCrashListener));
+ }
+
+ private static UncaughtExceptionHandler getUncaughtExceptionHandler(final String dirPath,
+ final OnCrashListener onCrashListener) {
+ return new UncaughtExceptionHandler() {
+ @Override
+ public void uncaughtException(@NonNull final Thread t, @NonNull final Throwable e) {
+ final String time = new SimpleDateFormat("yyyy_MM_dd-HH_mm_ss").format(new Date());
+ CrashInfo info = new CrashInfo(time, e);
+ final String crashFile = dirPath + time + ".txt";
+ UtilsBridge.writeFileFromString(crashFile, info.toString(), true);
+
+ if (DEFAULT_UNCAUGHT_EXCEPTION_HANDLER != null) {
+ DEFAULT_UNCAUGHT_EXCEPTION_HANDLER.uncaughtException(t, e);
+ }
+ if (onCrashListener != null) {
+ onCrashListener.onCrash(info);
+ }
+ }
+ };
}
///////////////////////////////////////////////////////////////////////////
@@ -196,69 +117,34 @@ public static void init(final String crashDirPath, final OnCrashListener onCrash
///////////////////////////////////////////////////////////////////////////
public interface OnCrashListener {
- void onCrash(String crashInfo, Throwable e);
+ void onCrash(CrashInfo crashInfo);
}
- ///////////////////////////////////////////////////////////////////////////
- // other utils methods
- ///////////////////////////////////////////////////////////////////////////
+ public static final class CrashInfo {
+ private UtilsBridge.FileHead mFileHeadProvider;
+ private Throwable mThrowable;
- private static void input2File(final String input, final String filePath) {
- Future submit = Executors.newSingleThreadExecutor().submit(new Callable() {
- @Override
- public Boolean call() {
- BufferedWriter bw = null;
- try {
- bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePath, true), "UTF-8"));
- bw.write(input);
- return true;
- } catch (IOException e) {
- e.printStackTrace();
- return false;
- } finally {
- try {
- if (bw != null) {
- bw.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- });
- try {
- if (submit.get()) return;
- } catch (InterruptedException e) {
- e.printStackTrace();
- } catch (ExecutionException e) {
- e.printStackTrace();
+ private CrashInfo(String time, Throwable throwable) {
+ mThrowable = throwable;
+ mFileHeadProvider = new UtilsBridge.FileHead("Crash");
+ mFileHeadProvider.addFirst("Time Of Crash", time);
}
- Log.e("CrashUtils", "write crash info to " + filePath + " failed!");
- }
- private static boolean createOrExistsFile(final String filePath) {
- File file = new File(filePath);
- if (file.exists()) return file.isFile();
- if (!createOrExistsDir(file.getParentFile())) return false;
- try {
- return file.createNewFile();
- } catch (IOException e) {
- e.printStackTrace();
- return false;
+ public final void addExtraHead(Map extraHead) {
+ mFileHeadProvider.append(extraHead);
}
- }
- private static boolean createOrExistsDir(final File file) {
- return file != null && (file.exists() ? file.isDirectory() : file.mkdirs());
- }
+ public final void addExtraHead(String key, String value) {
+ mFileHeadProvider.append(key, value);
+ }
- private static boolean isSpace(final String s) {
- if (s == null) return true;
- for (int i = 0, len = s.length(); i < len; ++i) {
- if (!Character.isWhitespace(s.charAt(i))) {
- return false;
- }
+ public final Throwable getThrowable() {
+ return mThrowable;
+ }
+
+ @Override
+ public String toString() {
+ return mFileHeadProvider.toString() + UtilsBridge.getFullStackTrace(mThrowable);
}
- return true;
}
}
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/DebouncingUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/DebouncingUtils.java
new file mode 100644
index 0000000000..afc49b9c6f
--- /dev/null
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/DebouncingUtils.java
@@ -0,0 +1,86 @@
+package com.blankj.utilcode.util;
+
+import android.os.SystemClock;
+import android.text.TextUtils;
+import android.view.View;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import androidx.annotation.NonNull;
+
+/**
+ *
+ * author: Blankj
+ * blog : http://blankj.com
+ * time : 2020/09/01
+ * desc : utils about debouncing
+ *
+ */
+public class DebouncingUtils {
+
+ private static final int CACHE_SIZE = 64;
+ private static final Map KEY_MILLIS_MAP = new ConcurrentHashMap<>(CACHE_SIZE);
+ private static final long DEBOUNCING_DEFAULT_VALUE = 1000;
+
+ private DebouncingUtils() {
+ throw new UnsupportedOperationException("u can't instantiate me...");
+ }
+
+ /**
+ * Return whether the view is not in a jitter state.
+ *
+ * @param view The view.
+ * @return {@code true}: yes
{@code false}: no
+ */
+ public static boolean isValid(@NonNull final View view) {
+ return isValid(view, DEBOUNCING_DEFAULT_VALUE);
+ }
+
+ /**
+ * Return whether the view is not in a jitter state.
+ *
+ * @param view The view.
+ * @param duration The duration.
+ * @return {@code true}: yes
{@code false}: no
+ */
+ public static boolean isValid(@NonNull final View view, final long duration) {
+ return isValid(String.valueOf(view.hashCode()), duration);
+ }
+
+ /**
+ * Return whether the key is not in a jitter state.
+ *
+ * @param key The key.
+ * @param duration The duration.
+ * @return {@code true}: yes
{@code false}: no
+ */
+ public static boolean isValid(@NonNull String key, final long duration) {
+ if (TextUtils.isEmpty(key)) {
+ throw new IllegalArgumentException("The key is null.");
+ }
+ if (duration < 0) {
+ throw new IllegalArgumentException("The duration is less than 0.");
+ }
+ long curTime = SystemClock.elapsedRealtime();
+ clearIfNecessary(curTime);
+ Long validTime = KEY_MILLIS_MAP.get(key);
+ if (validTime == null || curTime >= validTime) {
+ KEY_MILLIS_MAP.put(key, curTime + duration);
+ return true;
+ }
+ return false;
+ }
+
+ private static void clearIfNecessary(long curTime) {
+ if (KEY_MILLIS_MAP.size() < CACHE_SIZE) return;
+ for (Iterator> it = KEY_MILLIS_MAP.entrySet().iterator(); it.hasNext(); ) {
+ Map.Entry entry = it.next();
+ Long validTime = entry.getValue();
+ if (curTime >= validTime) {
+ it.remove();
+ }
+ }
+ }
+}
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/DeviceUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/DeviceUtils.java
index 44235d4d60..9cd01108e1 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/DeviceUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/DeviceUtils.java
@@ -4,23 +4,28 @@
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.net.Uri;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.provider.Settings;
-import android.support.annotation.RequiresApi;
-import android.support.annotation.RequiresPermission;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
+import java.io.BufferedReader;
import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import java.util.UUID;
+import androidx.annotation.RequiresApi;
+import androidx.annotation.RequiresPermission;
+
import static android.Manifest.permission.ACCESS_WIFI_STATE;
import static android.Manifest.permission.CHANGE_WIFI_STATE;
import static android.Manifest.permission.INTERNET;
@@ -112,10 +117,10 @@ public static String getAndroidID() {
*
* @return the MAC address
*/
- @RequiresPermission(allOf = {ACCESS_WIFI_STATE, INTERNET, CHANGE_WIFI_STATE})
+ @RequiresPermission(allOf = {ACCESS_WIFI_STATE, CHANGE_WIFI_STATE})
public static String getMacAddress() {
String macAddress = getMacAddress((String[]) null);
- if (!macAddress.equals("") || getWifiEnabled()) return macAddress;
+ if (!TextUtils.isEmpty(macAddress) || getWifiEnabled()) return macAddress;
setWifiEnabled(true);
setWifiEnabled(false);
return getMacAddress((String[]) null);
@@ -150,7 +155,7 @@ private static void setWifiEnabled(final boolean enabled) {
*
* @return the MAC address
*/
- @RequiresPermission(allOf = {ACCESS_WIFI_STATE, INTERNET})
+ @RequiresPermission(allOf = {ACCESS_WIFI_STATE})
public static String getMacAddress(final String... excepts) {
String macAddress = getMacAddressByNetworkInterface();
if (isAddressNotInExcepts(macAddress, excepts)) {
@@ -172,25 +177,37 @@ public static String getMacAddress(final String... excepts) {
}
private static boolean isAddressNotInExcepts(final String address, final String... excepts) {
+ if (TextUtils.isEmpty(address)) {
+ return false;
+ }
+ if ("02:00:00:00:00:00".equals(address)) {
+ return false;
+ }
if (excepts == null || excepts.length == 0) {
- return !"02:00:00:00:00:00".equals(address);
+ return true;
}
for (String filter : excepts) {
- if (address.equals(filter)) {
+ if (filter != null && filter.equals(address)) {
return false;
}
}
return true;
}
- @SuppressLint({"MissingPermission", "HardwareIds"})
+ @RequiresPermission(ACCESS_WIFI_STATE)
private static String getMacAddressByWifiInfo() {
try {
final WifiManager wifi = (WifiManager) Utils.getApp()
.getApplicationContext().getSystemService(WIFI_SERVICE);
if (wifi != null) {
final WifiInfo info = wifi.getConnectionInfo();
- if (info != null) return info.getMacAddress();
+ if (info != null) {
+ @SuppressLint("HardwareIds")
+ String macAddress = info.getMacAddress();
+ if (!TextUtils.isEmpty(macAddress)) {
+ return macAddress;
+ }
+ }
}
} catch (Exception e) {
e.printStackTrace();
@@ -264,11 +281,11 @@ private static InetAddress getInetAddress() {
}
private static String getMacAddressByFile() {
- ShellUtils.CommandResult result = ShellUtils.execCmd("getprop wifi.interface", false);
+ ShellUtils.CommandResult result = UtilsBridge.execCmd("getprop wifi.interface", false);
if (result.result == 0) {
String name = result.successMsg;
if (name != null) {
- result = ShellUtils.execCmd("cat /sys/class/net/" + name + "/address", false);
+ result = UtilsBridge.execCmd("cat /sys/class/net/" + name + "/address", false);
if (result.result == 0) {
String address = result.successMsg;
if (address != null && address.length() > 0) {
@@ -329,7 +346,7 @@ public static String[] getABIs() {
* @return {@code true}: yes
{@code false}: no
*/
public static boolean isTablet() {
- return (Utils.getApp().getResources().getConfiguration().screenLayout
+ return (Resources.getSystem().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
@@ -368,6 +385,7 @@ public static boolean isEmulator() {
intent.setAction(Intent.ACTION_DIAL);
boolean checkDial = intent.resolveActivity(Utils.getApp().getPackageManager()) == null;
if (checkDial) return true;
+ if (isEmulatorByCpu()) return true;
// boolean checkDebuggerConnected = Debug.isDebuggerConnected();
// if (checkDebuggerConnected) return true;
@@ -375,6 +393,55 @@ public static boolean isEmulator() {
return false;
}
+ /**
+ * Returns whether is emulator by check cpu info.
+ * by function of {@link #readCpuInfo}, obtain the device cpu information.
+ * then compare whether it is intel or amd (because intel and amd are generally not mobile phone cpu), to determine whether it is a real mobile phone
+ *
+ * @return {@code true}: yes
{@code false}: no
+ */
+ private static boolean isEmulatorByCpu() {
+ String cpuInfo = readCpuInfo();
+ return cpuInfo.contains("intel") || cpuInfo.contains("amd");
+ }
+
+ /**
+ * Return Cpu information
+ *
+ * @return Cpu info
+ */
+ private static String readCpuInfo() {
+ String result = "";
+ try {
+ String[] args = {"/system/bin/cat", "/proc/cpuinfo"};
+ ProcessBuilder cmd = new ProcessBuilder(args);
+ Process process = cmd.start();
+ StringBuilder sb = new StringBuilder();
+ String readLine;
+ BufferedReader responseReader = new BufferedReader(new InputStreamReader(process.getInputStream(), "utf-8"));
+ while ((readLine = responseReader.readLine()) != null) {
+ sb.append(readLine);
+ }
+ responseReader.close();
+ result = sb.toString().toLowerCase();
+ } catch (IOException ignored) {
+ }
+ return result;
+ }
+
+ /**
+ * Whether user has enabled development settings.
+ *
+ * @return whether user has enabled development settings.
+ */
+ @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
+ public static boolean isDevelopmentSettingsEnabled() {
+ return Settings.Global.getInt(
+ Utils.getApp().getContentResolver(),
+ Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0
+ ) > 0;
+ }
+
private static final String KEY_UDID = "KEY_UDID";
private volatile static String udid;
@@ -387,9 +454,8 @@ public static boolean isEmulator() {
*
* @return the unique device id
*/
- @SuppressLint({"MissingPermission", "HardwareIds"})
public static String getUniqueDeviceId() {
- return getUniqueDeviceId("");
+ return getUniqueDeviceId("", true);
}
/**
@@ -401,40 +467,79 @@ public static String getUniqueDeviceId() {
* @param prefix The prefix of the unique device id.
* @return the unique device id
*/
- @SuppressLint({"MissingPermission", "HardwareIds"})
public static String getUniqueDeviceId(String prefix) {
+ return getUniqueDeviceId(prefix, true);
+ }
+
+ /**
+ * Return the unique device id.
+ * {1}{UUID(macAddress)}
+ * {2}{UUID(androidId )}
+ * {9}{UUID(random )}
+ *
+ * @param useCache True to use cache, false otherwise.
+ * @return the unique device id
+ */
+ public static String getUniqueDeviceId(boolean useCache) {
+ return getUniqueDeviceId("", useCache);
+ }
+
+ /**
+ * Return the unique device id.
+ * android 10 deprecated {prefix}{1}{UUID(macAddress)}
+ * {prefix}{2}{UUID(androidId )}
+ * {prefix}{9}{UUID(random )}
+ *
+ * @param prefix The prefix of the unique device id.
+ * @param useCache True to use cache, false otherwise.
+ * @return the unique device id
+ */
+ public static String getUniqueDeviceId(String prefix, boolean useCache) {
+ if (!useCache) {
+ return getUniqueDeviceIdReal(prefix);
+ }
if (udid == null) {
synchronized (DeviceUtils.class) {
if (udid == null) {
- final String id = Utils.getSpUtils4Utils().getString(KEY_UDID, null);
+ final String id = UtilsBridge.getSpUtils4Utils().getString(KEY_UDID, null);
if (id != null) {
udid = id;
return udid;
}
- try {
- final String androidId = getAndroidID();
- if (!TextUtils.isEmpty(androidId)) {
- return saveUdid(prefix + 2, androidId);
- }
-
- } catch (Exception ignore) {/**/}
- return saveUdid(prefix + 9, "");
+ return getUniqueDeviceIdReal(prefix);
}
}
}
return udid;
}
- @SuppressLint({"MissingPermission", "HardwareIds"})
+ private static String getUniqueDeviceIdReal(String prefix) {
+ try {
+ final String androidId = getAndroidID();
+ if (!TextUtils.isEmpty(androidId)) {
+ return saveUdid(prefix + 2, androidId);
+ }
+
+ } catch (Exception ignore) {/**/}
+ return saveUdid(prefix + 9, "");
+ }
+
+ @RequiresPermission(allOf = {ACCESS_WIFI_STATE, INTERNET, CHANGE_WIFI_STATE})
public static boolean isSameDevice(final String uniqueDeviceId) {
// {prefix}{type}{32id}
if (TextUtils.isEmpty(uniqueDeviceId) && uniqueDeviceId.length() < 33) return false;
if (uniqueDeviceId.equals(udid)) return true;
- final String cachedId = Utils.getSpUtils4Utils().getString(KEY_UDID, null);
+ final String cachedId = UtilsBridge.getSpUtils4Utils().getString(KEY_UDID, null);
if (uniqueDeviceId.equals(cachedId)) return true;
int st = uniqueDeviceId.length() - 33;
String type = uniqueDeviceId.substring(st, st + 1);
- if (type.startsWith("2")) {
+ if (type.startsWith("1")) {
+ String macAddress = getMacAddress();
+ if (macAddress.equals("")) {
+ return false;
+ }
+ return uniqueDeviceId.substring(st + 1).equals(getUdid("", macAddress));
+ } else if (type.startsWith("2")) {
final String androidId = getAndroidID();
if (TextUtils.isEmpty(androidId)) {
return false;
@@ -446,7 +551,7 @@ public static boolean isSameDevice(final String uniqueDeviceId) {
private static String saveUdid(String prefix, String id) {
udid = getUdid(prefix, id);
- SPUtils.getInstance().put(KEY_UDID, udid);
+ UtilsBridge.getSpUtils4Utils().put(KEY_UDID, udid);
return udid;
}
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/EncodeUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/EncodeUtils.java
index 6a491c7c92..a961be77a4 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/EncodeUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/EncodeUtils.java
@@ -175,7 +175,6 @@ public static String htmlEncode(final CharSequence input) {
* @param input The input.
* @return the string of decode html-encode string
*/
- @SuppressWarnings("deprecation")
public static CharSequence htmlDecode(final String input) {
if (input == null || input.length() == 0) return "";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
@@ -191,13 +190,13 @@ public static CharSequence htmlDecode(final String input) {
* @param input The input.
* @return binary string
*/
- public static String binEncode(final String input) {
- StringBuilder stringBuilder = new StringBuilder();
+ public static String binaryEncode(final String input) {
+ if (input == null || input.length() == 0) return "";
+ StringBuilder sb = new StringBuilder();
for (char i : input.toCharArray()) {
- stringBuilder.append(Integer.toBinaryString(i));
- stringBuilder.append(' ');
+ sb.append(Integer.toBinaryString(i)).append(" ");
}
- return stringBuilder.toString();
+ return sb.deleteCharAt(sb.length() - 1).toString();
}
/**
@@ -206,11 +205,12 @@ public static String binEncode(final String input) {
* @param input binary string
* @return UTF-8 String
*/
- public static String binDecode(final String input) {
- String[] splitted = input.split(" ");
+ public static String binaryDecode(final String input) {
+ if (input == null || input.length() == 0) return "";
+ String[] splits = input.split(" ");
StringBuilder sb = new StringBuilder();
- for (String i : splitted) {
- sb.append(((char) Integer.parseInt(i.replace(" ", ""), 2)));
+ for (String split : splits) {
+ sb.append(((char) Integer.parseInt(split, 2)));
}
return sb.toString();
}
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/EncryptUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/EncryptUtils.java
index 691ff1f6f0..933f8e4953 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/EncryptUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/EncryptUtils.java
@@ -1,6 +1,6 @@
package com.blankj.utilcode.util;
-import android.util.Base64;
+import android.os.Build;
import java.io.File;
import java.io.FileInputStream;
@@ -12,15 +12,11 @@
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
-import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
import javax.crypto.Mac;
-import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
@@ -63,7 +59,7 @@ public static String encryptMD2ToString(final String data) {
* @return the hex string of MD2 encryption
*/
public static String encryptMD2ToString(final byte[] data) {
- return bytes2HexString(encryptMD2(data));
+ return UtilsBridge.bytes2HexString(encryptMD2(data));
}
/**
@@ -96,9 +92,9 @@ public static String encryptMD5ToString(final String data) {
*/
public static String encryptMD5ToString(final String data, final String salt) {
if (data == null && salt == null) return "";
- if (salt == null) return bytes2HexString(encryptMD5(data.getBytes()));
- if (data == null) return bytes2HexString(encryptMD5(salt.getBytes()));
- return bytes2HexString(encryptMD5((data + salt).getBytes()));
+ if (salt == null) return UtilsBridge.bytes2HexString(encryptMD5(data.getBytes()));
+ if (data == null) return UtilsBridge.bytes2HexString(encryptMD5(salt.getBytes()));
+ return UtilsBridge.bytes2HexString(encryptMD5((data + salt).getBytes()));
}
/**
@@ -108,7 +104,7 @@ public static String encryptMD5ToString(final String data, final String salt) {
* @return the hex string of MD5 encryption
*/
public static String encryptMD5ToString(final byte[] data) {
- return bytes2HexString(encryptMD5(data));
+ return UtilsBridge.bytes2HexString(encryptMD5(data));
}
/**
@@ -120,12 +116,12 @@ public static String encryptMD5ToString(final byte[] data) {
*/
public static String encryptMD5ToString(final byte[] data, final byte[] salt) {
if (data == null && salt == null) return "";
- if (salt == null) return bytes2HexString(encryptMD5(data));
- if (data == null) return bytes2HexString(encryptMD5(salt));
+ if (salt == null) return UtilsBridge.bytes2HexString(encryptMD5(data));
+ if (data == null) return UtilsBridge.bytes2HexString(encryptMD5(salt));
byte[] dataSalt = new byte[data.length + salt.length];
System.arraycopy(data, 0, dataSalt, 0, data.length);
System.arraycopy(salt, 0, dataSalt, data.length, salt.length);
- return bytes2HexString(encryptMD5(dataSalt));
+ return UtilsBridge.bytes2HexString(encryptMD5(dataSalt));
}
/**
@@ -145,7 +141,7 @@ public static byte[] encryptMD5(final byte[] data) {
* @return the hex string of file's MD5 encryption
*/
public static String encryptMD5File2String(final String filePath) {
- File file = isSpace(filePath) ? null : new File(filePath);
+ File file = UtilsBridge.isSpace(filePath) ? null : new File(filePath);
return encryptMD5File2String(file);
}
@@ -156,7 +152,7 @@ public static String encryptMD5File2String(final String filePath) {
* @return the bytes of file's MD5 encryption
*/
public static byte[] encryptMD5File(final String filePath) {
- File file = isSpace(filePath) ? null : new File(filePath);
+ File file = UtilsBridge.isSpace(filePath) ? null : new File(filePath);
return encryptMD5File(file);
}
@@ -167,7 +163,7 @@ public static byte[] encryptMD5File(final String filePath) {
* @return the hex string of file's MD5 encryption
*/
public static String encryptMD5File2String(final File file) {
- return bytes2HexString(encryptMD5File(file));
+ return UtilsBridge.bytes2HexString(encryptMD5File(file));
}
/**
@@ -222,7 +218,7 @@ public static String encryptSHA1ToString(final String data) {
* @return the hex string of SHA1 encryption
*/
public static String encryptSHA1ToString(final byte[] data) {
- return bytes2HexString(encryptSHA1(data));
+ return UtilsBridge.bytes2HexString(encryptSHA1(data));
}
/**
@@ -253,7 +249,7 @@ public static String encryptSHA224ToString(final String data) {
* @return the hex string of SHA224 encryption
*/
public static String encryptSHA224ToString(final byte[] data) {
- return bytes2HexString(encryptSHA224(data));
+ return UtilsBridge.bytes2HexString(encryptSHA224(data));
}
/**
@@ -284,7 +280,7 @@ public static String encryptSHA256ToString(final String data) {
* @return the hex string of SHA256 encryption
*/
public static String encryptSHA256ToString(final byte[] data) {
- return bytes2HexString(encryptSHA256(data));
+ return UtilsBridge.bytes2HexString(encryptSHA256(data));
}
/**
@@ -315,7 +311,7 @@ public static String encryptSHA384ToString(final String data) {
* @return the hex string of SHA384 encryption
*/
public static String encryptSHA384ToString(final byte[] data) {
- return bytes2HexString(encryptSHA384(data));
+ return UtilsBridge.bytes2HexString(encryptSHA384(data));
}
/**
@@ -346,7 +342,7 @@ public static String encryptSHA512ToString(final String data) {
* @return the hex string of SHA512 encryption
*/
public static String encryptSHA512ToString(final byte[] data) {
- return bytes2HexString(encryptSHA512(data));
+ return UtilsBridge.bytes2HexString(encryptSHA512(data));
}
/**
@@ -366,7 +362,7 @@ public static byte[] encryptSHA512(final byte[] data) {
* @param algorithm The name of hash encryption.
* @return the bytes of hash encryption
*/
- private static byte[] hashTemplate(final byte[] data, final String algorithm) {
+ static byte[] hashTemplate(final byte[] data, final String algorithm) {
if (data == null || data.length <= 0) return null;
try {
MessageDigest md = MessageDigest.getInstance(algorithm);
@@ -402,7 +398,7 @@ public static String encryptHmacMD5ToString(final String data, final String key)
* @return the hex string of HmacMD5 encryption
*/
public static String encryptHmacMD5ToString(final byte[] data, final byte[] key) {
- return bytes2HexString(encryptHmacMD5(data, key));
+ return UtilsBridge.bytes2HexString(encryptHmacMD5(data, key));
}
/**
@@ -436,7 +432,7 @@ public static String encryptHmacSHA1ToString(final String data, final String key
* @return the hex string of HmacSHA1 encryption
*/
public static String encryptHmacSHA1ToString(final byte[] data, final byte[] key) {
- return bytes2HexString(encryptHmacSHA1(data, key));
+ return UtilsBridge.bytes2HexString(encryptHmacSHA1(data, key));
}
/**
@@ -470,7 +466,7 @@ public static String encryptHmacSHA224ToString(final String data, final String k
* @return the hex string of HmacSHA224 encryption
*/
public static String encryptHmacSHA224ToString(final byte[] data, final byte[] key) {
- return bytes2HexString(encryptHmacSHA224(data, key));
+ return UtilsBridge.bytes2HexString(encryptHmacSHA224(data, key));
}
/**
@@ -504,7 +500,7 @@ public static String encryptHmacSHA256ToString(final String data, final String k
* @return the hex string of HmacSHA256 encryption
*/
public static String encryptHmacSHA256ToString(final byte[] data, final byte[] key) {
- return bytes2HexString(encryptHmacSHA256(data, key));
+ return UtilsBridge.bytes2HexString(encryptHmacSHA256(data, key));
}
/**
@@ -538,7 +534,7 @@ public static String encryptHmacSHA384ToString(final String data, final String k
* @return the hex string of HmacSHA384 encryption
*/
public static String encryptHmacSHA384ToString(final byte[] data, final byte[] key) {
- return bytes2HexString(encryptHmacSHA384(data, key));
+ return UtilsBridge.bytes2HexString(encryptHmacSHA384(data, key));
}
/**
@@ -572,7 +568,7 @@ public static String encryptHmacSHA512ToString(final String data, final String k
* @return the hex string of HmacSHA512 encryption
*/
public static String encryptHmacSHA512ToString(final byte[] data, final byte[] key) {
- return bytes2HexString(encryptHmacSHA512(data, key));
+ return UtilsBridge.bytes2HexString(encryptHmacSHA512(data, key));
}
/**
@@ -627,7 +623,7 @@ public static byte[] encryptDES2Base64(final byte[] data,
final byte[] key,
final String transformation,
final byte[] iv) {
- return base64Encode(encryptDES(data, key, transformation, iv));
+ return UtilsBridge.base64Encode(encryptDES(data, key, transformation, iv));
}
/**
@@ -644,7 +640,7 @@ public static String encryptDES2HexString(final byte[] data,
final byte[] key,
final String transformation,
final byte[] iv) {
- return bytes2HexString(encryptDES(data, key, transformation, iv));
+ return UtilsBridge.bytes2HexString(encryptDES(data, key, transformation, iv));
}
/**
@@ -678,7 +674,7 @@ public static byte[] decryptBase64DES(final byte[] data,
final byte[] key,
final String transformation,
final byte[] iv) {
- return decryptDES(base64Decode(data), key, transformation, iv);
+ return decryptDES(UtilsBridge.base64Decode(data), key, transformation, iv);
}
/**
@@ -695,7 +691,7 @@ public static byte[] decryptHexStringDES(final String data,
final byte[] key,
final String transformation,
final byte[] iv) {
- return decryptDES(hexString2Bytes(data), key, transformation, iv);
+ return decryptDES(UtilsBridge.hexString2Bytes(data), key, transformation, iv);
}
/**
@@ -733,7 +729,7 @@ public static byte[] encrypt3DES2Base64(final byte[] data,
final byte[] key,
final String transformation,
final byte[] iv) {
- return base64Encode(encrypt3DES(data, key, transformation, iv));
+ return UtilsBridge.base64Encode(encrypt3DES(data, key, transformation, iv));
}
/**
@@ -750,7 +746,7 @@ public static String encrypt3DES2HexString(final byte[] data,
final byte[] key,
final String transformation,
final byte[] iv) {
- return bytes2HexString(encrypt3DES(data, key, transformation, iv));
+ return UtilsBridge.bytes2HexString(encrypt3DES(data, key, transformation, iv));
}
/**
@@ -784,7 +780,7 @@ public static byte[] decryptBase64_3DES(final byte[] data,
final byte[] key,
final String transformation,
final byte[] iv) {
- return decrypt3DES(base64Decode(data), key, transformation, iv);
+ return decrypt3DES(UtilsBridge.base64Decode(data), key, transformation, iv);
}
/**
@@ -801,7 +797,7 @@ public static byte[] decryptHexString3DES(final String data,
final byte[] key,
final String transformation,
final byte[] iv) {
- return decrypt3DES(hexString2Bytes(data), key, transformation, iv);
+ return decrypt3DES(UtilsBridge.hexString2Bytes(data), key, transformation, iv);
}
/**
@@ -839,7 +835,7 @@ public static byte[] encryptAES2Base64(final byte[] data,
final byte[] key,
final String transformation,
final byte[] iv) {
- return base64Encode(encryptAES(data, key, transformation, iv));
+ return UtilsBridge.base64Encode(encryptAES(data, key, transformation, iv));
}
/**
@@ -856,7 +852,7 @@ public static String encryptAES2HexString(final byte[] data,
final byte[] key,
final String transformation,
final byte[] iv) {
- return bytes2HexString(encryptAES(data, key, transformation, iv));
+ return UtilsBridge.bytes2HexString(encryptAES(data, key, transformation, iv));
}
/**
@@ -890,7 +886,7 @@ public static byte[] decryptBase64AES(final byte[] data,
final byte[] key,
final String transformation,
final byte[] iv) {
- return decryptAES(base64Decode(data), key, transformation, iv);
+ return decryptAES(UtilsBridge.base64Decode(data), key, transformation, iv);
}
/**
@@ -907,7 +903,7 @@ public static byte[] decryptHexStringAES(final String data,
final byte[] key,
final String transformation,
final byte[] iv) {
- return decryptAES(hexString2Bytes(data), key, transformation, iv);
+ return decryptAES(UtilsBridge.hexString2Bytes(data), key, transformation, iv);
}
/**
@@ -984,7 +980,7 @@ public static byte[] encryptRSA2Base64(final byte[] data,
final byte[] publicKey,
final int keySize,
final String transformation) {
- return base64Encode(encryptRSA(data, publicKey, keySize, transformation));
+ return UtilsBridge.base64Encode(encryptRSA(data, publicKey, keySize, transformation));
}
/**
@@ -1000,7 +996,7 @@ public static String encryptRSA2HexString(final byte[] data,
final byte[] publicKey,
final int keySize,
final String transformation) {
- return bytes2HexString(encryptRSA(data, publicKey, keySize, transformation));
+ return UtilsBridge.bytes2HexString(encryptRSA(data, publicKey, keySize, transformation));
}
/**
@@ -1032,7 +1028,7 @@ public static byte[] decryptBase64RSA(final byte[] data,
final byte[] privateKey,
final int keySize,
final String transformation) {
- return decryptRSA(base64Decode(data), privateKey, keySize, transformation);
+ return decryptRSA(UtilsBridge.base64Decode(data), privateKey, keySize, transformation);
}
/**
@@ -1048,7 +1044,7 @@ public static byte[] decryptHexStringRSA(final String data,
final byte[] privateKey,
final int keySize,
final String transformation) {
- return decryptRSA(hexString2Bytes(data), privateKey, keySize, transformation);
+ return decryptRSA(UtilsBridge.hexString2Bytes(data), privateKey, keySize, transformation);
}
/**
@@ -1087,12 +1083,18 @@ private static byte[] rsaTemplate(final byte[] data,
}
try {
Key rsaKey;
+ KeyFactory keyFactory;
+ if (Build.VERSION.SDK_INT < 28) {
+ keyFactory = KeyFactory.getInstance("RSA", "BC");
+ } else {
+ keyFactory = KeyFactory.getInstance("RSA");
+ }
if (isEncrypt) {
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(key);
- rsaKey = KeyFactory.getInstance("RSA").generatePublic(keySpec);
+ rsaKey = keyFactory.generatePublic(keySpec);
} else {
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(key);
- rsaKey = KeyFactory.getInstance("RSA").generatePrivate(keySpec);
+ rsaKey = keyFactory.generatePrivate(keySpec);
}
if (rsaKey == null) return null;
Cipher cipher = Cipher.getInstance(transformation);
@@ -1125,17 +1127,7 @@ private static byte[] rsaTemplate(final byte[] data,
} else {
return cipher.doFinal(data);
}
- } catch (NoSuchAlgorithmException e) {
- e.printStackTrace();
- } catch (NoSuchPaddingException e) {
- e.printStackTrace();
- } catch (InvalidKeyException e) {
- e.printStackTrace();
- } catch (BadPaddingException e) {
- e.printStackTrace();
- } catch (IllegalBlockSizeException e) {
- e.printStackTrace();
- } catch (InvalidKeySpecException e) {
+ } catch (Exception e) {
e.printStackTrace();
}
return null;
@@ -1183,72 +1175,10 @@ public static byte[] rc4(byte[] data, byte[] key) {
return ret;
}
- ///////////////////////////////////////////////////////////////////////////
- // other utils methods
- ///////////////////////////////////////////////////////////////////////////
-
private static byte[] joins(final byte[] prefix, final byte[] suffix) {
byte[] ret = new byte[prefix.length + suffix.length];
System.arraycopy(prefix, 0, ret, 0, prefix.length);
System.arraycopy(suffix, 0, ret, prefix.length, suffix.length);
return ret;
}
-
- private static final char[] HEX_DIGITS =
- {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
-
- private static String bytes2HexString(final byte[] bytes) {
- if (bytes == null) return "";
- int len = bytes.length;
- if (len <= 0) return "";
- char[] ret = new char[len << 1];
- for (int i = 0, j = 0; i < len; i++) {
- ret[j++] = HEX_DIGITS[bytes[i] >> 4 & 0x0f];
- ret[j++] = HEX_DIGITS[bytes[i] & 0x0f];
- }
- return new String(ret);
- }
-
- private static byte[] hexString2Bytes(String hexString) {
- if (isSpace(hexString)) return null;
- int len = hexString.length();
- if (len % 2 != 0) {
- hexString = "0" + hexString;
- len = len + 1;
- }
- char[] hexBytes = hexString.toUpperCase().toCharArray();
- byte[] ret = new byte[len >> 1];
- for (int i = 0; i < len; i += 2) {
- ret[i >> 1] = (byte) (hex2Dec(hexBytes[i]) << 4 | hex2Dec(hexBytes[i + 1]));
- }
- return ret;
- }
-
- private static int hex2Dec(final char hexChar) {
- if (hexChar >= '0' && hexChar <= '9') {
- return hexChar - '0';
- } else if (hexChar >= 'A' && hexChar <= 'F') {
- return hexChar - 'A' + 10;
- } else {
- throw new IllegalArgumentException();
- }
- }
-
- private static byte[] base64Encode(final byte[] input) {
- return Base64.encode(input, Base64.NO_WRAP);
- }
-
- private static byte[] base64Decode(final byte[] input) {
- return Base64.decode(input, Base64.NO_WRAP);
- }
-
- private static boolean isSpace(final String s) {
- if (s == null) return true;
- for (int i = 0, len = s.length(); i < len; ++i) {
- if (!Character.isWhitespace(s.charAt(i))) {
- return false;
- }
- }
- return true;
- }
}
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/FileIOUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/FileIOUtils.java
index b40565aa16..ca786e0b98 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/FileIOUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/FileIOUtils.java
@@ -1,5 +1,7 @@
package com.blankj.utilcode.util;
+import android.util.Log;
+
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
@@ -51,7 +53,7 @@ private FileIOUtils() {
* @return {@code true}: success
{@code false}: fail
*/
public static boolean writeFileFromIS(final String filePath, final InputStream is) {
- return writeFileFromIS(getFileByPath(filePath), is, false, null);
+ return writeFileFromIS(UtilsBridge.getFileByPath(filePath), is, false, null);
}
/**
@@ -65,7 +67,7 @@ public static boolean writeFileFromIS(final String filePath, final InputStream i
public static boolean writeFileFromIS(final String filePath,
final InputStream is,
final boolean append) {
- return writeFileFromIS(getFileByPath(filePath), is, append, null);
+ return writeFileFromIS(UtilsBridge.getFileByPath(filePath), is, append, null);
}
/**
@@ -108,7 +110,7 @@ public static boolean writeFileFromIS(final File file,
public static boolean writeFileFromIS(final String filePath,
final InputStream is,
final OnProgressUpdateListener listener) {
- return writeFileFromIS(getFileByPath(filePath), is, false, listener);
+ return writeFileFromIS(UtilsBridge.getFileByPath(filePath), is, false, listener);
}
/**
@@ -124,7 +126,7 @@ public static boolean writeFileFromIS(final String filePath,
final InputStream is,
final boolean append,
final OnProgressUpdateListener listener) {
- return writeFileFromIS(getFileByPath(filePath), is, append, listener);
+ return writeFileFromIS(UtilsBridge.getFileByPath(filePath), is, append, listener);
}
/**
@@ -154,7 +156,10 @@ public static boolean writeFileFromIS(final File file,
final InputStream is,
final boolean append,
final OnProgressUpdateListener listener) {
- if (is == null || !createOrExistsFile(file)) return false;
+ if (is == null || !UtilsBridge.createOrExistsFile(file)) {
+ Log.e("FileIOUtils", "create file <" + file + "> failed.");
+ return false;
+ }
OutputStream os = null;
try {
os = new BufferedOutputStream(new FileOutputStream(file, append), sBufferSize);
@@ -207,7 +212,7 @@ public static boolean writeFileFromIS(final File file,
* @return {@code true}: success
{@code false}: fail
*/
public static boolean writeFileFromBytesByStream(final String filePath, final byte[] bytes) {
- return writeFileFromBytesByStream(getFileByPath(filePath), bytes, false, null);
+ return writeFileFromBytesByStream(UtilsBridge.getFileByPath(filePath), bytes, false, null);
}
/**
@@ -221,7 +226,7 @@ public static boolean writeFileFromBytesByStream(final String filePath, final by
public static boolean writeFileFromBytesByStream(final String filePath,
final byte[] bytes,
final boolean append) {
- return writeFileFromBytesByStream(getFileByPath(filePath), bytes, append, null);
+ return writeFileFromBytesByStream(UtilsBridge.getFileByPath(filePath), bytes, append, null);
}
/**
@@ -264,7 +269,7 @@ public static boolean writeFileFromBytesByStream(final File file,
public static boolean writeFileFromBytesByStream(final String filePath,
final byte[] bytes,
final OnProgressUpdateListener listener) {
- return writeFileFromBytesByStream(getFileByPath(filePath), bytes, false, listener);
+ return writeFileFromBytesByStream(UtilsBridge.getFileByPath(filePath), bytes, false, listener);
}
/**
@@ -280,7 +285,7 @@ public static boolean writeFileFromBytesByStream(final String filePath,
final byte[] bytes,
final boolean append,
final OnProgressUpdateListener listener) {
- return writeFileFromBytesByStream(getFileByPath(filePath), bytes, append, listener);
+ return writeFileFromBytesByStream(UtilsBridge.getFileByPath(filePath), bytes, append, listener);
}
/**
@@ -325,7 +330,7 @@ public static boolean writeFileFromBytesByStream(final File file,
public static boolean writeFileFromBytesByChannel(final String filePath,
final byte[] bytes,
final boolean isForce) {
- return writeFileFromBytesByChannel(getFileByPath(filePath), bytes, false, isForce);
+ return writeFileFromBytesByChannel(UtilsBridge.getFileByPath(filePath), bytes, false, isForce);
}
/**
@@ -341,7 +346,7 @@ public static boolean writeFileFromBytesByChannel(final String filePath,
final byte[] bytes,
final boolean append,
final boolean isForce) {
- return writeFileFromBytesByChannel(getFileByPath(filePath), bytes, append, isForce);
+ return writeFileFromBytesByChannel(UtilsBridge.getFileByPath(filePath), bytes, append, isForce);
}
/**
@@ -371,10 +376,21 @@ public static boolean writeFileFromBytesByChannel(final File file,
final byte[] bytes,
final boolean append,
final boolean isForce) {
- if (bytes == null || !createOrExistsFile(file)) return false;
+ if (bytes == null) {
+ Log.e("FileIOUtils", "bytes is null.");
+ return false;
+ }
+ if (!UtilsBridge.createOrExistsFile(file)) {
+ Log.e("FileIOUtils", "create file <" + file + "> failed.");
+ return false;
+ }
FileChannel fc = null;
try {
fc = new FileOutputStream(file, append).getChannel();
+ if (fc == null) {
+ Log.e("FileIOUtils", "fc is null.");
+ return false;
+ }
fc.position(fc.size());
fc.write(ByteBuffer.wrap(bytes));
if (isForce) fc.force(true);
@@ -420,7 +436,7 @@ public static boolean writeFileFromBytesByMap(final String filePath,
final byte[] bytes,
final boolean append,
final boolean isForce) {
- return writeFileFromBytesByMap(getFileByPath(filePath), bytes, append, isForce);
+ return writeFileFromBytesByMap(UtilsBridge.getFileByPath(filePath), bytes, append, isForce);
}
/**
@@ -450,10 +466,17 @@ public static boolean writeFileFromBytesByMap(final File file,
final byte[] bytes,
final boolean append,
final boolean isForce) {
- if (bytes == null || !createOrExistsFile(file)) return false;
+ if (bytes == null || !UtilsBridge.createOrExistsFile(file)) {
+ Log.e("FileIOUtils", "create file <" + file + "> failed.");
+ return false;
+ }
FileChannel fc = null;
try {
fc = new FileOutputStream(file, append).getChannel();
+ if (fc == null) {
+ Log.e("FileIOUtils", "fc is null.");
+ return false;
+ }
MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, fc.size(), bytes.length);
mbb.put(bytes);
if (isForce) mbb.force();
@@ -480,7 +503,7 @@ public static boolean writeFileFromBytesByMap(final File file,
* @return {@code true}: success
{@code false}: fail
*/
public static boolean writeFileFromString(final String filePath, final String content) {
- return writeFileFromString(getFileByPath(filePath), content, false);
+ return writeFileFromString(UtilsBridge.getFileByPath(filePath), content, false);
}
/**
@@ -494,7 +517,7 @@ public static boolean writeFileFromString(final String filePath, final String co
public static boolean writeFileFromString(final String filePath,
final String content,
final boolean append) {
- return writeFileFromString(getFileByPath(filePath), content, append);
+ return writeFileFromString(UtilsBridge.getFileByPath(filePath), content, append);
}
/**
@@ -520,7 +543,10 @@ public static boolean writeFileFromString(final File file,
final String content,
final boolean append) {
if (file == null || content == null) return false;
- if (!createOrExistsFile(file)) return false;
+ if (!UtilsBridge.createOrExistsFile(file)) {
+ Log.e("FileIOUtils", "create file <" + file + "> failed.");
+ return false;
+ }
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter(file, append));
@@ -551,7 +577,7 @@ public static boolean writeFileFromString(final File file,
* @return the lines in file
*/
public static List readFile2List(final String filePath) {
- return readFile2List(getFileByPath(filePath), null);
+ return readFile2List(UtilsBridge.getFileByPath(filePath), null);
}
/**
@@ -562,7 +588,7 @@ public static List readFile2List(final String filePath) {
* @return the lines in file
*/
public static List readFile2List(final String filePath, final String charsetName) {
- return readFile2List(getFileByPath(filePath), charsetName);
+ return readFile2List(UtilsBridge.getFileByPath(filePath), charsetName);
}
/**
@@ -595,7 +621,7 @@ public static List readFile2List(final File file, final String charsetNa
* @return the lines in file
*/
public static List readFile2List(final String filePath, final int st, final int end) {
- return readFile2List(getFileByPath(filePath), st, end, null);
+ return readFile2List(UtilsBridge.getFileByPath(filePath), st, end, null);
}
/**
@@ -611,7 +637,7 @@ public static List readFile2List(final String filePath,
final int st,
final int end,
final String charsetName) {
- return readFile2List(getFileByPath(filePath), st, end, charsetName);
+ return readFile2List(UtilsBridge.getFileByPath(filePath), st, end, charsetName);
}
/**
@@ -639,14 +665,14 @@ public static List readFile2List(final File file,
final int st,
final int end,
final String charsetName) {
- if (!isFileExists(file)) return null;
+ if (!UtilsBridge.isFileExists(file)) return null;
if (st > end) return null;
BufferedReader reader = null;
try {
String line;
int curLine = 1;
List list = new ArrayList<>();
- if (isSpace(charsetName)) {
+ if (UtilsBridge.isSpace(charsetName)) {
reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
} else {
reader = new BufferedReader(
@@ -680,7 +706,7 @@ public static List readFile2List(final File file,
* @return the string in file
*/
public static String readFile2String(final String filePath) {
- return readFile2String(getFileByPath(filePath), null);
+ return readFile2String(UtilsBridge.getFileByPath(filePath), null);
}
/**
@@ -691,7 +717,7 @@ public static String readFile2String(final String filePath) {
* @return the string in file
*/
public static String readFile2String(final String filePath, final String charsetName) {
- return readFile2String(getFileByPath(filePath), charsetName);
+ return readFile2String(UtilsBridge.getFileByPath(filePath), charsetName);
}
/**
@@ -714,7 +740,7 @@ public static String readFile2String(final File file) {
public static String readFile2String(final File file, final String charsetName) {
byte[] bytes = readFile2BytesByStream(file);
if (bytes == null) return null;
- if (isSpace(charsetName)) {
+ if (UtilsBridge.isSpace(charsetName)) {
return new String(bytes);
} else {
try {
@@ -737,7 +763,7 @@ public static String readFile2String(final File file, final String charsetName)
* @return the bytes in file
*/
public static byte[] readFile2BytesByStream(final String filePath) {
- return readFile2BytesByStream(getFileByPath(filePath), null);
+ return readFile2BytesByStream(UtilsBridge.getFileByPath(filePath), null);
}
/**
@@ -763,7 +789,7 @@ public static byte[] readFile2BytesByStream(final File file) {
*/
public static byte[] readFile2BytesByStream(final String filePath,
final OnProgressUpdateListener listener) {
- return readFile2BytesByStream(getFileByPath(filePath));
+ return readFile2BytesByStream(UtilsBridge.getFileByPath(filePath), listener);
}
/**
@@ -775,7 +801,7 @@ public static byte[] readFile2BytesByStream(final String filePath,
*/
public static byte[] readFile2BytesByStream(final File file,
final OnProgressUpdateListener listener) {
- if (!isFileExists(file)) return null;
+ if (!UtilsBridge.isFileExists(file)) return null;
try {
ByteArrayOutputStream os = null;
InputStream is = new BufferedInputStream(new FileInputStream(file), sBufferSize);
@@ -828,7 +854,7 @@ public static byte[] readFile2BytesByStream(final File file,
* @return the bytes in file
*/
public static byte[] readFile2BytesByChannel(final String filePath) {
- return readFile2BytesByChannel(getFileByPath(filePath));
+ return readFile2BytesByChannel(UtilsBridge.getFileByPath(filePath));
}
/**
@@ -838,10 +864,14 @@ public static byte[] readFile2BytesByChannel(final String filePath) {
* @return the bytes in file
*/
public static byte[] readFile2BytesByChannel(final File file) {
- if (!isFileExists(file)) return null;
+ if (!UtilsBridge.isFileExists(file)) return null;
FileChannel fc = null;
try {
fc = new RandomAccessFile(file, "r").getChannel();
+ if (fc == null) {
+ Log.e("FileIOUtils", "fc is null.");
+ return new byte[0];
+ }
ByteBuffer byteBuffer = ByteBuffer.allocate((int) fc.size());
while (true) {
if (!((fc.read(byteBuffer)) > 0)) break;
@@ -868,7 +898,7 @@ public static byte[] readFile2BytesByChannel(final File file) {
* @return the bytes in file
*/
public static byte[] readFile2BytesByMap(final String filePath) {
- return readFile2BytesByMap(getFileByPath(filePath));
+ return readFile2BytesByMap(UtilsBridge.getFileByPath(filePath));
}
/**
@@ -878,10 +908,14 @@ public static byte[] readFile2BytesByMap(final String filePath) {
* @return the bytes in file
*/
public static byte[] readFile2BytesByMap(final File file) {
- if (!isFileExists(file)) return null;
+ if (!UtilsBridge.isFileExists(file)) return null;
FileChannel fc = null;
try {
fc = new RandomAccessFile(file, "r").getChannel();
+ if (fc == null) {
+ Log.e("FileIOUtils", "fc is null.");
+ return new byte[0];
+ }
int size = (int) fc.size();
MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_ONLY, 0, size).load();
byte[] result = new byte[size];
@@ -911,81 +945,7 @@ public static void setBufferSize(final int bufferSize) {
sBufferSize = bufferSize;
}
- ///////////////////////////////////////////////////////////////////////////
- // other utils methods
- ///////////////////////////////////////////////////////////////////////////
-
- private static File getFileByPath(final String filePath) {
- return isSpace(filePath) ? null : new File(filePath);
- }
-
- private static boolean createOrExistsFile(final String filePath) {
- return createOrExistsFile(getFileByPath(filePath));
- }
-
- private static boolean createOrExistsFile(final File file) {
- if (file == null) return false;
- if (file.exists()) return file.isFile();
- if (!createOrExistsDir(file.getParentFile())) return false;
- try {
- return file.createNewFile();
- } catch (IOException e) {
- e.printStackTrace();
- return false;
- }
- }
-
- private static boolean createOrExistsDir(final File file) {
- return file != null && (file.exists() ? file.isDirectory() : file.mkdirs());
- }
-
- private static boolean isFileExists(final File file) {
- return file != null && file.exists();
- }
-
- private static boolean isSpace(final String s) {
- if (s == null) return true;
- for (int i = 0, len = s.length(); i < len; ++i) {
- if (!Character.isWhitespace(s.charAt(i))) {
- return false;
- }
- }
- return true;
- }
-
- private static byte[] is2Bytes(final InputStream is) {
- if (is == null) return null;
- ByteArrayOutputStream os = null;
- try {
- os = new ByteArrayOutputStream();
- byte[] b = new byte[sBufferSize];
- int len;
- while ((len = is.read(b, 0, sBufferSize)) != -1) {
- os.write(b, 0, len);
- }
- return os.toByteArray();
- } catch (IOException e) {
- e.printStackTrace();
- return null;
- } finally {
- try {
- is.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- try {
- if (os != null) {
- os.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
-
public interface OnProgressUpdateListener {
-
void onProgressUpdate(double progress);
-
}
}
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/FileUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/FileUtils.java
index 512f2e920a..1acca1e050 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/FileUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/FileUtils.java
@@ -5,17 +5,16 @@
import android.content.res.AssetFileDescriptor;
import android.net.Uri;
import android.os.Build;
+import android.os.StatFs;
+import android.text.TextUtils;
import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.OutputStream;
import java.net.URL;
import java.security.DigestInputStream;
import java.security.MessageDigest;
@@ -24,7 +23,6 @@
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
-import java.util.Locale;
import javax.net.ssl.HttpsURLConnection;
@@ -51,7 +49,21 @@ private FileUtils() {
* @return the file
*/
public static File getFileByPath(final String filePath) {
- return isSpace(filePath) ? null : new File(filePath);
+ return UtilsBridge.isSpace(filePath) ? null : new File(filePath);
+ }
+
+ /**
+ * Return whether the file exists.
+ *
+ * @param file The file.
+ * @return {@code true}: yes
{@code false}: no
+ */
+ public static boolean isFileExists(final File file) {
+ if (file == null) return false;
+ if (file.exists()) {
+ return true;
+ }
+ return isFileExists(file.getAbsolutePath());
}
/**
@@ -61,9 +73,16 @@ public static File getFileByPath(final String filePath) {
* @return {@code true}: yes
{@code false}: no
*/
public static boolean isFileExists(final String filePath) {
- if (Build.VERSION.SDK_INT < 29) {
- return isFileExists(getFileByPath(filePath));
- } else {
+ File file = getFileByPath(filePath);
+ if (file == null) return false;
+ if (file.exists()) {
+ return true;
+ }
+ return isFileExistsApi29(filePath);
+ }
+
+ private static boolean isFileExistsApi29(String filePath) {
+ if (Build.VERSION.SDK_INT >= 29) {
try {
Uri uri = Uri.parse(filePath);
ContentResolver cr = Utils.getApp().getContentResolver();
@@ -78,16 +97,7 @@ public static boolean isFileExists(final String filePath) {
}
return true;
}
- }
-
- /**
- * Return whether the file exists.
- *
- * @param file The file.
- * @return {@code true}: yes
{@code false}: no
- */
- public static boolean isFileExists(final File file) {
- return file != null && file.exists();
+ return false;
}
/**
@@ -114,7 +124,7 @@ public static boolean rename(final File file, final String newName) {
// file doesn't exist then return false
if (!file.exists()) return false;
// the new name is space then return false
- if (isSpace(newName)) return false;
+ if (UtilsBridge.isSpace(newName)) return false;
// the new name equals old name then return true
if (newName.equals(file.getName())) return true;
File newFile = new File(file.getParent() + File.separator + newName);
@@ -420,12 +430,14 @@ private static boolean copyOrMoveDir(final File srcDir,
if (!srcDir.exists() || !srcDir.isDirectory()) return false;
if (!createOrExistsDir(destDir)) return false;
File[] files = srcDir.listFiles();
- for (File file : files) {
- File oneDestFile = new File(destPath + file.getName());
- if (file.isFile()) {
- if (!copyOrMoveFile(file, oneDestFile, listener, isMove)) return false;
- } else if (file.isDirectory()) {
- if (!copyOrMoveDir(file, oneDestFile, listener, isMove)) return false;
+ if (files != null && files.length > 0) {
+ for (File file : files) {
+ File oneDestFile = new File(destPath + file.getName());
+ if (file.isFile()) {
+ if (!copyOrMoveFile(file, oneDestFile, listener, isMove)) return false;
+ } else if (file.isDirectory()) {
+ if (!copyOrMoveDir(file, oneDestFile, listener, isMove)) return false;
+ }
}
}
return !isMove || deleteDir(srcDir);
@@ -451,7 +463,7 @@ private static boolean copyOrMoveFile(final File srcFile,
}
if (!createOrExistsDir(destFile.getParentFile())) return false;
try {
- return writeFileFromIS(destFile, new FileInputStream(srcFile))
+ return UtilsBridge.writeFileFromIS(destFile.getAbsolutePath(), new FileInputStream(srcFile))
&& !(isMove && !deleteFile(srcFile));
} catch (FileNotFoundException e) {
e.printStackTrace();
@@ -496,7 +508,7 @@ private static boolean deleteDir(final File dir) {
// dir isn't a directory then return false
if (!dir.isDirectory()) return false;
File[] files = dir.listFiles();
- if (files != null && files.length != 0) {
+ if (files != null && files.length > 0) {
for (File file : files) {
if (file.isFile()) {
if (!file.delete()) return false;
@@ -639,7 +651,7 @@ public static List listFilesInDir(final File dir) {
* @return the files in directory
*/
public static List listFilesInDir(final String dirPath, Comparator comparator) {
- return listFilesInDir(getFileByPath(dirPath), false);
+ return listFilesInDir(getFileByPath(dirPath), false, comparator);
}
/**
@@ -836,7 +848,7 @@ private static List listFilesInDirWithFilterInner(final File dir,
List list = new ArrayList<>();
if (!isDir(dir)) return list;
File[] files = dir.listFiles();
- if (files != null && files.length != 0) {
+ if (files != null && files.length > 0) {
for (File file : files) {
if (filter.accept(file)) {
list.add(file);
@@ -1111,7 +1123,7 @@ public static String getSize(final File file) {
*/
private static String getDirSize(final File dir) {
long len = getDirLength(dir);
- return len == -1 ? "" : byte2FitMemorySize(len);
+ return len == -1 ? "" : UtilsBridge.byte2FitMemorySize(len);
}
/**
@@ -1122,7 +1134,7 @@ private static String getDirSize(final File dir) {
*/
private static String getFileSize(final File file) {
long len = getFileLength(file);
- return len == -1 ? "" : byte2FitMemorySize(len);
+ return len == -1 ? "" : UtilsBridge.byte2FitMemorySize(len);
}
/**
@@ -1156,10 +1168,10 @@ public static long getLength(final File file) {
* @return the length of directory
*/
private static long getDirLength(final File dir) {
- if (!isDir(dir)) return -1;
+ if (!isDir(dir)) return 0;
long len = 0;
File[] files = dir.listFiles();
- if (files != null && files.length != 0) {
+ if (files != null && files.length > 0) {
for (File file : files) {
if (file.isDirectory()) {
len += getDirLength(file);
@@ -1213,7 +1225,7 @@ private static long getFileLength(final File file) {
* @return the md5 of file
*/
public static String getFileMD5ToString(final String filePath) {
- File file = isSpace(filePath) ? null : new File(filePath);
+ File file = UtilsBridge.isSpace(filePath) ? null : new File(filePath);
return getFileMD5ToString(file);
}
@@ -1224,7 +1236,7 @@ public static String getFileMD5ToString(final String filePath) {
* @return the md5 of file
*/
public static String getFileMD5ToString(final File file) {
- return bytes2HexString(getFileMD5(file));
+ return UtilsBridge.bytes2HexString(getFileMD5(file));
}
/**
@@ -1288,7 +1300,7 @@ public static String getDirName(final File file) {
* @return the file's path of directory
*/
public static String getDirName(final String filePath) {
- if (isSpace(filePath)) return "";
+ if (UtilsBridge.isSpace(filePath)) return "";
int lastSep = filePath.lastIndexOf(File.separator);
return lastSep == -1 ? "" : filePath.substring(0, lastSep + 1);
}
@@ -1311,7 +1323,7 @@ public static String getFileName(final File file) {
* @return the name of file
*/
public static String getFileName(final String filePath) {
- if (isSpace(filePath)) return "";
+ if (UtilsBridge.isSpace(filePath)) return "";
int lastSep = filePath.lastIndexOf(File.separator);
return lastSep == -1 ? filePath : filePath.substring(lastSep + 1);
}
@@ -1334,7 +1346,7 @@ public static String getFileNameNoExtension(final File file) {
* @return the name of file without extension
*/
public static String getFileNameNoExtension(final String filePath) {
- if (isSpace(filePath)) return "";
+ if (UtilsBridge.isSpace(filePath)) return "";
int lastPoi = filePath.lastIndexOf('.');
int lastSep = filePath.lastIndexOf(File.separator);
if (lastSep == -1) {
@@ -1364,13 +1376,22 @@ public static String getFileExtension(final File file) {
* @return the extension of file
*/
public static String getFileExtension(final String filePath) {
- if (isSpace(filePath)) return "";
+ if (UtilsBridge.isSpace(filePath)) return "";
int lastPoi = filePath.lastIndexOf('.');
int lastSep = filePath.lastIndexOf(File.separator);
if (lastPoi == -1 || lastSep >= lastPoi) return "";
return filePath.substring(lastPoi + 1);
}
+ /**
+ * Notify system to scan the file.
+ *
+ * @param filePath The path of file.
+ */
+ public static void notifySystemToScan(final String filePath) {
+ notifySystemToScan(getFileByPath(filePath));
+ }
+
/**
* Notify system to scan the file.
*
@@ -1379,18 +1400,50 @@ public static String getFileExtension(final String filePath) {
public static void notifySystemToScan(final File file) {
if (file == null || !file.exists()) return;
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
- Uri uri = Uri.fromFile(file);
- intent.setData(uri);
+ intent.setData(Uri.parse("file://" + file.getAbsolutePath()));
Utils.getApp().sendBroadcast(intent);
}
/**
- * Notify system to scan the file.
+ * Return the total size of file system.
*
- * @param filePath The path of file.
+ * @param anyPathInFs Any path in file system.
+ * @return the total size of file system
*/
- public static void notifySystemToScan(final String filePath) {
- notifySystemToScan(getFileByPath(filePath));
+ public static long getFsTotalSize(String anyPathInFs) {
+ if (TextUtils.isEmpty(anyPathInFs)) return 0;
+ StatFs statFs = new StatFs(anyPathInFs);
+ long blockSize;
+ long totalSize;
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
+ blockSize = statFs.getBlockSizeLong();
+ totalSize = statFs.getBlockCountLong();
+ } else {
+ blockSize = statFs.getBlockSize();
+ totalSize = statFs.getBlockCount();
+ }
+ return blockSize * totalSize;
+ }
+
+ /**
+ * Return the available size of file system.
+ *
+ * @param anyPathInFs Any path in file system.
+ * @return the available size of file system
+ */
+ public static long getFsAvailableSize(final String anyPathInFs) {
+ if (TextUtils.isEmpty(anyPathInFs)) return 0;
+ StatFs statFs = new StatFs(anyPathInFs);
+ long blockSize;
+ long availableSize;
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
+ blockSize = statFs.getBlockSizeLong();
+ availableSize = statFs.getAvailableBlocksLong();
+ } else {
+ blockSize = statFs.getBlockSize();
+ availableSize = statFs.getAvailableBlocks();
+ }
+ return blockSize * availableSize;
}
///////////////////////////////////////////////////////////////////////////
@@ -1400,77 +1453,4 @@ public static void notifySystemToScan(final String filePath) {
public interface OnReplaceListener {
boolean onReplace(File srcFile, File destFile);
}
-
- ///////////////////////////////////////////////////////////////////////////
- // other utils methods
- ///////////////////////////////////////////////////////////////////////////
-
- private static final char[] HEX_DIGITS =
- {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
-
- private static String bytes2HexString(final byte[] bytes) {
- if (bytes == null) return "";
- int len = bytes.length;
- if (len <= 0) return "";
- char[] ret = new char[len << 1];
- for (int i = 0, j = 0; i < len; i++) {
- ret[j++] = HEX_DIGITS[bytes[i] >> 4 & 0x0f];
- ret[j++] = HEX_DIGITS[bytes[i] & 0x0f];
- }
- return new String(ret);
- }
-
- private static String byte2FitMemorySize(final long byteNum) {
- if (byteNum < 0) {
- return "shouldn't be less than zero!";
- } else if (byteNum < 1024) {
- return String.format(Locale.getDefault(), "%.3fB", (double) byteNum);
- } else if (byteNum < 1048576) {
- return String.format(Locale.getDefault(), "%.3fKB", (double) byteNum / 1024);
- } else if (byteNum < 1073741824) {
- return String.format(Locale.getDefault(), "%.3fMB", (double) byteNum / 1048576);
- } else {
- return String.format(Locale.getDefault(), "%.3fGB", (double) byteNum / 1073741824);
- }
- }
-
- private static boolean isSpace(final String s) {
- if (s == null) return true;
- for (int i = 0, len = s.length(); i < len; ++i) {
- if (!Character.isWhitespace(s.charAt(i))) {
- return false;
- }
- }
- return true;
- }
-
- private static boolean writeFileFromIS(final File file,
- final InputStream is) {
- OutputStream os = null;
- try {
- os = new BufferedOutputStream(new FileOutputStream(file));
- byte[] data = new byte[8192];
- int len;
- while ((len = is.read(data, 0, 8192)) != -1) {
- os.write(data, 0, len);
- }
- return true;
- } catch (IOException e) {
- e.printStackTrace();
- return false;
- } finally {
- try {
- is.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- try {
- if (os != null) {
- os.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
}
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/FlashlightUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/FlashlightUtils.java
index 1b864f6ef5..e74996d4e4 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/FlashlightUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/FlashlightUtils.java
@@ -65,7 +65,7 @@ public static void setFlashlightStatus(final boolean isOn) {
parameters.setFlashMode(FLASH_MODE_TORCH);
mCamera.setParameters(parameters);
} catch (IOException e) {
- Log.e("FlashlightUtils", "setFlashlightStatusOn: ", e);
+ e.printStackTrace();
}
}
} else {
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/FragmentUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/FragmentUtils.java
index b6c9615309..31bbac1217 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/FragmentUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/FragmentUtils.java
@@ -3,23 +3,25 @@
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
-import android.support.annotation.AnimRes;
-import android.support.annotation.AnimatorRes;
-import android.support.annotation.ColorInt;
-import android.support.annotation.DrawableRes;
-import android.support.annotation.IdRes;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.View;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import androidx.annotation.AnimRes;
+import androidx.annotation.AnimatorRes;
+import androidx.annotation.ColorInt;
+import androidx.annotation.DrawableRes;
+import androidx.annotation.IdRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
+
/**
*
* author: Blankj
@@ -301,7 +303,7 @@ public static void add(@NonNull final FragmentManager fm,
final boolean isHide,
final boolean isAddStack) {
putArgs(add, new Args(containerId, tag, isHide, isAddStack));
- operateNoAnim(fm, TYPE_ADD_FRAGMENT, null, add);
+ operateNoAnim(TYPE_ADD_FRAGMENT, fm, null, add);
}
/**
@@ -489,7 +491,7 @@ public static void add(@NonNull final FragmentManager fm,
putArgs(adds[i], new Args(containerId, tags[i], showIndex != i, false));
}
}
- operateNoAnim(fm, TYPE_ADD_FRAGMENT, null, adds);
+ operateNoAnim(TYPE_ADD_FRAGMENT, fm, null, adds);
}
/**
@@ -499,7 +501,7 @@ public static void add(@NonNull final FragmentManager fm,
*/
public static void show(@NonNull final Fragment show) {
putArgs(show, false);
- operateNoAnim(show.getFragmentManager(), TYPE_SHOW_FRAGMENT, null, show);
+ operateNoAnim(TYPE_SHOW_FRAGMENT, show.getFragmentManager(), null, show);
}
/**
@@ -512,11 +514,7 @@ public static void show(@NonNull final FragmentManager fm) {
for (Fragment show : fragments) {
putArgs(show, false);
}
- operateNoAnim(fm,
- TYPE_SHOW_FRAGMENT,
- null,
- fragments.toArray(new Fragment[0])
- );
+ operateNoAnim(TYPE_SHOW_FRAGMENT, fm, null, fragments.toArray(new Fragment[0]));
}
/**
@@ -526,7 +524,7 @@ public static void show(@NonNull final FragmentManager fm) {
*/
public static void hide(@NonNull final Fragment hide) {
putArgs(hide, true);
- operateNoAnim(hide.getFragmentManager(), TYPE_HIDE_FRAGMENT, null, hide);
+ operateNoAnim(TYPE_HIDE_FRAGMENT, hide.getFragmentManager(), null, hide);
}
/**
@@ -539,21 +537,28 @@ public static void hide(@NonNull final FragmentManager fm) {
for (Fragment hide : fragments) {
putArgs(hide, true);
}
- operateNoAnim(fm,
- TYPE_HIDE_FRAGMENT,
- null,
- fragments.toArray(new Fragment[0])
- );
+ operateNoAnim(TYPE_HIDE_FRAGMENT, fm, null, fragments.toArray(new Fragment[0]));
+ }
+
+ /**
+ * Show fragment then hide other fragment.
+ *
+ * @param show The fragment will be show.
+ * @param hide The fragment will be hide.
+ */
+ public static void showHide(@NonNull final Fragment show,
+ @NonNull final Fragment hide) {
+ showHide(show, Collections.singletonList(hide));
}
/**
* Show fragment then hide other fragment.
*
* @param showIndex The index of fragment will be shown.
- * @param fragments The fragments will be hide.
+ * @param fragments The fragment will be hide.
*/
- public static void showHide(final int showIndex, @NonNull final List fragments) {
- showHide(fragments.get(showIndex), fragments);
+ public static void showHide(final int showIndex, @NonNull final Fragment... fragments) {
+ showHide(fragments[showIndex], fragments);
}
/**
@@ -562,22 +567,18 @@ public static void showHide(final int showIndex, @NonNull final List f
* @param show The fragment will be show.
* @param hide The fragment will be hide.
*/
- public static void showHide(@NonNull final Fragment show, @NonNull final List hide) {
- for (Fragment fragment : hide) {
- putArgs(fragment, fragment != show);
- }
- operateNoAnim(show.getFragmentManager(), TYPE_SHOW_HIDE_FRAGMENT, show,
- hide.toArray(new Fragment[0]));
+ public static void showHide(@NonNull final Fragment show, @NonNull final Fragment... hide) {
+ showHide(show, Arrays.asList(hide));
}
/**
* Show fragment then hide other fragment.
*
* @param showIndex The index of fragment will be shown.
- * @param fragments The fragment will be hide.
+ * @param fragments The fragments will be hide.
*/
- public static void showHide(final int showIndex, @NonNull final Fragment... fragments) {
- showHide(fragments[showIndex], fragments);
+ public static void showHide(final int showIndex, @NonNull final List fragments) {
+ showHide(fragments.get(showIndex), fragments);
}
/**
@@ -586,13 +587,14 @@ public static void showHide(final int showIndex, @NonNull final Fragment... frag
* @param show The fragment will be show.
* @param hide The fragment will be hide.
*/
- public static void showHide(@NonNull final Fragment show, @NonNull final Fragment... hide) {
+ public static void showHide(@NonNull final Fragment show, @NonNull final List hide) {
for (Fragment fragment : hide) {
putArgs(fragment, fragment != show);
}
- operateNoAnim(show.getFragmentManager(), TYPE_SHOW_HIDE_FRAGMENT, show, hide);
+ operateNoAnim(TYPE_SHOW_HIDE_FRAGMENT, show.getFragmentManager(), show, hide.toArray(new Fragment[0]));
}
+
/**
* Show fragment then hide other fragment.
*
@@ -600,10 +602,47 @@ public static void showHide(@NonNull final Fragment show, @NonNull final Fragmen
* @param hide The fragment will be hide.
*/
public static void showHide(@NonNull final Fragment show,
- @NonNull final Fragment hide) {
- putArgs(show, false);
- putArgs(hide, true);
- operateNoAnim(show.getFragmentManager(), TYPE_SHOW_HIDE_FRAGMENT, show, hide);
+ @NonNull final Fragment hide, @AnimatorRes @AnimRes final int enterAnim,
+ @AnimatorRes @AnimRes final int exitAnim,
+ @AnimatorRes @AnimRes final int popEnterAnim,
+ @AnimatorRes @AnimRes final int popExitAnim) {
+ showHide(show, Collections.singletonList(hide), enterAnim, exitAnim, popEnterAnim, popExitAnim);
+ }
+
+ /**
+ * Show fragment then hide other fragment.
+ *
+ * @param showIndex The index of fragment will be shown.
+ * @param fragments The fragments will be hide.
+ */
+ public static void showHide(final int showIndex, @NonNull final List fragments,
+ @AnimatorRes @AnimRes final int enterAnim,
+ @AnimatorRes @AnimRes final int exitAnim,
+ @AnimatorRes @AnimRes final int popEnterAnim,
+ @AnimatorRes @AnimRes final int popExitAnim) {
+ showHide(fragments.get(showIndex), fragments, enterAnim, exitAnim, popEnterAnim, popExitAnim);
+ }
+
+ /**
+ * Show fragment then hide other fragment.
+ *
+ * @param show The fragment will be show.
+ * @param hide The fragment will be hide.
+ */
+ public static void showHide(@NonNull final Fragment show, @NonNull final List hide,
+ @AnimatorRes @AnimRes final int enterAnim,
+ @AnimatorRes @AnimRes final int exitAnim,
+ @AnimatorRes @AnimRes final int popEnterAnim,
+ @AnimatorRes @AnimRes final int popExitAnim) {
+ for (Fragment fragment : hide) {
+ putArgs(fragment, fragment != show);
+ }
+ FragmentManager fm = show.getFragmentManager();
+ if (fm != null) {
+ FragmentTransaction ft = fm.beginTransaction();
+ addAnim(ft, enterAnim, exitAnim, popEnterAnim, popExitAnim);
+ operate(TYPE_SHOW_HIDE_FRAGMENT, fm, ft, show, hide.toArray(new Fragment[0]));
+ }
}
/**
@@ -1357,7 +1396,7 @@ public static void popAll(@NonNull final FragmentManager fm, final boolean isImm
* @param remove The fragment will be removed.
*/
public static void remove(@NonNull final Fragment remove) {
- operateNoAnim(remove.getFragmentManager(), TYPE_REMOVE_FRAGMENT, null, remove);
+ operateNoAnim(TYPE_REMOVE_FRAGMENT, remove.getFragmentManager(), null, remove);
}
/**
@@ -1367,8 +1406,7 @@ public static void remove(@NonNull final Fragment remove) {
* @param isIncludeSelf True to include the fragment, false otherwise.
*/
public static void removeTo(@NonNull final Fragment removeTo, final boolean isIncludeSelf) {
- operateNoAnim(removeTo.getFragmentManager(), TYPE_REMOVE_TO_FRAGMENT,
- isIncludeSelf ? removeTo : null, removeTo);
+ operateNoAnim(TYPE_REMOVE_TO_FRAGMENT, removeTo.getFragmentManager(), isIncludeSelf ? removeTo : null, removeTo);
}
/**
@@ -1378,11 +1416,7 @@ public static void removeTo(@NonNull final Fragment removeTo, final boolean isIn
*/
public static void removeAll(@NonNull final FragmentManager fm) {
List fragments = getFragments(fm);
- operateNoAnim(fm,
- TYPE_REMOVE_FRAGMENT,
- null,
- fragments.toArray(new Fragment[0])
- );
+ operateNoAnim(TYPE_REMOVE_FRAGMENT, fm, null, fragments.toArray(new Fragment[0]));
}
private static void putArgs(final Fragment fragment, final Args args) {
@@ -1414,8 +1448,7 @@ private static Args getArgs(final Fragment fragment) {
bundle.getBoolean(ARGS_IS_ADD_STACK));
}
- private static void operateNoAnim(@Nullable final FragmentManager fm,
- final int type,
+ private static void operateNoAnim(final int type, @Nullable final FragmentManager fm,
final Fragment src,
Fragment... dest) {
if (fm == null) return;
@@ -1493,6 +1526,7 @@ private static void operate(final int type,
break;
}
ft.commitAllowingStateLoss();
+ fm.executePendingTransactions();
}
private static void addAnim(final FragmentTransaction ft,
@@ -1542,14 +1576,14 @@ private static Fragment getTopIsInStack(@NonNull final FragmentManager fm,
if (isInStack) {
Bundle args = fragment.getArguments();
if (args != null && args.getBoolean(ARGS_IS_ADD_STACK)) {
- return getTopIsInStack(fragment.getChildFragmentManager(), parentFragment, true);
+ return getTopIsInStack(fragment.getChildFragmentManager(), fragment, true);
}
} else {
- return getTopIsInStack(fragment.getChildFragmentManager(), parentFragment, false);
+ return getTopIsInStack(fragment.getChildFragmentManager(), fragment, false);
}
}
}
- return null;
+ return parentFragment;
}
/**
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/GsonUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/GsonUtils.java
index 2951f9797f..c3eb0684c6 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/GsonUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/GsonUtils.java
@@ -1,5 +1,7 @@
package com.blankj.utilcode.util;
+import android.text.TextUtils;
+
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
@@ -9,6 +11,9 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import androidx.annotation.NonNull;
/**
@@ -21,31 +26,58 @@
*/
public final class GsonUtils {
- private static final Gson GSON = createGson(true);
+ private static final String KEY_DEFAULT = "defaultGson";
+ private static final String KEY_DELEGATE = "delegateGson";
+ private static final String KEY_LOG_UTILS = "logUtilsGson";
- private static final Gson GSON_NO_NULLS = createGson(false);
+ private static final Map GSONS = new ConcurrentHashMap<>();
private GsonUtils() {
throw new UnsupportedOperationException("u can't instantiate me...");
}
/**
- * Gets pre-configured {@link Gson} instance.
+ * Set the delegate of {@link Gson}.
*
- * @return {@link Gson} instance.
+ * @param delegate The delegate of {@link Gson}.
*/
- public static Gson getGson() {
- return getGson(true);
+ public static void setGsonDelegate(Gson delegate) {
+ if (delegate == null) return;
+ GSONS.put(KEY_DELEGATE, delegate);
}
/**
- * Gets pre-configured {@link Gson} instance.
+ * Set the {@link Gson} with key.
*
- * @param serializeNulls Determines if nulls will be serialized.
- * @return {@link Gson} instance.
+ * @param key The key.
+ * @param gson The {@link Gson}.
*/
- public static Gson getGson(final boolean serializeNulls) {
- return serializeNulls ? GSON_NO_NULLS : GSON;
+ public static void setGson(final String key, final Gson gson) {
+ if (TextUtils.isEmpty(key) || gson == null) return;
+ GSONS.put(key, gson);
+ }
+
+ /**
+ * Return the {@link Gson} with key.
+ *
+ * @param key The key.
+ * @return the {@link Gson} with key
+ */
+ public static Gson getGson(final String key) {
+ return GSONS.get(key);
+ }
+
+ public static Gson getGson() {
+ Gson gsonDelegate = GSONS.get(KEY_DELEGATE);
+ if (gsonDelegate != null) {
+ return gsonDelegate;
+ }
+ Gson gsonDefault = GSONS.get(KEY_DEFAULT);
+ if (gsonDefault == null) {
+ gsonDefault = createGson();
+ GSONS.put(KEY_DEFAULT, gsonDefault);
+ }
+ return gsonDefault;
}
/**
@@ -55,86 +87,133 @@ public static Gson getGson(final boolean serializeNulls) {
* @return object serialized into json.
*/
public static String toJson(final Object object) {
- return toJson(object, true);
+ return toJson(getGson(), object);
}
/**
* Serializes an object into json.
*
- * @param object The object to serialize.
- * @param includeNulls Determines if nulls will be included.
+ * @param src The object to serialize.
+ * @param typeOfSrc The specific genericized type of src.
* @return object serialized into json.
*/
- public static String toJson(final Object object, final boolean includeNulls) {
- return includeNulls ? GSON.toJson(object) : GSON_NO_NULLS.toJson(object);
+ public static String toJson(final Object src, @NonNull final Type typeOfSrc) {
+ return toJson(getGson(), src, typeOfSrc);
}
/**
* Serializes an object into json.
*
- * @param src The object to serialize.
- * @param typeOfSrc The specific genericized type of src.
+ * @param gson The gson.
+ * @param object The object to serialize.
* @return object serialized into json.
*/
- public static String toJson(final Object src, final Type typeOfSrc) {
- return toJson(src, typeOfSrc, true);
+ public static String toJson(@NonNull final Gson gson, final Object object) {
+ return gson.toJson(object);
}
/**
* Serializes an object into json.
*
- * @param src The object to serialize.
- * @param typeOfSrc The specific genericized type of src.
- * @param includeNulls Determines if nulls will be included.
+ * @param gson The gson.
+ * @param src The object to serialize.
+ * @param typeOfSrc The specific genericized type of src.
* @return object serialized into json.
*/
- public static String toJson(final Object src, final Type typeOfSrc, final boolean includeNulls) {
- return includeNulls ? GSON.toJson(src, typeOfSrc) : GSON_NO_NULLS.toJson(src, typeOfSrc);
+ public static String toJson(@NonNull final Gson gson, final Object src, @NonNull final Type typeOfSrc) {
+ return gson.toJson(src, typeOfSrc);
+ }
+
+ /**
+ * Converts {@link String} to given type.
+ *
+ * @param json The json to convert.
+ * @param type Type json will be converted to.
+ * @return instance of type
+ */
+ public static T fromJson(final String json, @NonNull final Class type) {
+ return fromJson(getGson(), json, type);
+ }
+
+ /**
+ * Converts {@link String} to given type.
+ *
+ * @param json the json to convert.
+ * @param type type type json will be converted to.
+ * @return instance of type
+ */
+ public static T fromJson(final String json, @NonNull final Type type) {
+ return fromJson(getGson(), json, type);
}
+ /**
+ * Converts {@link Reader} to given type.
+ *
+ * @param reader the reader to convert.
+ * @param type type type json will be converted to.
+ * @return instance of type
+ */
+ public static T fromJson(@NonNull final Reader reader, @NonNull final Class type) {
+ return fromJson(getGson(), reader, type);
+ }
+
+ /**
+ * Converts {@link Reader} to given type.
+ *
+ * @param reader the reader to convert.
+ * @param type type type json will be converted to.
+ * @return instance of type
+ */
+ public static T fromJson(@NonNull final Reader reader, @NonNull final Type type) {
+ return fromJson(getGson(), reader, type);
+ }
/**
* Converts {@link String} to given type.
*
+ * @param gson The gson.
* @param json The json to convert.
* @param type Type json will be converted to.
* @return instance of type
*/
- public static T fromJson(final String json, final Class type) {
- return GSON.fromJson(json, type);
+ public static T fromJson(@NonNull final Gson gson, final String json, @NonNull final Class type) {
+ return gson.fromJson(json, type);
}
/**
* Converts {@link String} to given type.
*
+ * @param gson The gson.
* @param json the json to convert.
* @param type type type json will be converted to.
* @return instance of type
*/
- public static T fromJson(final String json, final Type type) {
- return GSON.fromJson(json, type);
+ public static T fromJson(@NonNull final Gson gson, final String json, @NonNull final Type type) {
+ return gson.fromJson(json, type);
}
/**
* Converts {@link Reader} to given type.
*
+ * @param gson The gson.
* @param reader the reader to convert.
* @param type type type json will be converted to.
* @return instance of type
*/
- public static T fromJson(final Reader reader, final Class type) {
- return GSON.fromJson(reader, type);
+ public static T fromJson(@NonNull final Gson gson, final Reader reader, @NonNull final Class type) {
+ return gson.fromJson(reader, type);
}
/**
* Converts {@link Reader} to given type.
*
+ * @param gson The gson.
* @param reader the reader to convert.
* @param type type type json will be converted to.
* @return instance of type
*/
- public static T fromJson(final Reader reader, final Type type) {
- return GSON.fromJson(reader, type);
+ public static T fromJson(@NonNull final Gson gson, final Reader reader, @NonNull final Type type) {
+ return gson.fromJson(reader, type);
}
/**
@@ -143,7 +222,7 @@ public static T fromJson(final Reader reader, final Type type) {
* @param type The type.
* @return the type of {@link List} with the {@code type}
*/
- public static Type getListType(final Type type) {
+ public static Type getListType(@NonNull final Type type) {
return TypeToken.getParameterized(List.class, type).getType();
}
@@ -153,7 +232,7 @@ public static Type getListType(final Type type) {
* @param type The type.
* @return the type of {@link Set} with the {@code type}
*/
- public static Type getSetType(final Type type) {
+ public static Type getSetType(@NonNull final Type type) {
return TypeToken.getParameterized(Set.class, type).getType();
}
@@ -164,7 +243,7 @@ public static Type getSetType(final Type type) {
* @param valueType The type of value.
* @return the type of map with the {@code keyType} and {@code valueType}
*/
- public static Type getMapType(final Type keyType, final Type valueType) {
+ public static Type getMapType(@NonNull final Type keyType, @NonNull final Type valueType) {
return TypeToken.getParameterized(Map.class, keyType, valueType).getType();
}
@@ -174,7 +253,7 @@ public static Type getMapType(final Type keyType, final Type valueType) {
* @param type The type.
* @return the type of map with the {@code type}
*/
- public static Type getArrayType(final Type type) {
+ public static Type getArrayType(@NonNull final Type type) {
return TypeToken.getArray(type).getType();
}
@@ -185,19 +264,20 @@ public static Type getArrayType(final Type type) {
* @param typeArguments The type of arguments.
* @return the type of map with the {@code type}
*/
- public static Type getType(final Type rawType, final Type... typeArguments) {
+ public static Type getType(@NonNull final Type rawType, @NonNull final Type... typeArguments) {
return TypeToken.getParameterized(rawType, typeArguments).getType();
}
- /**
- * Create a pre-configured {@link Gson} instance.
- *
- * @param serializeNulls determines if nulls will be serialized.
- * @return {@link Gson} instance.
- */
- private static Gson createGson(final boolean serializeNulls) {
- final GsonBuilder builder = new GsonBuilder();
- if (serializeNulls) builder.serializeNulls();
- return builder.create();
+ static Gson getGson4LogUtils() {
+ Gson gson4LogUtils = GSONS.get(KEY_LOG_UTILS);
+ if (gson4LogUtils == null) {
+ gson4LogUtils = new GsonBuilder().setPrettyPrinting().serializeNulls().create();
+ GSONS.put(KEY_LOG_UTILS, gson4LogUtils);
+ }
+ return gson4LogUtils;
+ }
+
+ private static Gson createGson() {
+ return new GsonBuilder().serializeNulls().disableHtmlEscaping().create();
}
}
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/ImageUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/ImageUtils.java
index c1b6c50f8f..e0d472428f 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/ImageUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/ImageUtils.java
@@ -1,5 +1,7 @@
package com.blankj.utilcode.util;
+import android.Manifest;
+import android.content.ContentValues;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
@@ -12,6 +14,7 @@
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
+import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
@@ -22,18 +25,16 @@
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.ExifInterface;
+import android.net.Uri;
import android.os.Build;
+import android.os.Environment;
+import android.provider.MediaStore;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicBlur;
-import android.support.annotation.ColorInt;
-import android.support.annotation.DrawableRes;
-import android.support.annotation.FloatRange;
-import android.support.annotation.IntRange;
-import android.support.annotation.NonNull;
-import android.support.annotation.RequiresApi;
-import android.support.v4.content.ContextCompat;
+import android.text.TextUtils;
+import android.util.Log;
import android.view.View;
import java.io.BufferedOutputStream;
@@ -46,6 +47,15 @@
import java.io.InputStream;
import java.io.OutputStream;
+import androidx.annotation.ColorInt;
+import androidx.annotation.DrawableRes;
+import androidx.annotation.FloatRange;
+import androidx.annotation.IntRange;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+import androidx.core.content.ContextCompat;
+
/**
*
* author: Blankj
@@ -64,13 +74,24 @@ private ImageUtils() {
* Bitmap to bytes.
*
* @param bitmap The bitmap.
- * @param format The format of bitmap.
* @return bytes
*/
- public static byte[] bitmap2Bytes(final Bitmap bitmap, final CompressFormat format) {
+ public static byte[] bitmap2Bytes(final Bitmap bitmap) {
+ return bitmap2Bytes(bitmap, CompressFormat.PNG, 100);
+ }
+
+ /**
+ * Bitmap to bytes.
+ *
+ * @param bitmap The bitmap.
+ * @param format The format of bitmap.
+ * @param quality The quality.
+ * @return bytes
+ */
+ public static byte[] bitmap2Bytes(@Nullable final Bitmap bitmap, @NonNull final CompressFormat format, int quality) {
if (bitmap == null) return null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
- bitmap.compress(format, 100, baos);
+ bitmap.compress(format, quality, baos);
return baos.toByteArray();
}
@@ -80,7 +101,7 @@ public static byte[] bitmap2Bytes(final Bitmap bitmap, final CompressFormat form
* @param bytes The bytes.
* @return bitmap
*/
- public static Bitmap bytes2Bitmap(final byte[] bytes) {
+ public static Bitmap bytes2Bitmap(@Nullable final byte[] bytes) {
return (bytes == null || bytes.length == 0)
? null
: BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
@@ -92,7 +113,8 @@ public static Bitmap bytes2Bitmap(final byte[] bytes) {
* @param drawable The drawable.
* @return bitmap
*/
- public static Bitmap drawable2Bitmap(final Drawable drawable) {
+ public static Bitmap drawable2Bitmap(@Nullable final Drawable drawable) {
+ if (drawable == null) return null;
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
if (bitmapDrawable.getBitmap() != null) {
@@ -124,10 +146,20 @@ public static Bitmap drawable2Bitmap(final Drawable drawable) {
* @param bitmap The bitmap.
* @return drawable
*/
- public static Drawable bitmap2Drawable(final Bitmap bitmap) {
+ public static Drawable bitmap2Drawable(@Nullable final Bitmap bitmap) {
return bitmap == null ? null : new BitmapDrawable(Utils.getApp().getResources(), bitmap);
}
+ /**
+ * Drawable to bytes.
+ *
+ * @param drawable The drawable.
+ * @return bytes
+ */
+ public static byte[] drawable2Bytes(@Nullable final Drawable drawable) {
+ return drawable == null ? null : bitmap2Bytes(drawable2Bitmap(drawable));
+ }
+
/**
* Drawable to bytes.
*
@@ -135,8 +167,8 @@ public static Drawable bitmap2Drawable(final Bitmap bitmap) {
* @param format The format of bitmap.
* @return bytes
*/
- public static byte[] drawable2Bytes(final Drawable drawable, final CompressFormat format) {
- return drawable == null ? null : bitmap2Bytes(drawable2Bitmap(drawable), format);
+ public static byte[] drawable2Bytes(final Drawable drawable, final CompressFormat format, int quality) {
+ return drawable == null ? null : bitmap2Bytes(drawable2Bitmap(drawable), format, quality);
}
/**
@@ -161,18 +193,24 @@ public static Bitmap view2Bitmap(final View view) {
boolean willNotCacheDrawing = view.willNotCacheDrawing();
view.setDrawingCacheEnabled(true);
view.setWillNotCacheDrawing(false);
- final Bitmap drawingCache = view.getDrawingCache();
+ Bitmap drawingCache = view.getDrawingCache();
Bitmap bitmap;
- if (null == drawingCache) {
+ if (null == drawingCache || drawingCache.isRecycled()) {
view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
view.buildDrawingCache();
- bitmap = Bitmap.createBitmap(view.getDrawingCache());
+ drawingCache = view.getDrawingCache();
+ if (null == drawingCache || drawingCache.isRecycled()) {
+ bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.RGB_565);
+ Canvas canvas = new Canvas(bitmap);
+ view.draw(canvas);
+ } else {
+ bitmap = Bitmap.createBitmap(drawingCache);
+ }
} else {
bitmap = Bitmap.createBitmap(drawingCache);
}
- view.destroyDrawingCache();
view.setWillNotCacheDrawing(willNotCacheDrawing);
view.setDrawingCacheEnabled(drawingCacheEnabled);
return bitmap;
@@ -214,7 +252,7 @@ public static Bitmap getBitmap(final File file, final int maxWidth, final int ma
* @return bitmap
*/
public static Bitmap getBitmap(final String filePath) {
- if (isSpace(filePath)) return null;
+ if (UtilsBridge.isSpace(filePath)) return null;
return BitmapFactory.decodeFile(filePath);
}
@@ -227,7 +265,7 @@ public static Bitmap getBitmap(final String filePath) {
* @return bitmap
*/
public static Bitmap getBitmap(final String filePath, final int maxWidth, final int maxHeight) {
- if (isSpace(filePath)) return null;
+ if (UtilsBridge.isSpace(filePath)) return null;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filePath, options);
@@ -257,8 +295,12 @@ public static Bitmap getBitmap(final InputStream is) {
*/
public static Bitmap getBitmap(final InputStream is, final int maxWidth, final int maxHeight) {
if (is == null) return null;
- byte[] bytes = input2Byte(is);
- return getBitmap(bytes, 0, maxWidth, maxHeight);
+ BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inJustDecodeBounds = true;
+ BitmapFactory.decodeStream(is, null, options);
+ options.inSampleSize = calculateInSampleSize(options, maxWidth, maxHeight);
+ options.inJustDecodeBounds = false;
+ return BitmapFactory.decodeStream(is, null, options);
}
/**
@@ -303,6 +345,9 @@ public static Bitmap getBitmap(final byte[] data,
*/
public static Bitmap getBitmap(@DrawableRes final int resId) {
Drawable drawable = ContextCompat.getDrawable(Utils.getApp(), resId);
+ if (drawable == null) {
+ return null;
+ }
Canvas canvas = new Canvas();
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight(),
@@ -753,11 +798,27 @@ public static Bitmap toRoundCorner(final Bitmap src,
*/
public static Bitmap toRoundCorner(final Bitmap src,
final float radius,
- @IntRange(from = 0) int borderSize,
+ @FloatRange(from = 0) float borderSize,
@ColorInt int borderColor) {
return toRoundCorner(src, radius, borderSize, borderColor, false);
}
+ /**
+ * Return the round corner bitmap.
+ *
+ * @param src The source of bitmap.
+ * @param radii Array of 8 values, 4 pairs of [X,Y] radii
+ * @param borderSize The size of border.
+ * @param borderColor The color of border.
+ * @return the round corner bitmap
+ */
+ public static Bitmap toRoundCorner(final Bitmap src,
+ final float[] radii,
+ @FloatRange(from = 0) float borderSize,
+ @ColorInt int borderColor) {
+ return toRoundCorner(src, radii, borderSize, borderColor, false);
+ }
+
/**
* Return the round corner bitmap.
*
@@ -770,7 +831,26 @@ public static Bitmap toRoundCorner(final Bitmap src,
*/
public static Bitmap toRoundCorner(final Bitmap src,
final float radius,
- @IntRange(from = 0) int borderSize,
+ @FloatRange(from = 0) float borderSize,
+ @ColorInt int borderColor,
+ final boolean recycle) {
+ float[] radii = {radius, radius, radius, radius, radius, radius, radius, radius};
+ return toRoundCorner(src, radii, borderSize, borderColor, recycle);
+ }
+
+ /**
+ * Return the round corner bitmap.
+ *
+ * @param src The source of bitmap.
+ * @param radii Array of 8 values, 4 pairs of [X,Y] radii
+ * @param borderSize The size of border.
+ * @param borderColor The color of border.
+ * @param recycle True to recycle the source of bitmap, false otherwise.
+ * @return the round corner bitmap
+ */
+ public static Bitmap toRoundCorner(final Bitmap src,
+ final float[] radii,
+ @FloatRange(from = 0) float borderSize,
@ColorInt int borderColor,
final boolean recycle) {
if (isEmptyBitmap(src)) return null;
@@ -784,14 +864,16 @@ public static Bitmap toRoundCorner(final Bitmap src,
RectF rectF = new RectF(0, 0, width, height);
float halfBorderSize = borderSize / 2f;
rectF.inset(halfBorderSize, halfBorderSize);
- canvas.drawRoundRect(rectF, radius, radius, paint);
+ Path path = new Path();
+ path.addRoundRect(rectF, radii, Path.Direction.CW);
+ canvas.drawPath(path, paint);
if (borderSize > 0) {
paint.setShader(null);
paint.setColor(borderColor);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(borderSize);
paint.setStrokeCap(Paint.Cap.ROUND);
- canvas.drawRoundRect(rectF, radius, radius, paint);
+ canvas.drawPath(path, paint);
}
if (recycle && !src.isRecycled() && ret != src) src.recycle();
return ret;
@@ -807,12 +889,46 @@ public static Bitmap toRoundCorner(final Bitmap src,
* @return the round corner bitmap with border
*/
public static Bitmap addCornerBorder(final Bitmap src,
- @IntRange(from = 1) final int borderSize,
+ @FloatRange(from = 1) final float borderSize,
@ColorInt final int color,
@FloatRange(from = 0) final float cornerRadius) {
return addBorder(src, borderSize, color, false, cornerRadius, false);
}
+ /**
+ * Return the round corner bitmap with border.
+ *
+ * @param src The source of bitmap.
+ * @param borderSize The size of border.
+ * @param color The color of border.
+ * @param radii Array of 8 values, 4 pairs of [X,Y] radii
+ * @return the round corner bitmap with border
+ */
+ public static Bitmap addCornerBorder(final Bitmap src,
+ @FloatRange(from = 1) final float borderSize,
+ @ColorInt final int color,
+ final float[] radii) {
+ return addBorder(src, borderSize, color, false, radii, false);
+ }
+
+ /**
+ * Return the round corner bitmap with border.
+ *
+ * @param src The source of bitmap.
+ * @param borderSize The size of border.
+ * @param color The color of border.
+ * @param radii Array of 8 values, 4 pairs of [X,Y] radii
+ * @param recycle True to recycle the source of bitmap, false otherwise.
+ * @return the round corner bitmap with border
+ */
+ public static Bitmap addCornerBorder(final Bitmap src,
+ @FloatRange(from = 1) final float borderSize,
+ @ColorInt final int color,
+ final float[] radii,
+ final boolean recycle) {
+ return addBorder(src, borderSize, color, false, radii, recycle);
+ }
+
/**
* Return the round corner bitmap with border.
*
@@ -824,7 +940,7 @@ public static Bitmap addCornerBorder(final Bitmap src,
* @return the round corner bitmap with border
*/
public static Bitmap addCornerBorder(final Bitmap src,
- @IntRange(from = 1) final int borderSize,
+ @FloatRange(from = 1) final float borderSize,
@ColorInt final int color,
@FloatRange(from = 0) final float cornerRadius,
final boolean recycle) {
@@ -840,7 +956,7 @@ public static Bitmap addCornerBorder(final Bitmap src,
* @return the round bitmap with border
*/
public static Bitmap addCircleBorder(final Bitmap src,
- @IntRange(from = 1) final int borderSize,
+ @FloatRange(from = 1) final float borderSize,
@ColorInt final int color) {
return addBorder(src, borderSize, color, true, 0, false);
}
@@ -855,7 +971,7 @@ public static Bitmap addCircleBorder(final Bitmap src,
* @return the round bitmap with border
*/
public static Bitmap addCircleBorder(final Bitmap src,
- @IntRange(from = 1) final int borderSize,
+ @FloatRange(from = 1) final float borderSize,
@ColorInt final int color,
final boolean recycle) {
return addBorder(src, borderSize, color, true, 0, recycle);
@@ -873,11 +989,33 @@ public static Bitmap addCircleBorder(final Bitmap src,
* @return the bitmap with border
*/
private static Bitmap addBorder(final Bitmap src,
- @IntRange(from = 1) final int borderSize,
+ @FloatRange(from = 1) final float borderSize,
@ColorInt final int color,
final boolean isCircle,
final float cornerRadius,
final boolean recycle) {
+ float[] radii = {cornerRadius, cornerRadius, cornerRadius, cornerRadius,
+ cornerRadius, cornerRadius, cornerRadius, cornerRadius};
+ return addBorder(src, borderSize, color, isCircle, radii, recycle);
+ }
+
+ /**
+ * Return the bitmap with border.
+ *
+ * @param src The source of bitmap.
+ * @param borderSize The size of border.
+ * @param color The color of border.
+ * @param isCircle True to draw circle, false to draw corner.
+ * @param radii Array of 8 values, 4 pairs of [X,Y] radii
+ * @param recycle True to recycle the source of bitmap, false otherwise.
+ * @return the bitmap with border
+ */
+ private static Bitmap addBorder(final Bitmap src,
+ @FloatRange(from = 1) final float borderSize,
+ @ColorInt final int color,
+ final boolean isCircle,
+ final float[] radii,
+ final boolean recycle) {
if (isEmptyBitmap(src)) return null;
Bitmap ret = recycle ? src : src.copy(src.getConfig(), true);
int width = ret.getWidth();
@@ -891,10 +1029,12 @@ private static Bitmap addBorder(final Bitmap src,
float radius = Math.min(width, height) / 2f - borderSize / 2f;
canvas.drawCircle(width / 2f, height / 2f, radius, paint);
} else {
- int halfBorderSize = borderSize >> 1;
- RectF rectF = new RectF(halfBorderSize, halfBorderSize,
- width - halfBorderSize, height - halfBorderSize);
- canvas.drawRoundRect(rectF, cornerRadius, cornerRadius, paint);
+ RectF rectF = new RectF(0, 0, width, height);
+ float halfBorderSize = borderSize / 2f;
+ rectF.inset(halfBorderSize, halfBorderSize);
+ Path path = new Path();
+ path.addRoundRect(rectF, radii, Path.Direction.CW);
+ canvas.drawPath(path, paint);
}
return ret;
}
@@ -1468,7 +1608,7 @@ public static Bitmap stackBlur(final Bitmap src, int radius, final boolean recyc
public static boolean save(final Bitmap src,
final String filePath,
final CompressFormat format) {
- return save(src, getFileByPath(filePath), format, false);
+ return save(src, filePath, format, 100, false);
}
/**
@@ -1480,7 +1620,7 @@ public static boolean save(final Bitmap src,
* @return {@code true}: success
{@code false}: fail
*/
public static boolean save(final Bitmap src, final File file, final CompressFormat format) {
- return save(src, file, format, false);
+ return save(src, file, format, 100, false);
}
/**
@@ -1496,7 +1636,7 @@ public static boolean save(final Bitmap src,
final String filePath,
final CompressFormat format,
final boolean recycle) {
- return save(src, getFileByPath(filePath), format, recycle);
+ return save(src, filePath, format, 100, recycle);
}
/**
@@ -1512,12 +1652,99 @@ public static boolean save(final Bitmap src,
final File file,
final CompressFormat format,
final boolean recycle) {
- if (isEmptyBitmap(src) || !createFileByDeleteOldFile(file)) return false;
+ return save(src, file, format, 100, recycle);
+ }
+
+ /**
+ * Save the bitmap.
+ *
+ * @param src The source of bitmap.
+ * @param filePath The path of file.
+ * @param format The format of the image.
+ * @param quality Hint to the compressor, 0-100. 0 meaning compress for
+ * small size, 100 meaning compress for max quality. Some
+ * formats, like PNG which is lossless, will ignore the
+ * quality setting
+ * @return {@code true}: success
{@code false}: fail
+ */
+ public static boolean save(final Bitmap src,
+ final String filePath,
+ final CompressFormat format,
+ final int quality) {
+ return save(src, UtilsBridge.getFileByPath(filePath), format, quality, false);
+ }
+
+ /**
+ * Save the bitmap.
+ *
+ * @param src The source of bitmap.
+ * @param file The file.
+ * @param format The format of the image.
+ * @return {@code true}: success
{@code false}: fail
+ */
+ public static boolean save(final Bitmap src,
+ final File file,
+ final CompressFormat format,
+ final int quality) {
+ return save(src, file, format, quality, false);
+ }
+
+ /**
+ * Save the bitmap.
+ *
+ * @param src The source of bitmap.
+ * @param filePath The path of file.
+ * @param format The format of the image.
+ * @param quality Hint to the compressor, 0-100. 0 meaning compress for
+ * small size, 100 meaning compress for max quality. Some
+ * formats, like PNG which is lossless, will ignore the
+ * quality setting
+ * @param recycle True to recycle the source of bitmap, false otherwise.
+ * @return {@code true}: success
{@code false}: fail
+ */
+ public static boolean save(final Bitmap src,
+ final String filePath,
+ final CompressFormat format,
+ final int quality,
+ final boolean recycle) {
+ return save(src, UtilsBridge.getFileByPath(filePath), format, quality, recycle);
+ }
+
+ /**
+ * Save the bitmap.
+ *
+ * @param src The source of bitmap.
+ * @param file The file.
+ * @param format The format of the image.
+ * @param quality Hint to the compressor, 0-100. 0 meaning compress for
+ * small size, 100 meaning compress for max quality. Some
+ * formats, like PNG which is lossless, will ignore the
+ * quality setting
+ * @param recycle True to recycle the source of bitmap, false otherwise.
+ * @return {@code true}: success
{@code false}: fail
+ */
+ public static boolean save(final Bitmap src,
+ final File file,
+ final CompressFormat format,
+ final int quality,
+ final boolean recycle) {
+ if (isEmptyBitmap(src)) {
+ Log.e("ImageUtils", "bitmap is empty.");
+ return false;
+ }
+ if (src.isRecycled()) {
+ Log.e("ImageUtils", "bitmap is recycled.");
+ return false;
+ }
+ if (!UtilsBridge.createFileByDeleteOldFile(file)) {
+ Log.e("ImageUtils", "create or delete file <" + file + "> failed.");
+ return false;
+ }
OutputStream os = null;
boolean ret = false;
try {
os = new BufferedOutputStream(new FileOutputStream(file));
- ret = src.compress(format, 100, os);
+ ret = src.compress(format, quality, os);
if (recycle && !src.isRecycled()) src.recycle();
} catch (IOException e) {
e.printStackTrace();
@@ -1533,6 +1760,184 @@ public static boolean save(final Bitmap src,
return ret;
}
+ /**
+ * @param src The source of bitmap.
+ * @param format The format of the image.
+ * @return the file if save success, otherwise return null.
+ */
+ @Nullable
+ public static File save2Album(final Bitmap src,
+ final CompressFormat format) {
+ return save2Album(src, "", format, 100, false);
+ }
+
+ /**
+ * @param src The source of bitmap.
+ * @param format The format of the image.
+ * @param recycle True to recycle the source of bitmap, false otherwise.
+ * @return the file if save success, otherwise return null.
+ */
+ @Nullable
+ public static File save2Album(final Bitmap src,
+ final CompressFormat format,
+ final boolean recycle) {
+ return save2Album(src, "", format, 100, recycle);
+ }
+
+ /**
+ * @param src The source of bitmap.
+ * @param format The format of the image.
+ * @param quality Hint to the compressor, 0-100. 0 meaning compress for
+ * small size, 100 meaning compress for max quality. Some
+ * formats, like PNG which is lossless, will ignore the
+ * quality setting
+ * @return the file if save success, otherwise return null.
+ */
+ @Nullable
+ public static File save2Album(final Bitmap src,
+ final CompressFormat format,
+ final int quality) {
+ return save2Album(src, "", format, quality, false);
+ }
+
+ /**
+ * @param src The source of bitmap.
+ * @param format The format of the image.
+ * @param quality Hint to the compressor, 0-100. 0 meaning compress for
+ * small size, 100 meaning compress for max quality. Some
+ * formats, like PNG which is lossless, will ignore the
+ * quality setting
+ * @param recycle True to recycle the source of bitmap, false otherwise.
+ * @return the file if save success, otherwise return null.
+ */
+ @Nullable
+ public static File save2Album(final Bitmap src,
+ final CompressFormat format,
+ final int quality,
+ final boolean recycle) {
+ return save2Album(src, "", format, quality, recycle);
+ }
+
+ /**
+ * @param src The source of bitmap.
+ * @param dirName The name of directory.
+ * @param format The format of the image.
+ * @return the file if save success, otherwise return null.
+ */
+ @Nullable
+ public static File save2Album(final Bitmap src,
+ final String dirName,
+ final CompressFormat format) {
+ return save2Album(src, dirName, format, 100, false);
+ }
+
+ /**
+ * @param src The source of bitmap.
+ * @param dirName The name of directory.
+ * @param format The format of the image.
+ * @param recycle True to recycle the source of bitmap, false otherwise.
+ * @return the file if save success, otherwise return null.
+ */
+ @Nullable
+ public static File save2Album(final Bitmap src,
+ final String dirName,
+ final CompressFormat format,
+ final boolean recycle) {
+ return save2Album(src, dirName, format, 100, recycle);
+ }
+
+ /**
+ * @param src The source of bitmap.
+ * @param dirName The name of directory.
+ * @param format The format of the image.
+ * @param quality Hint to the compressor, 0-100. 0 meaning compress for
+ * small size, 100 meaning compress for max quality. Some
+ * formats, like PNG which is lossless, will ignore the
+ * quality setting
+ * @return the file if save success, otherwise return null.
+ */
+ @Nullable
+ public static File save2Album(final Bitmap src,
+ final String dirName,
+ final CompressFormat format,
+ final int quality) {
+ return save2Album(src, dirName, format, quality, false);
+ }
+
+ /**
+ * @param src The source of bitmap.
+ * @param dirName The name of directory.
+ * @param format The format of the image.
+ * @param quality Hint to the compressor, 0-100. 0 meaning compress for
+ * small size, 100 meaning compress for max quality. Some
+ * formats, like PNG which is lossless, will ignore the
+ * quality setting
+ * @param recycle True to recycle the source of bitmap, false otherwise.
+ * @return the file if save success, otherwise return null.
+ */
+ @Nullable
+ public static File save2Album(final Bitmap src,
+ final String dirName,
+ final CompressFormat format,
+ final int quality,
+ final boolean recycle) {
+ String safeDirName = TextUtils.isEmpty(dirName) ? Utils.getApp().getPackageName() : dirName;
+ String suffix = CompressFormat.JPEG.equals(format) ? "JPG" : format.name();
+ String fileName = System.currentTimeMillis() + "_" + quality + "." + suffix;
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+ if (!UtilsBridge.isGranted(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
+ Log.e("ImageUtils", "save to album need storage permission");
+ return null;
+ }
+ File picDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
+ File destFile = new File(picDir, safeDirName + "/" + fileName);
+ if (!save(src, destFile, format, quality, recycle)) {
+ return null;
+ }
+ UtilsBridge.notifySystemToScan(destFile);
+ return destFile;
+ } else {
+ ContentValues contentValues = new ContentValues();
+ contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, fileName);
+ contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/*");
+ Uri contentUri;
+ if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+ contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
+ } else {
+ contentUri = MediaStore.Images.Media.INTERNAL_CONTENT_URI;
+ }
+ contentValues.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_DCIM + "/" + safeDirName);
+ contentValues.put(MediaStore.MediaColumns.IS_PENDING, 1);
+ Uri uri = Utils.getApp().getContentResolver().insert(contentUri, contentValues);
+ if (uri == null) {
+ return null;
+ }
+ OutputStream os = null;
+ try {
+ os = Utils.getApp().getContentResolver().openOutputStream(uri);
+ src.compress(format, quality, os);
+
+ contentValues.clear();
+ contentValues.put(MediaStore.MediaColumns.IS_PENDING, 0);
+ Utils.getApp().getContentResolver().update(uri, contentValues, null, null);
+
+ return UtilsBridge.uri2File(uri);
+ } catch (Exception e) {
+ Utils.getApp().getContentResolver().delete(uri, null, null);
+ e.printStackTrace();
+ return null;
+ } finally {
+ try {
+ if (os != null) {
+ os.close();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
/**
* Return whether it is a image according to the file name.
*
@@ -1553,11 +1958,11 @@ public static boolean isImage(final File file) {
* @return {@code true}: yes
{@code false}: no
*/
public static boolean isImage(final String filePath) {
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inJustDecodeBounds = true;
try {
- Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);
- return options.outWidth != -1 && options.outHeight != -1;
+ BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inJustDecodeBounds = true;
+ BitmapFactory.decodeFile(filePath, options);
+ return options.outWidth > 0 && options.outHeight > 0;
} catch (Exception e) {
return false;
}
@@ -1570,7 +1975,7 @@ public static boolean isImage(final String filePath) {
* @return the type of image
*/
public static ImageType getImageType(final String filePath) {
- return getImageType(getFileByPath(filePath));
+ return getImageType(UtilsBridge.getFileByPath(filePath));
}
/**
@@ -1614,7 +2019,7 @@ private static ImageType getImageType(final InputStream is) {
}
private static ImageType getImageType(final byte[] bytes) {
- String type = bytes2HexString(bytes).toUpperCase();
+ String type = UtilsBridge.bytes2HexString(bytes).toUpperCase();
if (type.contains("FFD8FF")) {
return ImageType.TYPE_JPG;
} else if (type.contains("89504E47")) {
@@ -1634,22 +2039,6 @@ private static ImageType getImageType(final byte[] bytes) {
}
}
- private static final char[] hexDigits =
- {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
-
- private static String bytes2HexString(final byte[] bytes) {
- if (bytes == null) return "";
- int len = bytes.length;
- if (len <= 0) return "";
- char[] ret = new char[len << 1];
- for (int i = 0, j = 0; i < len; i++) {
- ret[j++] = hexDigits[bytes[i] >> 4 & 0x0f];
- ret[j++] = hexDigits[bytes[i] & 0x0f];
- }
- return new String(ret);
- }
-
-
private static boolean isJPEG(final byte[] b) {
return b.length >= 2
&& (b[0] == (byte) 0xFF) && (b[1] == (byte) 0xD8);
@@ -1916,7 +2305,7 @@ public static Bitmap compressBySampleSize(final Bitmap src,
* @return the size of bitmap
*/
public static int[] getSize(String filePath) {
- return getSize(getFileByPath(filePath));
+ return getSize(UtilsBridge.getFileByPath(filePath));
}
/**
@@ -1942,8 +2331,8 @@ public static int[] getSize(File file) {
* @return the sample size
*/
public static int calculateInSampleSize(final BitmapFactory.Options options,
- final int maxWidth,
- final int maxHeight) {
+ final int maxWidth,
+ final int maxHeight) {
int height = options.outHeight;
int width = options.outWidth;
int inSampleSize = 1;
@@ -1955,62 +2344,6 @@ public static int calculateInSampleSize(final BitmapFactory.Options options,
return inSampleSize;
}
- ///////////////////////////////////////////////////////////////////////////
- // other utils methods
- ///////////////////////////////////////////////////////////////////////////
-
- private static File getFileByPath(final String filePath) {
- return isSpace(filePath) ? null : new File(filePath);
- }
-
- private static boolean createFileByDeleteOldFile(final File file) {
- if (file == null) return false;
- if (file.exists() && !file.delete()) return false;
- if (!createOrExistsDir(file.getParentFile())) return false;
- try {
- return file.createNewFile();
- } catch (IOException e) {
- e.printStackTrace();
- return false;
- }
- }
-
- private static boolean createOrExistsDir(final File file) {
- return file != null && (file.exists() ? file.isDirectory() : file.mkdirs());
- }
-
- private static boolean isSpace(final String s) {
- if (s == null) return true;
- for (int i = 0, len = s.length(); i < len; ++i) {
- if (!Character.isWhitespace(s.charAt(i))) {
- return false;
- }
- }
- return true;
- }
-
- private static byte[] input2Byte(final InputStream is) {
- if (is == null) return null;
- try {
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- byte[] b = new byte[1024];
- int len;
- while ((len = is.read(b, 0, 1024)) != -1) {
- os.write(b, 0, len);
- }
- return os.toByteArray();
- } catch (IOException e) {
- e.printStackTrace();
- return null;
- } finally {
- try {
- is.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
-
public enum ImageType {
TYPE_JPG("jpg"),
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/IntentUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/IntentUtils.java
index fc86d34a05..a5009c3cba 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/IntentUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/IntentUtils.java
@@ -8,14 +8,17 @@
import android.os.Bundle;
import android.provider.MediaStore;
import android.provider.Settings;
-import android.support.annotation.RequiresPermission;
-import android.support.v4.content.FileProvider;
import java.io.File;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresPermission;
+import androidx.core.content.FileProvider;
+
import static android.Manifest.permission.CALL_PHONE;
/**
@@ -54,7 +57,7 @@ public static boolean isIntentAvailable(final Intent intent) {
* @return the intent of install app
*/
public static Intent getInstallAppIntent(final String filePath) {
- return getInstallAppIntent(getFileByPath(filePath), false);
+ return getInstallAppIntent(UtilsBridge.getFileByPath(filePath));
}
/**
@@ -66,20 +69,15 @@ public static Intent getInstallAppIntent(final String filePath) {
* @return the intent of install app
*/
public static Intent getInstallAppIntent(final File file) {
- return getInstallAppIntent(file, false);
- }
-
- /**
- * Return the intent of install app.
- * Target APIs greater than 25 must hold
- * {@code }
- *
- * @param filePath The path of file.
- * @param isNewTask True to add flag of new task, false otherwise.
- * @return the intent of install app
- */
- public static Intent getInstallAppIntent(final String filePath, final boolean isNewTask) {
- return getInstallAppIntent(getFileByPath(filePath), isNewTask);
+ if (!UtilsBridge.isFileExists(file)) return null;
+ Uri uri;
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
+ uri = Uri.fromFile(file);
+ } else {
+ String authority = Utils.getApp().getPackageName() + ".utilcode.fileprovider";
+ uri = FileProvider.getUriForFile(Utils.getApp(), authority, file);
+ }
+ return getInstallAppIntent(uri);
}
/**
@@ -87,93 +85,68 @@ public static Intent getInstallAppIntent(final String filePath, final boolean is
* Target APIs greater than 25 must hold
* {@code }
*
- * @param file The file.
- * @param isNewTask True to add flag of new task, false otherwise.
+ * @param uri The uri.
* @return the intent of install app
*/
- public static Intent getInstallAppIntent(final File file, final boolean isNewTask) {
- if (file == null) return null;
+ public static Intent getInstallAppIntent(final Uri uri) {
+ if (uri == null) return null;
Intent intent = new Intent(Intent.ACTION_VIEW);
- Uri data;
String type = "application/vnd.android.package-archive";
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
- data = Uri.fromFile(file);
- } else {
+ intent.setDataAndType(uri, type);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- String authority = Utils.getApp().getPackageName() + ".utilcode.provider";
- data = FileProvider.getUriForFile(Utils.getApp(), authority, file);
}
- intent.setDataAndType(data, type);
- return getIntent(intent, isNewTask);
- }
-
- /**
- * Return the intent of uninstall app.
- *
- * @param packageName The name of the package.
- * @return the intent of uninstall app
- */
- public static Intent getUninstallAppIntent(final String packageName) {
- return getUninstallAppIntent(packageName, false);
+ return intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
/**
* Return the intent of uninstall app.
+ * Target APIs greater than 25 must hold
+ * Must hold {@code }
*
- * @param packageName The name of the package.
- * @param isNewTask True to add flag of new task, false otherwise.
+ * @param pkgName The name of the package.
* @return the intent of uninstall app
*/
- public static Intent getUninstallAppIntent(final String packageName, final boolean isNewTask) {
+ public static Intent getUninstallAppIntent(final String pkgName) {
Intent intent = new Intent(Intent.ACTION_DELETE);
- intent.setData(Uri.parse("package:" + packageName));
- return getIntent(intent, isNewTask);
+ intent.setData(Uri.parse("package:" + pkgName));
+ return intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
/**
* Return the intent of launch app.
*
- * @param packageName The name of the package.
+ * @param pkgName The name of the package.
* @return the intent of launch app
*/
- public static Intent getLaunchAppIntent(final String packageName) {
- return getLaunchAppIntent(packageName, false);
- }
-
- /**
- * Return the intent of launch app.
- *
- * @param packageName The name of the package.
- * @param isNewTask True to add flag of new task, false otherwise.
- * @return the intent of launch app
- */
- public static Intent getLaunchAppIntent(final String packageName, final boolean isNewTask) {
- Intent intent = Utils.getApp().getPackageManager().getLaunchIntentForPackage(packageName);
- if (intent == null) return null;
- return getIntent(intent, isNewTask);
+ public static Intent getLaunchAppIntent(final String pkgName) {
+ String launcherActivity = UtilsBridge.getLauncherActivity(pkgName);
+ if (UtilsBridge.isSpace(launcherActivity)) return null;
+ Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.addCategory(Intent.CATEGORY_LAUNCHER);
+ intent.setClassName(pkgName, launcherActivity);
+ return intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
/**
* Return the intent of launch app details settings.
*
- * @param packageName The name of the package.
+ * @param pkgName The name of the package.
* @return the intent of launch app details settings
*/
- public static Intent getLaunchAppDetailsSettingsIntent(final String packageName) {
- return getLaunchAppDetailsSettingsIntent(packageName, false);
+ public static Intent getLaunchAppDetailsSettingsIntent(final String pkgName) {
+ return getLaunchAppDetailsSettingsIntent(pkgName, false);
}
/**
* Return the intent of launch app details settings.
*
- * @param packageName The name of the package.
- * @param isNewTask True to add flag of new task, false otherwise.
+ * @param pkgName The name of the package.
* @return the intent of launch app details settings
*/
- public static Intent getLaunchAppDetailsSettingsIntent(final String packageName,
- final boolean isNewTask) {
+ public static Intent getLaunchAppDetailsSettingsIntent(final String pkgName, final boolean isNewTask) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
- intent.setData(Uri.parse("package:" + packageName));
+ intent.setData(Uri.parse("package:" + pkgName));
return getIntent(intent, isNewTask);
}
@@ -184,250 +157,223 @@ public static Intent getLaunchAppDetailsSettingsIntent(final String packageName,
* @return the intent of share text
*/
public static Intent getShareTextIntent(final String content) {
- return getShareTextIntent(content, false);
- }
-
- /**
- * Return the intent of share text.
- *
- * @param content The content.
- * @param isNewTask True to add flag of new task, false otherwise.
- * @return the intent of share text
- */
-
- public static Intent getShareTextIntent(final String content, final boolean isNewTask) {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, content);
- return getIntent(intent, isNewTask);
+ intent = Intent.createChooser(intent, "");
+ return getIntent(intent, true);
}
/**
* Return the intent of share image.
*
- * @param content The content.
* @param imagePath The path of image.
* @return the intent of share image
*/
- public static Intent getShareImageIntent(final String content, final String imagePath) {
- return getShareImageIntent(content, imagePath, false);
+ public static Intent getShareImageIntent(final String imagePath) {
+ return getShareTextImageIntent("", imagePath);
}
/**
* Return the intent of share image.
*
- * @param content The content.
- * @param imagePath The path of image.
- * @param isNewTask True to add flag of new task, false otherwise.
+ * @param imageFile The file of image.
* @return the intent of share image
*/
- public static Intent getShareImageIntent(final String content,
- final String imagePath,
- final boolean isNewTask) {
- if (imagePath == null || imagePath.length() == 0) return null;
- return getShareImageIntent(content, new File(imagePath), isNewTask);
+ public static Intent getShareImageIntent(final File imageFile) {
+ return getShareTextImageIntent("", imageFile);
}
/**
* Return the intent of share image.
*
- * @param content The content.
- * @param image The file of image.
+ * @param imageUri The uri of image.
* @return the intent of share image
*/
- public static Intent getShareImageIntent(final String content, final File image) {
- return getShareImageIntent(content, image, false);
+ public static Intent getShareImageIntent(final Uri imageUri) {
+ return getShareTextImageIntent("", imageUri);
}
/**
* Return the intent of share image.
*
* @param content The content.
- * @param image The file of image.
- * @param isNewTask True to add flag of new task, false otherwise.
+ * @param imagePath The path of image.
* @return the intent of share image
*/
- public static Intent getShareImageIntent(final String content,
- final File image,
- final boolean isNewTask) {
- if (image == null || !image.isFile()) return null;
- return getShareImageIntent(content, file2Uri(image), isNewTask);
+ public static Intent getShareTextImageIntent(@Nullable final String content, final String imagePath) {
+ return getShareTextImageIntent(content, UtilsBridge.getFileByPath(imagePath));
}
/**
* Return the intent of share image.
*
- * @param content The content.
- * @param uri The uri of image.
+ * @param content The content.
+ * @param imageFile The file of image.
* @return the intent of share image
*/
- public static Intent getShareImageIntent(final String content, final Uri uri) {
- return getShareImageIntent(content, uri, false);
+ public static Intent getShareTextImageIntent(@Nullable final String content, final File imageFile) {
+ return getShareTextImageIntent(content, UtilsBridge.file2Uri(imageFile));
}
/**
* Return the intent of share image.
*
- * @param content The content.
- * @param uri The uri of image.
- * @param isNewTask True to add flag of new task, false otherwise.
+ * @param content The content.
+ * @param imageUri The uri of image.
* @return the intent of share image
*/
- public static Intent getShareImageIntent(final String content,
- final Uri uri,
- final boolean isNewTask) {
+ public static Intent getShareTextImageIntent(@Nullable final String content, final Uri imageUri) {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_TEXT, content);
- intent.putExtra(Intent.EXTRA_STREAM, uri);
+ intent.putExtra(Intent.EXTRA_STREAM, imageUri);
intent.setType("image/*");
- return getIntent(intent, isNewTask);
+ intent = Intent.createChooser(intent, "");
+ return getIntent(intent, true);
}
/**
* Return the intent of share images.
*
- * @param content The content.
* @param imagePaths The paths of images.
* @return the intent of share images
*/
- public static Intent getShareImageIntent(final String content, final LinkedList imagePaths) {
- return getShareImageIntent(content, imagePaths, false);
+ public static Intent getShareImageIntent(final LinkedList imagePaths) {
+ return getShareTextImageIntent("", imagePaths);
}
/**
* Return the intent of share images.
*
- * @param content The content.
- * @param imagePaths The paths of images.
- * @param isNewTask True to add flag of new task, false otherwise.
+ * @param images The files of images.
* @return the intent of share images
*/
- public static Intent getShareImageIntent(final String content,
- final LinkedList imagePaths,
- final boolean isNewTask) {
- if (imagePaths == null || imagePaths.isEmpty()) return null;
- List files = new ArrayList<>();
- for (String imagePath : imagePaths) {
- files.add(new File(imagePath));
- }
- return getShareImageIntent(content, files, isNewTask);
+ public static Intent getShareImageIntent(final List images) {
+ return getShareTextImageIntent("", images);
}
/**
* Return the intent of share images.
*
- * @param content The content.
- * @param images The files of images.
- * @return the intent of share images
+ * @param uris The uris of image.
+ * @return the intent of share image
*/
- public static Intent getShareImageIntent(final String content, final List images) {
- return getShareImageIntent(content, images, false);
+ public static Intent getShareImageIntent(final ArrayList uris) {
+ return getShareTextImageIntent("", uris);
}
/**
* Return the intent of share images.
*
- * @param content The content.
- * @param images The files of images.
- * @param isNewTask True to add flag of new task, false otherwise.
+ * @param content The content.
+ * @param imagePaths The paths of images.
* @return the intent of share images
*/
- public static Intent getShareImageIntent(final String content,
- final List images,
- final boolean isNewTask) {
- if (images == null || images.isEmpty()) return null;
- ArrayList uris = new ArrayList<>();
- for (File image : images) {
- if (!image.isFile()) continue;
- uris.add(file2Uri(image));
+ public static Intent getShareTextImageIntent(@Nullable final String content,
+ final LinkedList imagePaths) {
+ List files = new ArrayList<>();
+ if (imagePaths != null) {
+ for (String imagePath : imagePaths) {
+ File file = UtilsBridge.getFileByPath(imagePath);
+ if (file != null) {
+ files.add(file);
+ }
+ }
}
- return getShareImageIntent(content, uris, isNewTask);
+ return getShareTextImageIntent(content, files);
}
/**
* Return the intent of share images.
*
* @param content The content.
- * @param uris The uris of images.
+ * @param images The files of images.
* @return the intent of share images
*/
- public static Intent getShareImageIntent(final String content, final ArrayList uris) {
- return getShareImageIntent(content, uris, false);
+ public static Intent getShareTextImageIntent(@Nullable final String content, final List images) {
+ ArrayList