From 55c3fc2eb9344eb3278b2690b32488d8a200adaa Mon Sep 17 00:00:00 2001 From: Blankj <625783482@qq.com> Date: Fri, 8 Mar 2019 17:46:44 +0800 Subject: [PATCH 01/44] see 03/08 log --- CHANGELOG.md | 1 + config.gradle | 17 ++++++------- gradle.properties | 4 ++- .../com/blankj/launcher/pkg/MainActivity.kt | 2 +- .../pkg/src/main/res/layout/activity_main.xml | 18 ++++++------- lib/base/build.gradle | 6 ++--- .../java/com/blankj/lib/base/BaseActivity.kt | 2 +- .../com/blankj/lib/base/BaseApplication.kt | 2 +- .../com/blankj/lib/base/BaseDrawerActivity.kt | 6 ++--- .../java/com/blankj/lib/base/BaseFragment.kt | 6 ++--- .../blankj/lib/base/rv/BaseViewHolder.java | 4 +-- .../lib/base/rv/RecycleViewDivider.java | 10 ++++---- .../lib/base/rv/adapter/BaseAdapter.java | 6 ++--- .../lib/base/rv/adapter/SingleAdapter.java | 2 +- .../src/main/res/layout/activity_back.xml | 14 +++++------ .../src/main/res/layout/activity_drawer.xml | 6 ++--- subutil/lib/build.gradle | 6 ++--- .../blankj/subutil/util/LocationUtils.java | 2 +- .../com/blankj/subutil/util/PinyinUtils.java | 2 +- .../java/com/blankj/subutil/util/Utils.java | 4 +-- .../blankj/subutil/pkg/helper/DialogHelper.kt | 2 +- utilcode/lib/build.gradle | 8 +++--- utilcode/lib/project.properties | 2 +- .../utilcode/constant/MemoryConstants.java | 2 +- .../constant/PermissionConstants.java | 2 +- .../utilcode/constant/TimeConstants.java | 2 +- .../blankj/utilcode/util/ActivityUtils.java | 9 ++++--- .../blankj/utilcode/util/AntiShakeUtils.java | 5 ++-- .../com/blankj/utilcode/util/AppUtils.java | 5 ++-- .../com/blankj/utilcode/util/BarUtils.java | 11 ++++---- .../blankj/utilcode/util/BrightnessUtils.java | 5 ++-- .../utilcode/util/CacheDiskStaticUtils.java | 3 ++- .../blankj/utilcode/util/CacheDiskUtils.java | 3 ++- .../utilcode/util/CacheDoubleStaticUtils.java | 3 ++- .../utilcode/util/CacheDoubleUtils.java | 2 +- .../utilcode/util/CacheMemoryStaticUtils.java | 2 +- .../utilcode/util/CacheMemoryUtils.java | 4 +-- .../com/blankj/utilcode/util/ColorUtils.java | 12 ++++----- .../com/blankj/utilcode/util/CrashUtils.java | 4 +-- .../com/blankj/utilcode/util/DeviceUtils.java | 4 +-- .../blankj/utilcode/util/FragmentUtils.java | 21 ++++++++-------- .../com/blankj/utilcode/util/ImageUtils.java | 14 +++++------ .../com/blankj/utilcode/util/IntentUtils.java | 4 +-- .../com/blankj/utilcode/util/LogUtils.java | 8 +++--- .../blankj/utilcode/util/MetaDataUtils.java | 2 +- .../blankj/utilcode/util/NetworkUtils.java | 2 +- .../utilcode/util/NotificationUtils.java | 6 ++--- .../com/blankj/utilcode/util/ObjectUtils.java | 6 ++--- .../blankj/utilcode/util/PermissionUtils.java | 8 +++--- .../com/blankj/utilcode/util/PhoneUtils.java | 2 +- .../blankj/utilcode/util/ProcessUtils.java | 4 +-- .../com/blankj/utilcode/util/RegexUtils.java | 2 +- .../blankj/utilcode/util/ResourceUtils.java | 2 +- .../blankj/utilcode/util/SPStaticUtils.java | 2 +- .../com/blankj/utilcode/util/SPUtils.java | 2 +- .../com/blankj/utilcode/util/ScreenUtils.java | 5 ++-- .../blankj/utilcode/util/SnackbarUtils.java | 14 +++++------ .../com/blankj/utilcode/util/SpanUtils.java | 16 ++++++------ .../com/blankj/utilcode/util/StringUtils.java | 4 +-- .../com/blankj/utilcode/util/ThreadUtils.java | 7 +++--- .../com/blankj/utilcode/util/TimeUtils.java | 2 +- .../com/blankj/utilcode/util/ToastUtils.java | 10 ++++---- .../com/blankj/utilcode/util/UriUtils.java | 25 +++++++++++++------ .../java/com/blankj/utilcode/util/Utils.java | 2 +- .../blankj/utilcode/util/VibrateUtils.java | 2 +- .../blankj/utilcode/util/ObjectUtilsTest.java | 5 ++-- .../pkg/feature/activity/ActivityActivity.kt | 2 +- .../feature/activity/SubActivityActivity.kt | 2 +- .../feature/bar/BarStatusFragmentActivity.kt | 16 ++++++------ .../pkg/feature/fragment/ContainerFragment.kt | 6 ++--- .../pkg/feature/fragment/FragmentActivity.kt | 6 ++--- .../pkg/feature/image/ImageActivity.kt | 8 +++--- .../pkg/feature/snackbar/SnackbarActivity.kt | 2 +- .../utilcode/pkg/feature/span/SpanActivity.kt | 2 +- .../utilcode/pkg/feature/toast/CustomToast.kt | 2 +- .../pkg/feature/toast/ToastActivity.kt | 2 +- .../utilcode/pkg/helper/DialogHelper.kt | 2 +- .../main/res/layout/activity_adaptscreen.xml | 4 +-- .../res/layout/activity_adaptscreen_close.xml | 4 +-- .../layout/activity_adaptscreen_height.xml | 4 +-- .../res/layout/activity_adaptscreen_width.xml | 4 +-- .../layout/activity_bar_status_fragment.xml | 4 +-- .../src/main/res/layout/activity_fragment.xml | 2 +- .../src/main/res/layout/activity_image.xml | 2 +- 84 files changed, 241 insertions(+), 220 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8271c33548..a1706be701 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,4 @@ +* `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/config.gradle b/config.gradle index 57c3d35e99..106f066059 100644 --- a/config.gradle +++ b/config.gradle @@ -2,7 +2,7 @@ ext { applicationId = 'com.blankj.androidutilcode' appName = 'Util' - compileSdkVersion = 27 + compileSdkVersion = 28 minSdkVersion = 14 targetSdkVersion = 27 versionCode = 1_023_007 @@ -16,8 +16,8 @@ ext { // lib version kotlin_version = '1.3.0' - support_version = '27.1.1' leakcanary_version = '1.6.3' + androidx_version = '1.0.0' dep = [ plugin : [ @@ -30,19 +30,18 @@ ext { ], // lib - support : [ - appcompat_v7: "com.android.support:appcompat-v7:$support_version", - design : "com.android.support:design:$support_version", - multidex : "com.android.support:multidex:1.0.2", - ], - constraint : "com.android.support.constraint:constraint-layout:1.1.3", + appcompat : "androidx.appcompat:appcompat:$androidx_version", + design : "com.google.android.material:material:$androidx_version", + multidex : "androidx.multidex:multidex:2.0.1", + constraint : "androidx.constraintlayout:constraintlayout:1.1.3", + kotlin : "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version", leakcanary : [ android : "com.squareup.leakcanary:leakcanary-android:$leakcanary_version", android_no_op : "com.squareup.leakcanary:leakcanary-android-no-op:$leakcanary_version", support_fragment: "com.squareup.leakcanary:leakcanary-support-fragment:$leakcanary_version" ], - free_proguard: "com.blankj:free-proguard:0.0.7", + free_proguard: "com.blankj:free-proguard:0.0.12", adapt_screen : "com.blankj:adapt-screen:0.0.3", gson : "com.google.code.gson:gson:2.8.2", diff --git a/gradle.properties b/gradle.properties index e98b0a89fc..ad5471a961 100644 --- a/gradle.properties +++ b/gradle.properties @@ -17,4 +17,6 @@ # 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 \ No newline at end of file +#org.gradle.jvmargs=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005 +android.enableJetifier=true +android.useAndroidX=true \ No newline at end of file diff --git a/launcher/pkg/src/main/java/com/blankj/launcher/pkg/MainActivity.kt b/launcher/pkg/src/main/java/com/blankj/launcher/pkg/MainActivity.kt index 27d29a032a..e6dc516ed6 100644 --- a/launcher/pkg/src/main/java/com/blankj/launcher/pkg/MainActivity.kt +++ b/launcher/pkg/src/main/java/com/blankj/launcher/pkg/MainActivity.kt @@ -2,7 +2,7 @@ package com.blankj.launcher.pkg import android.graphics.Color import android.os.Bundle -import android.support.v7.app.ActionBarDrawerToggle +import androidx.appcompat.app.ActionBarDrawerToggle import android.view.View import android.widget.ImageView import com.blankj.lib.base.BaseDrawerActivity diff --git a/launcher/pkg/src/main/res/layout/activity_main.xml b/launcher/pkg/src/main/res/layout/activity_main.xml index 3b31dafe32..ee8b62a6fa 100644 --- a/launcher/pkg/src/main/res/layout/activity_main.xml +++ b/launcher/pkg/src/main/res/layout/activity_main.xml @@ -1,17 +1,17 @@ - - - - - - + + - @@ -69,5 +69,5 @@ android:text="@string/sub_util" /> - - + + diff --git a/lib/base/build.gradle b/lib/base/build.gradle index bd369d23ee..8c6cb29835 100644 --- a/lib/base/build.gradle +++ b/lib/base/build.gradle @@ -7,9 +7,9 @@ dependencies { api project(':utilcode-lib') api project(':subutil-lib') - api dep.support.appcompat_v7 - api dep.support.design - api dep.support.multidex + api dep.appcompat + api dep.design + api dep.multidex api dep.constraint api dep.kotlin api dep.free_proguard diff --git a/lib/base/src/main/java/com/blankj/lib/base/BaseActivity.kt b/lib/base/src/main/java/com/blankj/lib/base/BaseActivity.kt index deb05718a9..b1b3086f14 100644 --- a/lib/base/src/main/java/com/blankj/lib/base/BaseActivity.kt +++ b/lib/base/src/main/java/com/blankj/lib/base/BaseActivity.kt @@ -2,7 +2,7 @@ package com.blankj.lib.base import android.app.Activity import android.os.Bundle -import android.support.v7.app.AppCompatActivity +import androidx.appcompat.app.AppCompatActivity import android.view.LayoutInflater import android.view.View import com.blankj.utilcode.util.AntiShakeUtils diff --git a/lib/base/src/main/java/com/blankj/lib/base/BaseApplication.kt b/lib/base/src/main/java/com/blankj/lib/base/BaseApplication.kt index f3eb078f79..873c71fa49 100644 --- a/lib/base/src/main/java/com/blankj/lib/base/BaseApplication.kt +++ b/lib/base/src/main/java/com/blankj/lib/base/BaseApplication.kt @@ -2,7 +2,7 @@ package com.blankj.lib.base 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 diff --git a/lib/base/src/main/java/com/blankj/lib/base/BaseDrawerActivity.kt b/lib/base/src/main/java/com/blankj/lib/base/BaseDrawerActivity.kt index a29cc60cc8..3514d2fdd3 100644 --- a/lib/base/src/main/java/com/blankj/lib/base/BaseDrawerActivity.kt +++ b/lib/base/src/main/java/com/blankj/lib/base/BaseDrawerActivity.kt @@ -2,8 +2,8 @@ package com.blankj.lib.base import android.content.Intent import android.net.Uri -import android.support.annotation.StringRes -import android.support.v4.widget.DrawerLayout +import androidx.annotation.StringRes +import androidx.drawerlayout.widget.DrawerLayout import android.view.LayoutInflater import android.widget.FrameLayout import com.blankj.utilcode.util.ActivityUtils @@ -20,7 +20,7 @@ import kotlinx.android.synthetic.main.activity_drawer.* */ abstract class BaseDrawerActivity : BaseActivity() { - protected lateinit var mBaseDrawerRootLayout: DrawerLayout + protected lateinit var mBaseDrawerRootLayout: androidx.drawerlayout.widget.DrawerLayout protected lateinit var mBaseDrawerContainerView: FrameLayout override fun isSwipeBack(): Boolean { diff --git a/lib/base/src/main/java/com/blankj/lib/base/BaseFragment.kt b/lib/base/src/main/java/com/blankj/lib/base/BaseFragment.kt index 42e7073529..3db893bea2 100644 --- a/lib/base/src/main/java/com/blankj/lib/base/BaseFragment.kt +++ b/lib/base/src/main/java/com/blankj/lib/base/BaseFragment.kt @@ -3,8 +3,8 @@ package com.blankj.lib.base import android.app.Activity import android.content.Context import android.os.Bundle -import android.support.annotation.IdRes -import android.support.v4.app.Fragment +import androidx.annotation.IdRes +import androidx.fragment.app.Fragment import android.util.Log import android.view.LayoutInflater import android.view.View @@ -19,7 +19,7 @@ import com.blankj.utilcode.util.AntiShakeUtils * desc : base about v4-fragment * ``` */ -abstract class BaseFragment : Fragment(), IBaseView { +abstract class BaseFragment : androidx.fragment.app.Fragment(), IBaseView { companion object { private const val TAG = "BaseFragment" diff --git a/lib/base/src/main/java/com/blankj/lib/base/rv/BaseViewHolder.java b/lib/base/src/main/java/com/blankj/lib/base/rv/BaseViewHolder.java index ee47e751f5..6441f8c1fd 100644 --- a/lib/base/src/main/java/com/blankj/lib/base/rv/BaseViewHolder.java +++ b/lib/base/src/main/java/com/blankj/lib/base/rv/BaseViewHolder.java @@ -1,7 +1,7 @@ package com.blankj.lib.base.rv; -import android.support.annotation.IdRes; -import android.support.v7.widget.RecyclerView; +import androidx.annotation.IdRes; +import androidx.recyclerview.widget.RecyclerView; import android.util.SparseArray; import android.view.View; diff --git a/lib/base/src/main/java/com/blankj/lib/base/rv/RecycleViewDivider.java b/lib/base/src/main/java/com/blankj/lib/base/rv/RecycleViewDivider.java index 3d2b90f302..dd20894e10 100644 --- a/lib/base/src/main/java/com/blankj/lib/base/rv/RecycleViewDivider.java +++ b/lib/base/src/main/java/com/blankj/lib/base/rv/RecycleViewDivider.java @@ -5,11 +5,11 @@ import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.Drawable; -import android.support.annotation.DrawableRes; -import android.support.annotation.NonNull; -import android.support.v4.content.ContextCompat; -import android.support.v4.view.ViewCompat; -import android.support.v7.widget.RecyclerView; +import androidx.annotation.DrawableRes; +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; +import androidx.core.view.ViewCompat; +import androidx.recyclerview.widget.RecyclerView; import android.view.View; import android.widget.LinearLayout; diff --git a/lib/base/src/main/java/com/blankj/lib/base/rv/adapter/BaseAdapter.java b/lib/base/src/main/java/com/blankj/lib/base/rv/adapter/BaseAdapter.java index f5acee0bb3..b8cf5ae12d 100644 --- a/lib/base/src/main/java/com/blankj/lib/base/rv/adapter/BaseAdapter.java +++ b/lib/base/src/main/java/com/blankj/lib/base/rv/adapter/BaseAdapter.java @@ -1,9 +1,9 @@ package com.blankj.lib.base.rv.adapter; import android.content.Context; -import android.support.annotation.LayoutRes; -import android.support.annotation.NonNull; -import android.support.v7.widget.RecyclerView; +import androidx.annotation.LayoutRes; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; import android.util.SparseArray; import android.view.LayoutInflater; import android.view.View; diff --git a/lib/base/src/main/java/com/blankj/lib/base/rv/adapter/SingleAdapter.java b/lib/base/src/main/java/com/blankj/lib/base/rv/adapter/SingleAdapter.java index 619c8fc688..b7e81b892b 100644 --- a/lib/base/src/main/java/com/blankj/lib/base/rv/adapter/SingleAdapter.java +++ b/lib/base/src/main/java/com/blankj/lib/base/rv/adapter/SingleAdapter.java @@ -1,6 +1,6 @@ package com.blankj.lib.base.rv.adapter; -import android.support.annotation.LayoutRes; +import androidx.annotation.LayoutRes; import java.util.List; diff --git a/lib/base/src/main/res/layout/activity_back.xml b/lib/base/src/main/res/layout/activity_back.xml index 5747922950..848cc885fe 100644 --- a/lib/base/src/main/res/layout/activity_back.xml +++ b/lib/base/src/main/res/layout/activity_back.xml @@ -1,26 +1,26 @@ - - - - + - - - + + diff --git a/lib/base/src/main/res/layout/activity_drawer.xml b/lib/base/src/main/res/layout/activity_drawer.xml index 1fec3fc953..697e83f643 100644 --- a/lib/base/src/main/res/layout/activity_drawer.xml +++ b/lib/base/src/main/res/layout/activity_drawer.xml @@ -1,5 +1,5 @@ - - - + diff --git a/subutil/lib/build.gradle b/subutil/lib/build.gradle index a8b9264e6c..8f8aa8198f 100644 --- a/subutil/lib/build.gradle +++ b/subutil/lib/build.gradle @@ -1,7 +1,7 @@ apply { from "${rootDir.path}/config_lib.gradle" - plugin "tech.harmonysoft.oss.traute" +// plugin "tech.harmonysoft.oss.traute" plugin "com.github.dcendents.android-maven" plugin "com.jfrog.bintray" plugin "readme-sub" @@ -13,8 +13,8 @@ readme { } dependencies { - compileOnly dep.support.appcompat_v7 - compileOnly dep.support.design + compileOnly dep.appcompat + compileOnly dep.design api(dep.glide) { exclude group: "com.android.support" } diff --git a/subutil/lib/src/main/java/com/blankj/subutil/util/LocationUtils.java b/subutil/lib/src/main/java/com/blankj/subutil/util/LocationUtils.java index 7ee8747902..0c177b534c 100755 --- a/subutil/lib/src/main/java/com/blankj/subutil/util/LocationUtils.java +++ b/subutil/lib/src/main/java/com/blankj/subutil/util/LocationUtils.java @@ -11,7 +11,7 @@ import android.location.LocationProvider; import android.os.Bundle; import android.provider.Settings; -import android.support.annotation.RequiresPermission; +import androidx.annotation.RequiresPermission; import android.util.Log; import java.io.IOException; diff --git a/subutil/lib/src/main/java/com/blankj/subutil/util/PinyinUtils.java b/subutil/lib/src/main/java/com/blankj/subutil/util/PinyinUtils.java index 22486b3a91..934408c65e 100644 --- a/subutil/lib/src/main/java/com/blankj/subutil/util/PinyinUtils.java +++ b/subutil/lib/src/main/java/com/blankj/subutil/util/PinyinUtils.java @@ -1,6 +1,6 @@ package com.blankj.subutil.util; -import android.support.v4.util.SimpleArrayMap; +import androidx.collection.SimpleArrayMap; /** *
diff --git a/subutil/lib/src/main/java/com/blankj/subutil/util/Utils.java b/subutil/lib/src/main/java/com/blankj/subutil/util/Utils.java
index 9cbf4e06fd..91b336abcf 100644
--- a/subutil/lib/src/main/java/com/blankj/subutil/util/Utils.java
+++ b/subutil/lib/src/main/java/com/blankj/subutil/util/Utils.java
@@ -7,8 +7,8 @@
 import android.content.Context;
 import android.database.Cursor;
 import android.net.Uri;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 
 import java.lang.reflect.InvocationTargetException;
 
diff --git a/subutil/pkg/src/main/java/com/blankj/subutil/pkg/helper/DialogHelper.kt b/subutil/pkg/src/main/java/com/blankj/subutil/pkg/helper/DialogHelper.kt
index 45e67a4a0d..9eba25c622 100644
--- a/subutil/pkg/src/main/java/com/blankj/subutil/pkg/helper/DialogHelper.kt
+++ b/subutil/pkg/src/main/java/com/blankj/subutil/pkg/helper/DialogHelper.kt
@@ -1,6 +1,6 @@
 package com.blankj.subutil.pkg.helper
 
-import android.support.v7.app.AlertDialog
+import androidx.appcompat.app.AlertDialog
 import com.blankj.subutil.pkg.R
 import com.blankj.utilcode.util.ActivityUtils
 import com.blankj.utilcode.util.PermissionUtils
diff --git a/utilcode/lib/build.gradle b/utilcode/lib/build.gradle
index 3570124816..41b0dacaa4 100644
--- a/utilcode/lib/build.gradle
+++ b/utilcode/lib/build.gradle
@@ -1,7 +1,7 @@
 apply {
     from "${rootDir.path}/config_lib.gradle"
 
-    plugin "tech.harmonysoft.oss.traute"
+//    plugin "tech.harmonysoft.oss.traute"
     plugin "com.github.dcendents.android-maven"
     plugin "com.jfrog.bintray"
     plugin "readme-core"
@@ -17,10 +17,10 @@ apply from: "${rootDir.path}/gradle/bintrayUploadAndroid.gradle"
 dependencies {
     compile dep.gson
 
-    compileOnly dep.support.appcompat_v7
-    compileOnly dep.support.design
+    compileOnly dep.appcompat
+    compileOnly dep.design
 
     testImplementation dep.junit
     testImplementation dep.robolectric
-    testImplementation dep.support.appcompat_v7
+    testImplementation dep.appcompat
 }
\ No newline at end of file
diff --git a/utilcode/lib/project.properties b/utilcode/lib/project.properties
index 22ae3b8603..d0f2a3f7e0 100644
--- a/utilcode/lib/project.properties
+++ b/utilcode/lib/project.properties
@@ -1,7 +1,7 @@
 #project
 project.name=UtilCode
 project.groupId=com.blankj
-project.artifactId=utilcode
+project.artifactId=utilcodex
 project.packaging=aar
 project.siteUrl=https://github.com/Blankj/AndroidUtilCode
 project.gitUrl=https://github.com/Blankj/AndroidUtilCode.git
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/constant/MemoryConstants.java b/utilcode/lib/src/main/java/com/blankj/utilcode/constant/MemoryConstants.java
index b68bfcb113..5c05c0163e 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/constant/MemoryConstants.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/constant/MemoryConstants.java
@@ -1,6 +1,6 @@
 package com.blankj.utilcode.constant;
 
-import android.support.annotation.IntDef;
+import androidx.annotation.IntDef;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/constant/PermissionConstants.java b/utilcode/lib/src/main/java/com/blankj/utilcode/constant/PermissionConstants.java
index 76f7e9a217..6db826e4ab 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/constant/PermissionConstants.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/constant/PermissionConstants.java
@@ -4,7 +4,7 @@
 import android.Manifest.permission;
 import android.annotation.SuppressLint;
 import android.os.Build;
-import android.support.annotation.StringDef;
+import androidx.annotation.StringDef;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/constant/TimeConstants.java b/utilcode/lib/src/main/java/com/blankj/utilcode/constant/TimeConstants.java
index 9932037bf8..45090576e3 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/constant/TimeConstants.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/constant/TimeConstants.java
@@ -1,6 +1,6 @@
 package com.blankj.utilcode.constant;
 
-import android.support.annotation.IntDef;
+import androidx.annotation.IntDef;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ActivityUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ActivityUtils.java
index 4b8a9a07b5..9dd16d6e48 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ActivityUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ActivityUtils.java
@@ -10,15 +10,16 @@
 import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.os.Bundle;
-import android.support.annotation.AnimRes;
-import android.support.annotation.NonNull;
-import android.support.v4.app.ActivityOptionsCompat;
-import android.support.v4.util.Pair;
 import android.util.Log;
 import android.view.View;
 
 import java.util.List;
 
+import androidx.annotation.AnimRes;
+import androidx.annotation.NonNull;
+import androidx.core.app.ActivityOptionsCompat;
+import androidx.core.util.Pair;
+
 /**
  * 
  *     author: Blankj
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/AntiShakeUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/AntiShakeUtils.java
index 7e87e73474..ca9036225e 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/AntiShakeUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/AntiShakeUtils.java
@@ -1,9 +1,10 @@
 package com.blankj.utilcode.util;
 
-import android.support.annotation.IntRange;
-import android.support.annotation.NonNull;
 import android.view.View;
 
+import androidx.annotation.IntRange;
+import androidx.annotation.NonNull;
+
 /**
  * 
  *     author: blankj
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/AppUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/AppUtils.java
index 136f27b5ed..357c423fc6 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/AppUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/AppUtils.java
@@ -17,8 +17,6 @@
 import android.net.Uri;
 import android.os.Build;
 import android.provider.Settings;
-import android.support.annotation.NonNull;
-import android.support.v4.content.FileProvider;
 import android.util.Log;
 
 import java.io.File;
@@ -27,6 +25,9 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import androidx.annotation.NonNull;
+import androidx.core.content.FileProvider;
+
 /**
  * 
  *     author: Blankj
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/BarUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/BarUtils.java
index 7b5509b2b5..22178a5c20 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/BarUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/BarUtils.java
@@ -8,11 +8,6 @@
 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.util.TypedValue;
 import android.view.Display;
@@ -27,6 +22,12 @@
 
 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;
 
 /**
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/BrightnessUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/BrightnessUtils.java
index f9344b0a59..bacc519540 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/BrightnessUtils.java
+++ b/utilcode/lib/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
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheDiskStaticUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheDiskStaticUtils.java
index bb48a4b5cf..c5a9a17a6d 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheDiskStaticUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheDiskStaticUtils.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/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheDiskUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheDiskUtils.java
index 99aef6b078..2e6637febf 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheDiskUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheDiskUtils.java
@@ -8,7 +8,6 @@
 import android.graphics.drawable.Drawable;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.support.annotation.NonNull;
 import android.util.Log;
 
 import com.blankj.utilcode.constant.CacheConstants;
@@ -37,6 +36,8 @@
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 
+import androidx.annotation.NonNull;
+
 /**
  * 
  *     author: Blankj
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheDoubleStaticUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheDoubleStaticUtils.java
index 2ef267bd01..6dbb9f7475 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheDoubleStaticUtils.java
+++ b/utilcode/lib/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/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheDoubleUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheDoubleUtils.java
index c800423c78..aca1c25837 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheDoubleUtils.java
+++ b/utilcode/lib/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;
 
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheMemoryStaticUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheMemoryStaticUtils.java
index 56abfba117..aedcfa7fc4 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheMemoryStaticUtils.java
+++ b/utilcode/lib/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/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheMemoryUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheMemoryUtils.java
index d0e06e394d..ddaa2baed9 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheMemoryUtils.java
+++ b/utilcode/lib/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/utilcode/lib/src/main/java/com/blankj/utilcode/util/ColorUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ColorUtils.java
index 4c0c22232b..a6603cfc44 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ColorUtils.java
+++ b/utilcode/lib/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;
 
 /**
  * 
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/CrashUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/CrashUtils.java
index 9ef930c467..a096321cf4 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/CrashUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/CrashUtils.java
@@ -5,8 +5,8 @@
 import android.content.pm.PackageManager;
 import android.os.Build;
 import android.os.Environment;
-import android.support.annotation.NonNull;
-import android.support.annotation.RequiresPermission;
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresPermission;
 import android.util.Log;
 
 import java.io.BufferedWriter;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/DeviceUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/DeviceUtils.java
index c1c2c3c76e..d0c1788a02 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/DeviceUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/DeviceUtils.java
@@ -8,8 +8,8 @@
 import android.os.Build;
 import android.os.PowerManager;
 import android.provider.Settings;
-import android.support.annotation.RequiresApi;
-import android.support.annotation.RequiresPermission;
+import androidx.annotation.RequiresApi;
+import androidx.annotation.RequiresPermission;
 import android.text.TextUtils;
 
 import java.io.File;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/FragmentUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/FragmentUtils.java
index 43b8537e75..9e8ae14ef1 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/FragmentUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/FragmentUtils.java
@@ -3,16 +3,6 @@
 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;
 
@@ -20,6 +10,17 @@
 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
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ImageUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ImageUtils.java
index 83e01eb1ad..cbee7dd4bd 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ImageUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ImageUtils.java
@@ -27,13 +27,13 @@
 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 androidx.annotation.ColorInt;
+import androidx.annotation.DrawableRes;
+import androidx.annotation.FloatRange;
+import androidx.annotation.IntRange;
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+import androidx.core.content.ContextCompat;
 import android.view.View;
 
 import java.io.BufferedOutputStream;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/IntentUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/IntentUtils.java
index 6faa37d043..1e26dc8a9a 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/IntentUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/IntentUtils.java
@@ -8,8 +8,8 @@
 import android.os.Bundle;
 import android.provider.MediaStore;
 import android.provider.Settings;
-import android.support.annotation.RequiresPermission;
-import android.support.v4.content.FileProvider;
+import androidx.annotation.RequiresPermission;
+import androidx.core.content.FileProvider;
 
 import java.io.File;
 import java.util.ArrayList;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/LogUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/LogUtils.java
index e1e2e78600..f5d814207d 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/LogUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/LogUtils.java
@@ -12,10 +12,10 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Environment;
-import android.support.annotation.IntDef;
-import android.support.annotation.IntRange;
-import android.support.annotation.RequiresApi;
-import android.support.v4.util.SimpleArrayMap;
+import androidx.annotation.IntDef;
+import androidx.annotation.IntRange;
+import androidx.annotation.RequiresApi;
+import androidx.collection.SimpleArrayMap;
 import android.util.Log;
 
 import com.google.gson.Gson;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/MetaDataUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/MetaDataUtils.java
index 6f6cf85b80..bd4b8da935 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/MetaDataUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/MetaDataUtils.java
@@ -8,7 +8,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
 
 /**
  * 
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/NetworkUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/NetworkUtils.java
index f281d777c2..3171837f46 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/NetworkUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/NetworkUtils.java
@@ -7,7 +7,7 @@
 import android.net.NetworkInfo;
 import android.net.wifi.WifiManager;
 import android.os.Build;
-import android.support.annotation.RequiresPermission;
+import androidx.annotation.RequiresPermission;
 import android.telephony.TelephonyManager;
 import android.text.format.Formatter;
 import android.util.Log;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/NotificationUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/NotificationUtils.java
index b8163d2e66..73a900b465 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/NotificationUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/NotificationUtils.java
@@ -5,9 +5,9 @@
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
-import android.support.annotation.Nullable;
-import android.support.v4.app.NotificationCompat;
-import android.support.v4.app.NotificationManagerCompat;
+import androidx.annotation.Nullable;
+import androidx.core.app.NotificationCompat;
+import androidx.core.app.NotificationManagerCompat;
 
 /**
  * 
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ObjectUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ObjectUtils.java
index be5491ece0..3c0c087a39 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ObjectUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ObjectUtils.java
@@ -1,9 +1,9 @@
 package com.blankj.utilcode.util;
 
 import android.os.Build;
-import android.support.annotation.RequiresApi;
-import android.support.v4.util.LongSparseArray;
-import android.support.v4.util.SimpleArrayMap;
+import androidx.annotation.RequiresApi;
+import androidx.collection.LongSparseArray;
+import androidx.collection.SimpleArrayMap;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/PermissionUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/PermissionUtils.java
index 235a0f3f94..1cb3df0156 100755
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/PermissionUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/PermissionUtils.java
@@ -10,10 +10,10 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.provider.Settings;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.annotation.RequiresApi;
-import android.support.v4.content.ContextCompat;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+import androidx.core.content.ContextCompat;
 import android.util.Log;
 import android.view.MotionEvent;
 import android.view.WindowManager;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/PhoneUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/PhoneUtils.java
index 99068781a4..f407f81b5f 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/PhoneUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/PhoneUtils.java
@@ -7,7 +7,7 @@
 import android.content.pm.PackageManager;
 import android.net.Uri;
 import android.os.Build;
-import android.support.annotation.RequiresPermission;
+import androidx.annotation.RequiresPermission;
 import android.telephony.SmsManager;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ProcessUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ProcessUtils.java
index 7db75522d9..00c2bf6f73 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ProcessUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ProcessUtils.java
@@ -10,8 +10,8 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.provider.Settings;
-import android.support.annotation.NonNull;
-import android.support.annotation.RequiresPermission;
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresPermission;
 import android.util.Log;
 
 import java.io.BufferedReader;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/RegexUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/RegexUtils.java
index ba57fab956..817a94149f 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/RegexUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/RegexUtils.java
@@ -1,6 +1,6 @@
 package com.blankj.utilcode.util;
 
-import android.support.v4.util.SimpleArrayMap;
+import androidx.collection.SimpleArrayMap;
 
 import com.blankj.utilcode.constant.RegexConstants;
 
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ResourceUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ResourceUtils.java
index 92424163bb..ee41e95958 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ResourceUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ResourceUtils.java
@@ -1,6 +1,6 @@
 package com.blankj.utilcode.util;
 
-import android.support.annotation.RawRes;
+import androidx.annotation.RawRes;
 
 import java.io.BufferedOutputStream;
 import java.io.BufferedReader;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/SPStaticUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/SPStaticUtils.java
index d3e21fb873..21274c3023 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/SPStaticUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/SPStaticUtils.java
@@ -1,7 +1,7 @@
 package com.blankj.utilcode.util;
 
 import android.content.SharedPreferences;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
 
 import java.util.Map;
 import java.util.Set;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/SPUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/SPUtils.java
index 554a2ed586..a9d18a1a55 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/SPUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/SPUtils.java
@@ -3,7 +3,7 @@
 import android.annotation.SuppressLint;
 import android.content.Context;
 import android.content.SharedPreferences;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
 
 import java.util.Collections;
 import java.util.HashMap;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ScreenUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ScreenUtils.java
index c3e089a90f..f55e4a21db 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ScreenUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ScreenUtils.java
@@ -7,12 +7,11 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
-import android.graphics.Canvas;
 import android.graphics.Point;
 import android.os.Build;
 import android.provider.Settings;
-import android.support.annotation.NonNull;
-import android.support.annotation.RequiresPermission;
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresPermission;
 import android.util.DisplayMetrics;
 import android.view.Surface;
 import android.view.View;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/SnackbarUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/SnackbarUtils.java
index b164e6154e..eab1990d29 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/SnackbarUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/SnackbarUtils.java
@@ -1,12 +1,12 @@
 package com.blankj.utilcode.util;
 
-import android.support.annotation.ColorInt;
-import android.support.annotation.DrawableRes;
-import android.support.annotation.IntDef;
-import android.support.annotation.IntRange;
-import android.support.annotation.LayoutRes;
-import android.support.annotation.NonNull;
-import android.support.design.widget.Snackbar;
+import androidx.annotation.ColorInt;
+import androidx.annotation.DrawableRes;
+import androidx.annotation.IntDef;
+import androidx.annotation.IntRange;
+import androidx.annotation.LayoutRes;
+import androidx.annotation.NonNull;
+import com.google.android.material.snackbar.Snackbar;
 import android.text.SpannableString;
 import android.text.Spanned;
 import android.text.style.ForegroundColorSpan;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/SpanUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/SpanUtils.java
index 641204fd63..d79cf9262b 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/SpanUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/SpanUtils.java
@@ -14,14 +14,14 @@
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
-import android.support.annotation.ColorInt;
-import android.support.annotation.DrawableRes;
-import android.support.annotation.FloatRange;
-import android.support.annotation.IntDef;
-import android.support.annotation.IntRange;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.v4.content.ContextCompat;
+import androidx.annotation.ColorInt;
+import androidx.annotation.DrawableRes;
+import androidx.annotation.FloatRange;
+import androidx.annotation.IntDef;
+import androidx.annotation.IntRange;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.content.ContextCompat;
 import android.text.Layout;
 import android.text.Layout.Alignment;
 import android.text.SpannableStringBuilder;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/StringUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/StringUtils.java
index c3254e3d32..70f0defe50 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/StringUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/StringUtils.java
@@ -1,8 +1,8 @@
 package com.blankj.utilcode.util;
 
 import android.content.res.Resources;
-import android.support.annotation.ArrayRes;
-import android.support.annotation.StringRes;
+import androidx.annotation.ArrayRes;
+import androidx.annotation.StringRes;
 
 /**
  * 
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ThreadUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ThreadUtils.java
index ba7122e366..819af790e8 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ThreadUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ThreadUtils.java
@@ -2,9 +2,6 @@
 
 import android.os.Handler;
 import android.os.Looper;
-import android.support.annotation.IntRange;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
 import android.util.Log;
 import android.util.SparseArray;
 
@@ -21,6 +18,10 @@
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 
+import androidx.annotation.IntRange;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
 /**
  * 
  *     author: Blankj
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/TimeUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/TimeUtils.java
index adaa920474..a5286b0fbe 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/TimeUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/TimeUtils.java
@@ -1,6 +1,6 @@
 package com.blankj.utilcode.util;
 
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
 
 import com.blankj.utilcode.constant.TimeConstants;
 
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ToastUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ToastUtils.java
index b4fe658945..b25360e52c 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ToastUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ToastUtils.java
@@ -14,11 +14,11 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
-import android.support.annotation.ColorInt;
-import android.support.annotation.DrawableRes;
-import android.support.annotation.LayoutRes;
-import android.support.annotation.StringRes;
-import android.support.v4.app.NotificationManagerCompat;
+import androidx.annotation.ColorInt;
+import androidx.annotation.DrawableRes;
+import androidx.annotation.LayoutRes;
+import androidx.annotation.StringRes;
+import androidx.core.app.NotificationManagerCompat;
 import android.util.Log;
 import android.view.Gravity;
 import android.view.LayoutInflater;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/UriUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/UriUtils.java
index 98f3ef66a8..8e4fd9d09c 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/UriUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/UriUtils.java
@@ -8,12 +8,14 @@
 import android.os.Environment;
 import android.provider.DocumentsContract;
 import android.provider.MediaStore;
-import android.support.annotation.NonNull;
-import android.support.v4.content.FileProvider;
+import android.text.TextUtils;
 import android.util.Log;
 
 import java.io.File;
 
+import androidx.annotation.NonNull;
+import androidx.core.content.FileProvider;
+
 /**
  * 
  *     author: Blankj
@@ -70,12 +72,19 @@ public static File uri2File(@NonNull final Uri uri) {
                 Log.d("UriUtils", uri.toString() + " parse failed. -> 1");
                 return null;
             } else if ("com.android.providers.downloads.documents".equals(authority)) {
-                final String id = DocumentsContract.getDocumentId(uri);
-                final Uri contentUri = ContentUris.withAppendedId(
-                        Uri.parse("content://downloads/public_downloads"),
-                        Long.valueOf(id)
-                );
-                return getFileFromUri(contentUri, 2);
+                String id = DocumentsContract.getDocumentId(uri);
+                if (!TextUtils.isEmpty(id)) {
+                    if (id.startsWith("raw:")) {
+                        return new File(id.substring(4));
+                    }
+                    final Uri contentUri = ContentUris.withAppendedId(
+                            Uri.parse(Environment.DIRECTORY_DOWNLOADS),
+                            Long.valueOf(id)
+                    );
+                    return getFileFromUri(contentUri, 2);
+                }
+                Log.d("UriUtils", uri.toString() + " parse failed. -> 3");
+                return null;
             } else if ("com.android.providers.media.documents".equals(authority)) {
                 final String docId = DocumentsContract.getDocumentId(uri);
                 final String[] split = docId.split(":");
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/Utils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/Utils.java
index 52b82376e1..d858e4ad22 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/Utils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/Utils.java
@@ -7,7 +7,7 @@
 import android.app.Application.ActivityLifecycleCallbacks;
 import android.content.Context;
 import android.os.Bundle;
-import android.support.v4.content.FileProvider;
+import androidx.core.content.FileProvider;
 import android.view.View;
 import android.view.inputmethod.InputMethodManager;
 
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/VibrateUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/VibrateUtils.java
index a57bbb8241..622d657817 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/VibrateUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/VibrateUtils.java
@@ -2,7 +2,7 @@
 
 import android.content.Context;
 import android.os.Vibrator;
-import android.support.annotation.RequiresPermission;
+import androidx.annotation.RequiresPermission;
 
 import static android.Manifest.permission.VIBRATE;
 
diff --git a/utilcode/lib/src/test/java/com/blankj/utilcode/util/ObjectUtilsTest.java b/utilcode/lib/src/test/java/com/blankj/utilcode/util/ObjectUtilsTest.java
index a0203f78fc..ed12c24d8d 100644
--- a/utilcode/lib/src/test/java/com/blankj/utilcode/util/ObjectUtilsTest.java
+++ b/utilcode/lib/src/test/java/com/blankj/utilcode/util/ObjectUtilsTest.java
@@ -1,7 +1,5 @@
 package com.blankj.utilcode.util;
 
-import android.support.v4.util.LongSparseArray;
-import android.support.v4.util.SimpleArrayMap;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
@@ -12,6 +10,9 @@
 import java.util.HashMap;
 import java.util.LinkedList;
 
+import androidx.collection.LongSparseArray;
+import androidx.collection.SimpleArrayMap;
+
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
diff --git a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/activity/ActivityActivity.kt b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/activity/ActivityActivity.kt
index 5ace21f5b1..f3d3600a27 100644
--- a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/activity/ActivityActivity.kt
+++ b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/activity/ActivityActivity.kt
@@ -6,7 +6,7 @@ import android.graphics.Bitmap
 import android.graphics.drawable.BitmapDrawable
 import android.os.Build
 import android.os.Bundle
-import android.support.v4.app.ActivityOptionsCompat
+import androidx.core.app.ActivityOptionsCompat
 import android.view.View
 import android.view.Window
 import com.blankj.lib.base.BaseTitleBarActivity
diff --git a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/activity/SubActivityActivity.kt b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/activity/SubActivityActivity.kt
index 4815032936..864f1c12b4 100644
--- a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/activity/SubActivityActivity.kt
+++ b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/activity/SubActivityActivity.kt
@@ -2,7 +2,7 @@ package com.blankj.utilcode.pkg.feature.activity
 
 import android.os.Build
 import android.os.Bundle
-import android.support.v4.app.ActivityCompat
+import androidx.core.app.ActivityCompat
 import android.view.View
 import android.view.Window
 import com.blankj.lib.base.BaseTitleBarActivity
diff --git a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/BarStatusFragmentActivity.kt b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/BarStatusFragmentActivity.kt
index b2633ddf5c..0dac18c72c 100644
--- a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/BarStatusFragmentActivity.kt
+++ b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/BarStatusFragmentActivity.kt
@@ -3,10 +3,10 @@ package com.blankj.utilcode.pkg.feature.bar
 import android.content.Context
 import android.content.Intent
 import android.os.Bundle
-import android.support.design.widget.BottomNavigationView
-import android.support.v4.app.Fragment
-import android.support.v4.app.FragmentPagerAdapter
-import android.support.v4.view.ViewPager
+import com.google.android.material.bottomnavigation.BottomNavigationView
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.FragmentPagerAdapter
+import androidx.viewpager.widget.ViewPager
 import android.view.View
 import com.blankj.lib.base.BaseActivity
 import com.blankj.utilcode.pkg.R
@@ -37,7 +37,7 @@ class BarStatusFragmentActivity : BaseActivity() {
             R.id.barStatusFragmentNavigationCustom
     )
 
-    private val mFragmentList = ArrayList()
+    private val mFragmentList = ArrayList()
 
     private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener l@{ item ->
         when (item.itemId) {
@@ -78,8 +78,8 @@ class BarStatusFragmentActivity : BaseActivity() {
         mFragmentList.add(BarStatusCustomFragment.newInstance())
 
         barStatusFragmentVp.offscreenPageLimit = 3
-        barStatusFragmentVp.adapter = object : FragmentPagerAdapter(supportFragmentManager) {
-            override fun getItem(position: Int): Fragment {
+        barStatusFragmentVp.adapter = object : androidx.fragment.app.FragmentPagerAdapter(supportFragmentManager) {
+            override fun getItem(position: Int): androidx.fragment.app.Fragment {
                 return mFragmentList[position]
             }
 
@@ -88,7 +88,7 @@ class BarStatusFragmentActivity : BaseActivity() {
             }
         }
 
-        barStatusFragmentVp.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+        barStatusFragmentVp.addOnPageChangeListener(object : androidx.viewpager.widget.ViewPager.OnPageChangeListener {
             override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
 
             override fun onPageSelected(position: Int) {
diff --git a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/fragment/ContainerFragment.kt b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/fragment/ContainerFragment.kt
index ca0289a158..117c7d121e 100644
--- a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/fragment/ContainerFragment.kt
+++ b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/fragment/ContainerFragment.kt
@@ -2,8 +2,8 @@ package com.blankj.utilcode.pkg.feature.fragment
 
 import android.os.Build
 import android.os.Bundle
-import android.support.annotation.RequiresApi
-import android.support.v4.app.Fragment
+import androidx.annotation.RequiresApi
+import androidx.fragment.app.Fragment
 import android.transition.*
 import android.view.View
 import com.blankj.lib.base.BaseLazyFragment
@@ -129,7 +129,7 @@ class ContainerFragment : BaseLazyFragment(), FragmentUtils.OnBackClickListener
         }
     }
 
-    private fun addSharedElement(fragment: Fragment): Fragment {
+    private fun addSharedElement(fragment: androidx.fragment.app.Fragment): androidx.fragment.app.Fragment {
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
             fragment.sharedElementEnterTransition = DetailTransition()
             fragment.enterTransition = Fade()
diff --git a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/fragment/FragmentActivity.kt b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/fragment/FragmentActivity.kt
index b768f563e5..6e3137b9c6 100644
--- a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/fragment/FragmentActivity.kt
+++ b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/fragment/FragmentActivity.kt
@@ -4,8 +4,8 @@ import android.content.Context
 import android.content.Intent
 import android.os.Bundle
 import android.os.PersistableBundle
-import android.support.design.widget.BottomNavigationView
-import android.support.v4.app.Fragment
+import com.google.android.material.bottomnavigation.BottomNavigationView
+import androidx.fragment.app.Fragment
 import android.view.View
 import com.blankj.lib.base.BaseActivity
 import com.blankj.utilcode.pkg.R
@@ -30,7 +30,7 @@ class FragmentActivity : BaseActivity() {
         }
     }
 
-    private val mFragments = arrayListOf()
+    private val mFragments = arrayListOf()
     private var curIndex: Int = 0
 
     private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
diff --git a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/image/ImageActivity.kt b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/image/ImageActivity.kt
index 496c5a4032..636d92c030 100644
--- a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/image/ImageActivity.kt
+++ b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/image/ImageActivity.kt
@@ -6,9 +6,9 @@ import android.graphics.Bitmap
 import android.graphics.Color
 import android.os.Build
 import android.os.Bundle
-import android.support.annotation.LayoutRes
-import android.support.annotation.StringRes
-import android.support.v7.widget.LinearLayoutManager
+import androidx.annotation.LayoutRes
+import androidx.annotation.StringRes
+import androidx.recyclerview.widget.LinearLayoutManager
 import android.view.View
 import android.widget.ImageView
 import android.widget.TextView
@@ -92,7 +92,7 @@ class ImageActivity : BaseActivity() {
         }
 
         imageRv.adapter = ImageAdapter(mList, R.layout.item_image)
-        imageRv.layoutManager = LinearLayoutManager(this)
+        imageRv.layoutManager = androidx.recyclerview.widget.LinearLayoutManager(this)
     }
 
     override fun doBusiness() {}
diff --git a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/snackbar/SnackbarActivity.kt b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/snackbar/SnackbarActivity.kt
index 4bd07d274e..34d3914fe1 100644
--- a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/snackbar/SnackbarActivity.kt
+++ b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/snackbar/SnackbarActivity.kt
@@ -4,7 +4,7 @@ import android.content.Context
 import android.content.Intent
 import android.graphics.Color
 import android.os.Bundle
-import android.support.annotation.StringRes
+import androidx.annotation.StringRes
 import android.text.SpannableStringBuilder
 import android.view.View
 import android.view.ViewGroup
diff --git a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/span/SpanActivity.kt b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/span/SpanActivity.kt
index f3a1a3ee02..7c5fd45308 100644
--- a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/span/SpanActivity.kt
+++ b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/span/SpanActivity.kt
@@ -5,7 +5,7 @@ import android.content.Context
 import android.content.Intent
 import android.graphics.*
 import android.os.Bundle
-import android.support.annotation.ColorInt
+import androidx.annotation.ColorInt
 import android.text.Layout
 import android.text.SpannableStringBuilder
 import android.text.TextPaint
diff --git a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/toast/CustomToast.kt b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/toast/CustomToast.kt
index 314ba33d59..458ecbb3fb 100644
--- a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/toast/CustomToast.kt
+++ b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/toast/CustomToast.kt
@@ -2,7 +2,7 @@ package com.blankj.utilcode.pkg.feature.toast
 
 import android.os.Handler
 import android.os.Looper
-import android.support.annotation.StringRes
+import androidx.annotation.StringRes
 import android.widget.TextView
 import android.widget.Toast
 
diff --git a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/toast/ToastActivity.kt b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/toast/ToastActivity.kt
index ea6c10c24d..40055d14b9 100644
--- a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/toast/ToastActivity.kt
+++ b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/toast/ToastActivity.kt
@@ -4,7 +4,7 @@ import android.content.Context
 import android.content.Intent
 import android.graphics.Color
 import android.os.Bundle
-import android.support.v4.content.ContextCompat
+import androidx.core.content.ContextCompat
 import android.view.Gravity
 import android.view.View
 import com.blankj.lib.base.BaseTitleBarActivity
diff --git a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/helper/DialogHelper.kt b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/helper/DialogHelper.kt
index 7e6094414a..c3247b1312 100644
--- a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/helper/DialogHelper.kt
+++ b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/helper/DialogHelper.kt
@@ -1,6 +1,6 @@
 package com.blankj.utilcode.pkg.helper
 
-import android.support.v7.app.AlertDialog
+import androidx.appcompat.app.AlertDialog
 import android.text.method.ScrollingMovementMethod
 import android.view.LayoutInflater
 import android.view.View
diff --git a/utilcode/pkg/src/main/res/layout/activity_adaptscreen.xml b/utilcode/pkg/src/main/res/layout/activity_adaptscreen.xml
index 003c6f5840..e33848b84d 100644
--- a/utilcode/pkg/src/main/res/layout/activity_adaptscreen.xml
+++ b/utilcode/pkg/src/main/res/layout/activity_adaptscreen.xml
@@ -1,5 +1,5 @@
 
-
 
-
+
diff --git a/utilcode/pkg/src/main/res/layout/activity_adaptscreen_close.xml b/utilcode/pkg/src/main/res/layout/activity_adaptscreen_close.xml
index c3f88ecba3..e43cbb2bb5 100644
--- a/utilcode/pkg/src/main/res/layout/activity_adaptscreen_close.xml
+++ b/utilcode/pkg/src/main/res/layout/activity_adaptscreen_close.xml
@@ -8,7 +8,7 @@
     android:background="@color/white"
     tools:context=".feature.adaptScreen.CloseAdaptActivity">
 
-    
 
@@ -42,6 +42,6 @@
             android:textSize="30pt"
             app:layout_constraintTop_toBottomOf="@id/adaptScreenCloseAdaptDpTv" />
 
-    
+    
 
 
\ No newline at end of file
diff --git a/utilcode/pkg/src/main/res/layout/activity_adaptscreen_height.xml b/utilcode/pkg/src/main/res/layout/activity_adaptscreen_height.xml
index 0b207d97f5..07c76be55b 100644
--- a/utilcode/pkg/src/main/res/layout/activity_adaptscreen_height.xml
+++ b/utilcode/pkg/src/main/res/layout/activity_adaptscreen_height.xml
@@ -8,7 +8,7 @@
     android:background="@color/white"
     tools:context=".feature.adaptScreen.HeightActivity">
 
-    
 
@@ -94,6 +94,6 @@
         
 
 
-    
+    
 
 
\ No newline at end of file
diff --git a/utilcode/pkg/src/main/res/layout/activity_adaptscreen_width.xml b/utilcode/pkg/src/main/res/layout/activity_adaptscreen_width.xml
index 46e0f2f1a2..5a791d924f 100644
--- a/utilcode/pkg/src/main/res/layout/activity_adaptscreen_width.xml
+++ b/utilcode/pkg/src/main/res/layout/activity_adaptscreen_width.xml
@@ -8,7 +8,7 @@
     android:background="@color/white"
     tools:context=".feature.adaptScreen.WidthActivity">
 
-    
 
@@ -147,6 +147,6 @@
 
         
 
-    
+    
 
 
\ No newline at end of file
diff --git a/utilcode/pkg/src/main/res/layout/activity_bar_status_fragment.xml b/utilcode/pkg/src/main/res/layout/activity_bar_status_fragment.xml
index c5f975b58f..1a36770b58 100644
--- a/utilcode/pkg/src/main/res/layout/activity_bar_status_fragment.xml
+++ b/utilcode/pkg/src/main/res/layout/activity_bar_status_fragment.xml
@@ -7,7 +7,7 @@
     android:background="@color/white"
     android:orientation="vertical">
 
-    
 
-    
 
-    
 
-    

From 70b6089109b6e58734d0a500820f54cb41858eba Mon Sep 17 00:00:00 2001
From: Blankj <625783482@qq.com>
Date: Fri, 8 Mar 2019 18:07:14 +0800
Subject: [PATCH 02/44] see 03/08 log

---
 utilcode/README-CN.md | 3 +++
 utilcode/README.md    | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/utilcode/README-CN.md b/utilcode/README-CN.md
index f3756be966..7fc06ebf99 100644
--- a/utilcode/README-CN.md
+++ b/utilcode/README-CN.md
@@ -3,6 +3,9 @@
 Gradle:
 ```groovy
 implementation 'com.blankj:utilcode:1.23.7'
+
+// if u use AndroidX, use the following
+implementation 'com.blankj:utilcodex:1.23.7'
 ```
 
 
diff --git a/utilcode/README.md b/utilcode/README.md
index 75d8757892..094cc44c08 100644
--- a/utilcode/README.md
+++ b/utilcode/README.md
@@ -3,6 +3,9 @@
 Gradle:
 ```groovy
 implementation 'com.blankj:utilcode:1.23.7'
+
+// if u use AndroidX, use the following
+implementation 'com.blankj:utilcodex:1.23.7'
 ```
 
 

From 2fa66306221456a5be12d9d201c7495958596fb4 Mon Sep 17 00:00:00 2001
From: Blankj <625783482@qq.com>
Date: Mon, 11 Mar 2019 20:45:31 +0800
Subject: [PATCH 03/44] see 03/11 log

---
 utilcode/lib/project.properties | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/utilcode/lib/project.properties b/utilcode/lib/project.properties
index d0f2a3f7e0..d238eda740 100644
--- a/utilcode/lib/project.properties
+++ b/utilcode/lib/project.properties
@@ -1,9 +1,9 @@
 #project
-project.name=UtilCode
+project.name=UtilCodeX
 project.groupId=com.blankj
 project.artifactId=utilcodex
 project.packaging=aar
 project.siteUrl=https://github.com/Blankj/AndroidUtilCode
 project.gitUrl=https://github.com/Blankj/AndroidUtilCode.git
 #javadoc
-javadoc.name=UtilCode
\ No newline at end of file
+javadoc.name=UtilCodeX
\ No newline at end of file

From 6b0ff9575675cf0ae15c9c9a85eb249b5591c3a8 Mon Sep 17 00:00:00 2001
From: Blankj <625783482@qq.com>
Date: Mon, 3 Jun 2019 20:49:21 +0800
Subject: [PATCH 04/44] see 06/03 log

---
 .gitignore                                    |  2 +-
 CHANGELOG.md                                  |  1 +
 gradle.properties                             |  8 +++++-
 gradle/config/config.gradle                   | 10 ++++----
 gradle/config/configApp.gradle                |  5 +++-
 launcher/app/build.gradle                     |  6 ++---
 launcher/pkg/build.gradle                     |  2 +-
 .../com/blankj/launcher/pkg/MainActivity.kt   |  2 +-
 .../pkg/src/main/res/layout/activity_main.xml | 18 ++++++-------
 lib/base/build.gradle                         |  2 +-
 .../com/blankj/lib/base/BaseActivity.java     |  5 ++--
 .../com/blankj/lib/base/BaseApplication.java  |  3 ++-
 .../blankj/lib/base/BaseDrawerActivity.java   | 11 ++++----
 .../com/blankj/lib/base/BaseFragment.java     | 13 +++++-----
 .../blankj/lib/base/BaseTitleActivity.java    |  9 ++++---
 .../java/com/blankj/lib/base/IBaseView.java   |  5 ++--
 .../com/blankj/lib/base/rv/BaseAdapter.java   |  5 ++--
 .../java/com/blankj/lib/base/rv/BaseCell.java |  3 ++-
 .../blankj/lib/base/rv/BaseViewHolder.java    |  4 +--
 .../lib/base/rv/RecycleViewDivider.java       | 10 ++++----
 .../main/res/layout/activity_base_title.xml   | 11 ++++----
 .../activity_base_title_stub_scroll.xml       |  4 +--
 .../src/main/res/layout/activity_drawer.xml   |  6 ++---
 subutil/app/build.gradle                      |  2 +-
 subutil/lib/build.gradle                      |  2 +-
 .../blankj/subutil/util/LocationUtils.java    |  2 +-
 .../com/blankj/subutil/util/PinyinUtils.java  |  2 +-
 .../java/com/blankj/subutil/util/Utils.java   |  4 +--
 .../subutil/util/http/ExecutorFactory.java    |  3 ++-
 .../blankj/subutil/util/http/HttpUtils.java   |  3 ++-
 .../com/blankj/subutil/util/http/Request.java |  3 ++-
 .../blankj/subutil/util/http/SSLConfig.java   |  3 ++-
 subutil/pkg/build.gradle                      |  2 +-
 .../blankj/subutil/pkg/helper/DialogHelper.kt |  2 +-
 utilcode/README-CN.md                         |  2 +-
 utilcode/README.md                            |  2 +-
 utilcode/app/build.gradle                     |  2 +-
 utilcode/lib/build.gradle                     |  2 +-
 utilcode/lib/project.properties               |  6 ++---
 .../utilcode/constant/MemoryConstants.java    |  2 +-
 .../constant/PermissionConstants.java         |  2 +-
 .../utilcode/constant/TimeConstants.java      |  2 +-
 .../blankj/utilcode/util/ActivityUtils.java   | 11 ++++----
 .../blankj/utilcode/util/AntiShakeUtils.java  |  5 ++--
 .../com/blankj/utilcode/util/AppUtils.java    |  5 ++--
 .../com/blankj/utilcode/util/BarUtils.java    | 11 ++++----
 .../blankj/utilcode/util/BrightnessUtils.java |  5 ++--
 .../com/blankj/utilcode/util/BusUtils.java    |  5 ++--
 .../utilcode/util/CacheDiskStaticUtils.java   |  3 ++-
 .../blankj/utilcode/util/CacheDiskUtils.java  |  3 ++-
 .../utilcode/util/CacheDoubleStaticUtils.java |  3 ++-
 .../utilcode/util/CacheDoubleUtils.java       |  2 +-
 .../utilcode/util/CacheMemoryStaticUtils.java |  2 +-
 .../utilcode/util/CacheMemoryUtils.java       |  4 +--
 .../com/blankj/utilcode/util/ColorUtils.java  | 12 ++++-----
 .../com/blankj/utilcode/util/CrashUtils.java  |  4 +--
 .../com/blankj/utilcode/util/DeviceUtils.java |  5 ++--
 .../blankj/utilcode/util/FragmentUtils.java   | 21 ++++++++--------
 .../com/blankj/utilcode/util/ImageUtils.java  | 14 +++++------
 .../com/blankj/utilcode/util/IntentUtils.java |  4 +--
 .../blankj/utilcode/util/KeyboardUtils.java   |  3 ++-
 .../com/blankj/utilcode/util/LogUtils.java    |  8 +++---
 .../blankj/utilcode/util/MetaDataUtils.java   |  2 +-
 .../blankj/utilcode/util/NetworkUtils.java    |  5 ++--
 .../utilcode/util/NotificationUtils.java      |  6 ++---
 .../com/blankj/utilcode/util/ObjectUtils.java |  6 ++---
 .../blankj/utilcode/util/PermissionUtils.java |  8 +++---
 .../com/blankj/utilcode/util/PhoneUtils.java  |  2 +-
 .../blankj/utilcode/util/ProcessUtils.java    |  4 +--
 .../com/blankj/utilcode/util/RegexUtils.java  |  2 +-
 .../blankj/utilcode/util/ResourceUtils.java   |  2 +-
 .../blankj/utilcode/util/SPStaticUtils.java   |  2 +-
 .../com/blankj/utilcode/util/SPUtils.java     |  2 +-
 .../com/blankj/utilcode/util/ScreenUtils.java |  4 +--
 .../com/blankj/utilcode/util/ShellUtils.java  |  2 +-
 .../blankj/utilcode/util/SnackbarUtils.java   | 14 +++++------
 .../com/blankj/utilcode/util/SpanUtils.java   | 16 ++++++------
 .../com/blankj/utilcode/util/StringUtils.java |  4 +--
 .../com/blankj/utilcode/util/ThreadUtils.java |  5 ++--
 .../com/blankj/utilcode/util/TimeUtils.java   |  2 +-
 .../com/blankj/utilcode/util/ToastUtils.java  | 10 ++++----
 .../com/blankj/utilcode/util/UriUtils.java    | 25 +++++++++++++------
 .../java/com/blankj/utilcode/util/Utils.java  |  3 ++-
 .../blankj/utilcode/util/VibrateUtils.java    |  2 +-
 .../com/blankj/utilcode/util/BaseTest.java    | 11 +++-----
 .../blankj/utilcode/util/ObjectUtilsTest.java |  5 ++--
 utilcode/pkg/build.gradle                     |  2 +-
 .../pkg/feature/activity/ActivityActivity.kt  |  2 +-
 .../feature/activity/SubActivityActivity.kt   |  2 +-
 .../feature/bar/BarStatusFragmentActivity.kt  | 16 ++++++------
 .../pkg/feature/fragment/ContainerFragment.kt |  6 ++---
 .../pkg/feature/fragment/FragmentActivity.kt  |  6 ++---
 .../pkg/feature/image/ImageActivity.kt        |  4 +--
 .../pkg/feature/snackbar/SnackbarActivity.kt  |  2 +-
 .../utilcode/pkg/feature/span/SpanActivity.kt |  2 +-
 .../utilcode/pkg/feature/toast/CustomToast.kt |  2 +-
 .../pkg/feature/toast/ToastActivity.kt        |  2 +-
 .../utilcode/pkg/helper/DialogHelper.kt       |  5 ++--
 .../main/res/layout/activity_adaptscreen.xml  |  4 +--
 .../res/layout/activity_adaptscreen_close.xml |  4 +--
 .../layout/activity_adaptscreen_height.xml    |  7 +++---
 .../res/layout/activity_adaptscreen_width.xml |  4 +--
 .../layout/activity_bar_status_fragment.xml   |  4 +--
 .../src/main/res/layout/activity_fragment.xml |  2 +-
 .../src/main/res/layout/activity_image.xml    |  3 +--
 105 files changed, 293 insertions(+), 253 deletions(-)

diff --git a/.gitignore b/.gitignore
index 201b88771a..193619553c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,4 +9,4 @@
 .externalNativeBuild
 /apk
 *.phrof
-/maven
+/busMaven
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 95dfb60cc3..9c48786e89 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,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/gradle.properties b/gradle.properties
index 110f0cb7ef..c209c08b84 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -19,4 +19,10 @@
 
 #org.gradle.jvmargs=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005
 
-org.gradle.jvmargs=-XX:MaxHeapSize=1024m -Xmx1024m
\ No newline at end of file
+org.gradle.jvmargs=-Xmx8192m -XX:MaxPermSize=2048m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+org.gradle.daemon=true
+org.gradle.configureondemand=true
+org.gradle.parallel=true
+
+android.enableJetifier=true
+android.useAndroidX=true
\ No newline at end of file
diff --git a/gradle/config/config.gradle b/gradle/config/config.gradle
index e455c4dba6..e8c793b6b3 100644
--- a/gradle/config/config.gradle
+++ b/gradle/config/config.gradle
@@ -5,7 +5,7 @@ gradle.ext {
     applicationId = 'com.blankj.androidutilcode'
     appName = 'Util'
 
-    compileSdkVersion = 27
+    compileSdkVersion = 28
     minSdkVersion = 14
     targetSdkVersion = 27
     versionCode = 1_024_000
@@ -13,8 +13,8 @@ gradle.ext {
 
     // lib version
     kotlin_version = '1.3.10'
-    support_version = '27.1.1'
     leakcanary_version = '1.6.3'
+    androidx_version = '1.0.0'
 
     dep = [:]
 
@@ -36,11 +36,11 @@ gradle.ext {
             subutil_lib                : new DepConfig(":subutil:lib"),
             subutil_pkg                : new DepConfig(":subutil:pkg"),
             utilcode_app               : new DepConfig(":utilcode:app"),
-            utilcode_lib               : new DepConfig(false, ":utilcode:lib", "com.blankj:utilcode:$versionName"),
+            utilcode_lib               : new DepConfig(true, ":utilcode:lib", "com.blankj:utilcode:$versionName"),
             utilcode_pkg               : new DepConfig(":utilcode:pkg"),
 
-            support_appcompat_v7       : new DepConfig("com.android.support:appcompat-v7:$support_version"),
-            support_design             : new DepConfig("com.android.support:design:$support_version"),
+            support_appcompat_v7       : new DepConfig("androidx.appcompat:appcompat:$androidx_version"),
+            support_material           : new DepConfig("com.google.android.material:material:$androidx_version"),
             support_multidex           : new DepConfig("com.android.support:multidex:1.0.2"),
 
             constraint                 : new DepConfig("com.android.support.constraint:constraint-layout:1.1.3"),
diff --git a/gradle/config/configApp.gradle b/gradle/config/configApp.gradle
index cb8d5a290a..809cb07cd4 100644
--- a/gradle/config/configApp.gradle
+++ b/gradle/config/configApp.gradle
@@ -42,8 +42,11 @@ android {
     }
 
     dexOptions {
+        preDexLibraries true
         javaMaxHeapSize "8g"
         maxProcessCount 8
+        incremental true
+        dexInProcess = true
     }
 }
 
@@ -57,7 +60,7 @@ dependencies {
 
 private String getSuffix() {
     if (project.path == ":launcher:app") return ""
-    return project.path.replace(":" , "_").substring(0, project.path.length() - 4)
+    return project.path.replace(":", "_").substring(0, project.path.length() - 4)
 }
 
 def configSigning(Project pro) {
diff --git a/launcher/app/build.gradle b/launcher/app/build.gradle
index eb9f8d906f..bf68fb45ff 100644
--- a/launcher/app/build.gradle
+++ b/launcher/app/build.gradle
@@ -4,7 +4,7 @@ apply {
 
 dependencies {
     implementation fileTree(dir: 'libs', include: ['*.jar'])
-    implementation project(':launcher:pkg')
-    implementation project(':subutil:pkg')
-    implementation project(':utilcode:pkg')
+    implementation gradle.ext.dep.launcher_pkg
+    implementation gradle.ext.dep.subutil_pkg
+    implementation gradle.ext.dep.utilcode_pkg
 }
\ No newline at end of file
diff --git a/launcher/pkg/build.gradle b/launcher/pkg/build.gradle
index 9fe360a5dd..881637b34a 100644
--- a/launcher/pkg/build.gradle
+++ b/launcher/pkg/build.gradle
@@ -4,5 +4,5 @@ apply {
 
 dependencies {
     implementation fileTree(dir: 'libs', include: ['*.jar'])
-    api project(':lib:base')
+    api gradle.ext.dep.lib_base
 }
\ No newline at end of file
diff --git a/launcher/pkg/src/main/java/com/blankj/launcher/pkg/MainActivity.kt b/launcher/pkg/src/main/java/com/blankj/launcher/pkg/MainActivity.kt
index 02491cd88d..0e9f0a8477 100644
--- a/launcher/pkg/src/main/java/com/blankj/launcher/pkg/MainActivity.kt
+++ b/launcher/pkg/src/main/java/com/blankj/launcher/pkg/MainActivity.kt
@@ -2,7 +2,7 @@ package com.blankj.launcher.pkg
 
 import android.graphics.Color
 import android.os.Bundle
-import android.support.v7.app.ActionBarDrawerToggle
+import androidx.appcompat.app.ActionBarDrawerToggle
 import android.view.View
 import android.widget.ImageView
 import com.blankj.lib.base.BaseDrawerActivity
diff --git a/launcher/pkg/src/main/res/layout/activity_main.xml b/launcher/pkg/src/main/res/layout/activity_main.xml
index 3b31dafe32..ee8b62a6fa 100644
--- a/launcher/pkg/src/main/res/layout/activity_main.xml
+++ b/launcher/pkg/src/main/res/layout/activity_main.xml
@@ -1,17 +1,17 @@
 
-
 
-    
 
-        
 
-            
 
-        
-    
+        
+    
 
     
 
-    
@@ -69,5 +69,5 @@
                 android:text="@string/sub_util" />
 
         
-    
-
+    
+
diff --git a/lib/base/build.gradle b/lib/base/build.gradle
index 370036c062..67f9762d82 100644
--- a/lib/base/build.gradle
+++ b/lib/base/build.gradle
@@ -8,7 +8,7 @@ dependencies {
     api gradle.ext.dep.subutil_lib
 
     api gradle.ext.dep.support_appcompat_v7
-    api gradle.ext.dep.support_design
+    api gradle.ext.dep.support_material
     api gradle.ext.dep.support_multidex
     api gradle.ext.dep.constraint
     api gradle.ext.dep.kotlin
diff --git a/lib/base/src/main/java/com/blankj/lib/base/BaseActivity.java b/lib/base/src/main/java/com/blankj/lib/base/BaseActivity.java
index caae1d45cf..0c9d8fa419 100644
--- a/lib/base/src/main/java/com/blankj/lib/base/BaseActivity.java
+++ b/lib/base/src/main/java/com/blankj/lib/base/BaseActivity.java
@@ -3,11 +3,12 @@
 import android.annotation.SuppressLint;
 import android.app.Activity;
 import android.os.Bundle;
-import android.support.annotation.LayoutRes;
-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.swipepanel.SwipePanel;
 import com.blankj.utilcode.util.AntiShakeUtils;
 import com.blankj.utilcode.util.AppUtils;
diff --git a/lib/base/src/main/java/com/blankj/lib/base/BaseApplication.java b/lib/base/src/main/java/com/blankj/lib/base/BaseApplication.java
index 1e0ddc0b27..5d2eba8260 100644
--- a/lib/base/src/main/java/com/blankj/lib/base/BaseApplication.java
+++ b/lib/base/src/main/java/com/blankj/lib/base/BaseApplication.java
@@ -2,7 +2,8 @@
 
 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;
diff --git a/lib/base/src/main/java/com/blankj/lib/base/BaseDrawerActivity.java b/lib/base/src/main/java/com/blankj/lib/base/BaseDrawerActivity.java
index c7f7f1daea..ec3c895f6e 100755
--- a/lib/base/src/main/java/com/blankj/lib/base/BaseDrawerActivity.java
+++ b/lib/base/src/main/java/com/blankj/lib/base/BaseDrawerActivity.java
@@ -3,17 +3,18 @@
 import android.annotation.SuppressLint;
 import android.content.Intent;
 import android.net.Uri;
-import android.support.annotation.LayoutRes;
-import android.support.annotation.NonNull;
-import android.support.annotation.StringRes;
-import android.support.design.widget.NavigationView;
-import android.support.v4.widget.DrawerLayout;
 import android.view.LayoutInflater;
 import android.view.MenuItem;
 import android.widget.FrameLayout;
 
+import androidx.annotation.LayoutRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.StringRes;
+import androidx.drawerlayout.widget.DrawerLayout;
+
 import com.blankj.utilcode.util.ActivityUtils;
 import com.blankj.utilcode.util.StringUtils;
+import com.google.android.material.navigation.NavigationView;
 
 
 /**
diff --git a/lib/base/src/main/java/com/blankj/lib/base/BaseFragment.java b/lib/base/src/main/java/com/blankj/lib/base/BaseFragment.java
index 5667f3f02c..0e4e7ba5cc 100755
--- a/lib/base/src/main/java/com/blankj/lib/base/BaseFragment.java
+++ b/lib/base/src/main/java/com/blankj/lib/base/BaseFragment.java
@@ -4,17 +4,18 @@
 import android.app.Activity;
 import android.content.Context;
 import android.os.Bundle;
-import android.support.annotation.IdRes;
-import android.support.annotation.LayoutRes;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentTransaction;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 
+import androidx.annotation.IdRes;
+import androidx.annotation.LayoutRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentTransaction;
+
 import com.blankj.utilcode.util.AntiShakeUtils;
 
 /**
diff --git a/lib/base/src/main/java/com/blankj/lib/base/BaseTitleActivity.java b/lib/base/src/main/java/com/blankj/lib/base/BaseTitleActivity.java
index a40230420d..e0ed3ed10a 100644
--- a/lib/base/src/main/java/com/blankj/lib/base/BaseTitleActivity.java
+++ b/lib/base/src/main/java/com/blankj/lib/base/BaseTitleActivity.java
@@ -1,16 +1,17 @@
 package com.blankj.lib.base;
 
 import android.annotation.SuppressLint;
-import android.support.annotation.LayoutRes;
-import android.support.design.widget.CoordinatorLayout;
-import android.support.v7.app.ActionBar;
-import android.support.v7.widget.Toolbar;
 import android.view.LayoutInflater;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewStub;
 import android.widget.FrameLayout;
 
+import androidx.annotation.LayoutRes;
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.widget.Toolbar;
+import androidx.coordinatorlayout.widget.CoordinatorLayout;
+
 import com.blankj.utilcode.util.BarUtils;
 import com.blankj.utilcode.util.ColorUtils;
 
diff --git a/lib/base/src/main/java/com/blankj/lib/base/IBaseView.java b/lib/base/src/main/java/com/blankj/lib/base/IBaseView.java
index 29e8553899..b0550f126c 100644
--- a/lib/base/src/main/java/com/blankj/lib/base/IBaseView.java
+++ b/lib/base/src/main/java/com/blankj/lib/base/IBaseView.java
@@ -1,10 +1,11 @@
 package com.blankj.lib.base;
 
 import android.os.Bundle;
-import android.support.annotation.LayoutRes;
-import android.support.annotation.Nullable;
 import android.view.View;
 
+import androidx.annotation.LayoutRes;
+import androidx.annotation.Nullable;
+
 
 /**
  * 
diff --git a/lib/base/src/main/java/com/blankj/lib/base/rv/BaseAdapter.java b/lib/base/src/main/java/com/blankj/lib/base/rv/BaseAdapter.java
index 11aa94e015..e69be6c6df 100644
--- a/lib/base/src/main/java/com/blankj/lib/base/rv/BaseAdapter.java
+++ b/lib/base/src/main/java/com/blankj/lib/base/rv/BaseAdapter.java
@@ -1,12 +1,13 @@
 package com.blankj.lib.base.rv;
 
 import android.content.Context;
-import android.support.annotation.NonNull;
-import android.support.v7.widget.RecyclerView;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
 import java.util.List;
 
 /**
diff --git a/lib/base/src/main/java/com/blankj/lib/base/rv/BaseCell.java b/lib/base/src/main/java/com/blankj/lib/base/rv/BaseCell.java
index cdf42c7882..332c4caee0 100644
--- a/lib/base/src/main/java/com/blankj/lib/base/rv/BaseCell.java
+++ b/lib/base/src/main/java/com/blankj/lib/base/rv/BaseCell.java
@@ -1,10 +1,11 @@
 package com.blankj.lib.base.rv;
 
-import android.support.annotation.NonNull;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
 import android.view.View;
 
+import androidx.annotation.NonNull;
+
 /**
  * 
  *     author: blankj
diff --git a/lib/base/src/main/java/com/blankj/lib/base/rv/BaseViewHolder.java b/lib/base/src/main/java/com/blankj/lib/base/rv/BaseViewHolder.java
index ceb1c46eac..0bd892f317 100644
--- a/lib/base/src/main/java/com/blankj/lib/base/rv/BaseViewHolder.java
+++ b/lib/base/src/main/java/com/blankj/lib/base/rv/BaseViewHolder.java
@@ -1,7 +1,7 @@
 package com.blankj.lib.base.rv;
 
-import android.support.annotation.IdRes;
-import android.support.v7.widget.RecyclerView;
+import androidx.annotation.IdRes;
+import androidx.recyclerview.widget.RecyclerView;
 import android.util.SparseArray;
 import android.view.View;
 
diff --git a/lib/base/src/main/java/com/blankj/lib/base/rv/RecycleViewDivider.java b/lib/base/src/main/java/com/blankj/lib/base/rv/RecycleViewDivider.java
index 3d2b90f302..dd20894e10 100644
--- a/lib/base/src/main/java/com/blankj/lib/base/rv/RecycleViewDivider.java
+++ b/lib/base/src/main/java/com/blankj/lib/base/rv/RecycleViewDivider.java
@@ -5,11 +5,11 @@
 import android.graphics.Canvas;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
-import android.support.annotation.DrawableRes;
-import android.support.annotation.NonNull;
-import android.support.v4.content.ContextCompat;
-import android.support.v4.view.ViewCompat;
-import android.support.v7.widget.RecyclerView;
+import androidx.annotation.DrawableRes;
+import androidx.annotation.NonNull;
+import androidx.core.content.ContextCompat;
+import androidx.core.view.ViewCompat;
+import androidx.recyclerview.widget.RecyclerView;
 import android.view.View;
 import android.widget.LinearLayout;
 
diff --git a/lib/base/src/main/res/layout/activity_base_title.xml b/lib/base/src/main/res/layout/activity_base_title.xml
index b11ecf7341..986d3669b6 100644
--- a/lib/base/src/main/res/layout/activity_base_title.xml
+++ b/lib/base/src/main/res/layout/activity_base_title.xml
@@ -1,24 +1,23 @@
 
-
 
-    
 
-        
-    
+    
 
     
 
-
+
diff --git a/lib/base/src/main/res/layout/activity_base_title_stub_scroll.xml b/lib/base/src/main/res/layout/activity_base_title_stub_scroll.xml
index 96f5e09d49..bd031cfb67 100644
--- a/lib/base/src/main/res/layout/activity_base_title_stub_scroll.xml
+++ b/lib/base/src/main/res/layout/activity_base_title_stub_scroll.xml
@@ -1,5 +1,5 @@
 
-
 
-
+
 
diff --git a/lib/base/src/main/res/layout/activity_drawer.xml b/lib/base/src/main/res/layout/activity_drawer.xml
index 72f70ed969..be44cd718c 100644
--- a/lib/base/src/main/res/layout/activity_drawer.xml
+++ b/lib/base/src/main/res/layout/activity_drawer.xml
@@ -1,5 +1,5 @@
 
-
 
-    
 
-
+
diff --git a/subutil/app/build.gradle b/subutil/app/build.gradle
index a2e0172413..a7027c15ef 100644
--- a/subutil/app/build.gradle
+++ b/subutil/app/build.gradle
@@ -4,5 +4,5 @@ apply {
 
 dependencies {
     implementation fileTree(dir: 'libs', include: ['*.jar'])
-    implementation project(':subutil:pkg')
+    implementation gradle.ext.dep.subutil_pkg
 }
\ No newline at end of file
diff --git a/subutil/lib/build.gradle b/subutil/lib/build.gradle
index 9dcbe0b542..f3140b4f0b 100644
--- a/subutil/lib/build.gradle
+++ b/subutil/lib/build.gradle
@@ -14,7 +14,7 @@ readme {
 
 dependencies {
     compileOnly gradle.ext.dep.support_appcompat_v7
-    compileOnly gradle.ext.dep.support_design
+    compileOnly gradle.ext.dep.support_material
     api(gradle.ext.dep.glide) {
         exclude group: "com.android.support"
     }
diff --git a/subutil/lib/src/main/java/com/blankj/subutil/util/LocationUtils.java b/subutil/lib/src/main/java/com/blankj/subutil/util/LocationUtils.java
index 7ee8747902..0c177b534c 100755
--- a/subutil/lib/src/main/java/com/blankj/subutil/util/LocationUtils.java
+++ b/subutil/lib/src/main/java/com/blankj/subutil/util/LocationUtils.java
@@ -11,7 +11,7 @@
 import android.location.LocationProvider;
 import android.os.Bundle;
 import android.provider.Settings;
-import android.support.annotation.RequiresPermission;
+import androidx.annotation.RequiresPermission;
 import android.util.Log;
 
 import java.io.IOException;
diff --git a/subutil/lib/src/main/java/com/blankj/subutil/util/PinyinUtils.java b/subutil/lib/src/main/java/com/blankj/subutil/util/PinyinUtils.java
index 22486b3a91..934408c65e 100644
--- a/subutil/lib/src/main/java/com/blankj/subutil/util/PinyinUtils.java
+++ b/subutil/lib/src/main/java/com/blankj/subutil/util/PinyinUtils.java
@@ -1,6 +1,6 @@
 package com.blankj.subutil.util;
 
-import android.support.v4.util.SimpleArrayMap;
+import androidx.collection.SimpleArrayMap;
 
 /**
  * 
diff --git a/subutil/lib/src/main/java/com/blankj/subutil/util/Utils.java b/subutil/lib/src/main/java/com/blankj/subutil/util/Utils.java
index 9cbf4e06fd..91b336abcf 100644
--- a/subutil/lib/src/main/java/com/blankj/subutil/util/Utils.java
+++ b/subutil/lib/src/main/java/com/blankj/subutil/util/Utils.java
@@ -7,8 +7,8 @@
 import android.content.Context;
 import android.database.Cursor;
 import android.net.Uri;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 
 import java.lang.reflect.InvocationTargetException;
 
diff --git a/subutil/lib/src/main/java/com/blankj/subutil/util/http/ExecutorFactory.java b/subutil/lib/src/main/java/com/blankj/subutil/util/http/ExecutorFactory.java
index f5583397d9..2f26fb9c24 100644
--- a/subutil/lib/src/main/java/com/blankj/subutil/util/http/ExecutorFactory.java
+++ b/subutil/lib/src/main/java/com/blankj/subutil/util/http/ExecutorFactory.java
@@ -2,7 +2,8 @@
 
 import android.os.Handler;
 import android.os.Looper;
-import android.support.annotation.NonNull;
+
+import androidx.annotation.NonNull;
 
 import java.util.concurrent.Executor;
 import java.util.concurrent.LinkedBlockingQueue;
diff --git a/subutil/lib/src/main/java/com/blankj/subutil/util/http/HttpUtils.java b/subutil/lib/src/main/java/com/blankj/subutil/util/http/HttpUtils.java
index b952f318cb..bdd4174486 100644
--- a/subutil/lib/src/main/java/com/blankj/subutil/util/http/HttpUtils.java
+++ b/subutil/lib/src/main/java/com/blankj/subutil/util/http/HttpUtils.java
@@ -1,7 +1,8 @@
 package com.blankj.subutil.util.http;
 
 import android.accounts.NetworkErrorException;
-import android.support.annotation.NonNull;
+
+import androidx.annotation.NonNull;
 
 import java.io.BufferedOutputStream;
 import java.io.ByteArrayOutputStream;
diff --git a/subutil/lib/src/main/java/com/blankj/subutil/util/http/Request.java b/subutil/lib/src/main/java/com/blankj/subutil/util/http/Request.java
index fe39b1299c..c6eddf9b96 100644
--- a/subutil/lib/src/main/java/com/blankj/subutil/util/http/Request.java
+++ b/subutil/lib/src/main/java/com/blankj/subutil/util/http/Request.java
@@ -1,6 +1,7 @@
 package com.blankj.subutil.util.http;
 
-import android.support.annotation.NonNull;
+
+import androidx.annotation.NonNull;
 
 import java.io.BufferedInputStream;
 import java.io.ByteArrayInputStream;
diff --git a/subutil/lib/src/main/java/com/blankj/subutil/util/http/SSLConfig.java b/subutil/lib/src/main/java/com/blankj/subutil/util/http/SSLConfig.java
index b8624af490..0cf43662f2 100644
--- a/subutil/lib/src/main/java/com/blankj/subutil/util/http/SSLConfig.java
+++ b/subutil/lib/src/main/java/com/blankj/subutil/util/http/SSLConfig.java
@@ -2,7 +2,8 @@
 
 import android.annotation.SuppressLint;
 import android.os.Build;
-import android.support.annotation.NonNull;
+
+import androidx.annotation.NonNull;
 
 import java.io.IOException;
 import java.net.InetAddress;
diff --git a/subutil/pkg/build.gradle b/subutil/pkg/build.gradle
index 9fe360a5dd..881637b34a 100644
--- a/subutil/pkg/build.gradle
+++ b/subutil/pkg/build.gradle
@@ -4,5 +4,5 @@ apply {
 
 dependencies {
     implementation fileTree(dir: 'libs', include: ['*.jar'])
-    api project(':lib:base')
+    api gradle.ext.dep.lib_base
 }
\ No newline at end of file
diff --git a/subutil/pkg/src/main/java/com/blankj/subutil/pkg/helper/DialogHelper.kt b/subutil/pkg/src/main/java/com/blankj/subutil/pkg/helper/DialogHelper.kt
index 45e67a4a0d..9eba25c622 100644
--- a/subutil/pkg/src/main/java/com/blankj/subutil/pkg/helper/DialogHelper.kt
+++ b/subutil/pkg/src/main/java/com/blankj/subutil/pkg/helper/DialogHelper.kt
@@ -1,6 +1,6 @@
 package com.blankj.subutil.pkg.helper
 
-import android.support.v7.app.AlertDialog
+import androidx.appcompat.app.AlertDialog
 import com.blankj.subutil.pkg.R
 import com.blankj.utilcode.util.ActivityUtils
 import com.blankj.utilcode.util.PermissionUtils
diff --git a/utilcode/README-CN.md b/utilcode/README-CN.md
index 445f206121..0bdb622940 100644
--- a/utilcode/README-CN.md
+++ b/utilcode/README-CN.md
@@ -5,7 +5,7 @@ Gradle:
 implementation 'com.blankj:utilcode:1.24.0'
 
 // if u use AndroidX, use the following
-implementation 'com.blankj:utilcodex:1.23.7'
+implementation 'com.blankj:utilcodex:1.24.0'
 ```
 
 
diff --git a/utilcode/README.md b/utilcode/README.md
index f449736061..5a6a295b4c 100644
--- a/utilcode/README.md
+++ b/utilcode/README.md
@@ -5,7 +5,7 @@ Gradle:
 implementation 'com.blankj:utilcode:1.24.0'
 
 // if u use AndroidX, use the following
-implementation 'com.blankj:utilcodex:1.23.7'
+implementation 'com.blankj:utilcodex:1.24.0'
 ```
 
 
diff --git a/utilcode/app/build.gradle b/utilcode/app/build.gradle
index 5616386892..ea5c172cd7 100644
--- a/utilcode/app/build.gradle
+++ b/utilcode/app/build.gradle
@@ -4,5 +4,5 @@ apply {
 
 dependencies {
     implementation fileTree(dir: 'libs', include: ['*.jar'])
-    implementation project(':utilcode:pkg')
+    implementation gradle.ext.dep.utilcode_pkg
 }
\ No newline at end of file
diff --git a/utilcode/lib/build.gradle b/utilcode/lib/build.gradle
index e4dd3a6716..6d6c599298 100644
--- a/utilcode/lib/build.gradle
+++ b/utilcode/lib/build.gradle
@@ -18,7 +18,7 @@ dependencies {
     compile gradle.ext.dep.gson
 
     compileOnly gradle.ext.dep.support_appcompat_v7
-    compileOnly gradle.ext.dep.support_design
+    compileOnly gradle.ext.dep.support_material
 
     testImplementation gradle.ext.dep.junit
     testImplementation gradle.ext.dep.robolectric
diff --git a/utilcode/lib/project.properties b/utilcode/lib/project.properties
index 22ae3b8603..d238eda740 100644
--- a/utilcode/lib/project.properties
+++ b/utilcode/lib/project.properties
@@ -1,9 +1,9 @@
 #project
-project.name=UtilCode
+project.name=UtilCodeX
 project.groupId=com.blankj
-project.artifactId=utilcode
+project.artifactId=utilcodex
 project.packaging=aar
 project.siteUrl=https://github.com/Blankj/AndroidUtilCode
 project.gitUrl=https://github.com/Blankj/AndroidUtilCode.git
 #javadoc
-javadoc.name=UtilCode
\ No newline at end of file
+javadoc.name=UtilCodeX
\ No newline at end of file
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/constant/MemoryConstants.java b/utilcode/lib/src/main/java/com/blankj/utilcode/constant/MemoryConstants.java
index b68bfcb113..5c05c0163e 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/constant/MemoryConstants.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/constant/MemoryConstants.java
@@ -1,6 +1,6 @@
 package com.blankj.utilcode.constant;
 
-import android.support.annotation.IntDef;
+import androidx.annotation.IntDef;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/constant/PermissionConstants.java b/utilcode/lib/src/main/java/com/blankj/utilcode/constant/PermissionConstants.java
index 76f7e9a217..6db826e4ab 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/constant/PermissionConstants.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/constant/PermissionConstants.java
@@ -4,7 +4,7 @@
 import android.Manifest.permission;
 import android.annotation.SuppressLint;
 import android.os.Build;
-import android.support.annotation.StringDef;
+import androidx.annotation.StringDef;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/constant/TimeConstants.java b/utilcode/lib/src/main/java/com/blankj/utilcode/constant/TimeConstants.java
index 9932037bf8..45090576e3 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/constant/TimeConstants.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/constant/TimeConstants.java
@@ -1,6 +1,6 @@
 package com.blankj.utilcode.constant;
 
-import android.support.annotation.IntDef;
+import androidx.annotation.IntDef;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ActivityUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ActivityUtils.java
index d6a671e4fe..de1bfeb005 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ActivityUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ActivityUtils.java
@@ -10,14 +10,15 @@
 import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.os.Bundle;
-import android.support.annotation.AnimRes;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.v4.app.ActivityOptionsCompat;
-import android.support.v4.util.Pair;
 import android.util.Log;
 import android.view.View;
 
+import androidx.annotation.AnimRes;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.app.ActivityOptionsCompat;
+import androidx.core.util.Pair;
+
 import java.util.List;
 
 /**
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/AntiShakeUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/AntiShakeUtils.java
index 7e87e73474..ca9036225e 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/AntiShakeUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/AntiShakeUtils.java
@@ -1,9 +1,10 @@
 package com.blankj.utilcode.util;
 
-import android.support.annotation.IntRange;
-import android.support.annotation.NonNull;
 import android.view.View;
 
+import androidx.annotation.IntRange;
+import androidx.annotation.NonNull;
+
 /**
  * 
  *     author: blankj
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/AppUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/AppUtils.java
index a9368be59f..5a9194ce66 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/AppUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/AppUtils.java
@@ -17,8 +17,6 @@
 import android.net.Uri;
 import android.os.Build;
 import android.provider.Settings;
-import android.support.annotation.NonNull;
-import android.support.v4.content.FileProvider;
 import android.util.Log;
 
 import java.io.File;
@@ -27,6 +25,9 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import androidx.annotation.NonNull;
+import androidx.core.content.FileProvider;
+
 /**
  * 
  *     author: Blankj
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/BarUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/BarUtils.java
index 7b5509b2b5..22178a5c20 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/BarUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/BarUtils.java
@@ -8,11 +8,6 @@
 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.util.TypedValue;
 import android.view.Display;
@@ -27,6 +22,12 @@
 
 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;
 
 /**
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/BrightnessUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/BrightnessUtils.java
index f9344b0a59..bacc519540 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/BrightnessUtils.java
+++ b/utilcode/lib/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
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/BusUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/BusUtils.java
index f04202043e..d272c99b98 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/BusUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/BusUtils.java
@@ -16,11 +16,12 @@
 import android.os.Message;
 import android.os.Messenger;
 import android.os.RemoteException;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
 import android.text.TextUtils;
 import android.util.Log;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheDiskStaticUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheDiskStaticUtils.java
index bb48a4b5cf..c5a9a17a6d 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheDiskStaticUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheDiskStaticUtils.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/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheDiskUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheDiskUtils.java
index 67e6b3fb0e..a8ae8afa5b 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheDiskUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheDiskUtils.java
@@ -8,9 +8,10 @@
 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;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheDoubleStaticUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheDoubleStaticUtils.java
index 2ef267bd01..6dbb9f7475 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheDoubleStaticUtils.java
+++ b/utilcode/lib/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/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheDoubleUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheDoubleUtils.java
index c800423c78..aca1c25837 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheDoubleUtils.java
+++ b/utilcode/lib/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;
 
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheMemoryStaticUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheMemoryStaticUtils.java
index 56abfba117..aedcfa7fc4 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheMemoryStaticUtils.java
+++ b/utilcode/lib/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/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheMemoryUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheMemoryUtils.java
index d0e06e394d..ddaa2baed9 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/CacheMemoryUtils.java
+++ b/utilcode/lib/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/utilcode/lib/src/main/java/com/blankj/utilcode/util/ColorUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ColorUtils.java
index 4c0c22232b..a6603cfc44 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ColorUtils.java
+++ b/utilcode/lib/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;
 
 /**
  * 
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/CrashUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/CrashUtils.java
index 18b5f814a3..081dd09761 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/CrashUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/CrashUtils.java
@@ -5,8 +5,8 @@
 import android.content.pm.PackageManager;
 import android.os.Build;
 import android.os.Environment;
-import android.support.annotation.NonNull;
-import android.support.annotation.RequiresPermission;
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresPermission;
 import android.util.Log;
 
 import java.io.BufferedWriter;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/DeviceUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/DeviceUtils.java
index e6b1910cfc..c641c9bdae 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/DeviceUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/DeviceUtils.java
@@ -11,11 +11,12 @@
 import android.os.Debug;
 import android.os.PowerManager;
 import android.provider.Settings;
-import android.support.annotation.RequiresApi;
-import android.support.annotation.RequiresPermission;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 
+import androidx.annotation.RequiresApi;
+import androidx.annotation.RequiresPermission;
+
 import java.io.File;
 import java.net.InetAddress;
 import java.net.NetworkInterface;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/FragmentUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/FragmentUtils.java
index 43b8537e75..9e8ae14ef1 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/FragmentUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/FragmentUtils.java
@@ -3,16 +3,6 @@
 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;
 
@@ -20,6 +10,17 @@
 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
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ImageUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ImageUtils.java
index 83e01eb1ad..cbee7dd4bd 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ImageUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ImageUtils.java
@@ -27,13 +27,13 @@
 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 androidx.annotation.ColorInt;
+import androidx.annotation.DrawableRes;
+import androidx.annotation.FloatRange;
+import androidx.annotation.IntRange;
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresApi;
+import androidx.core.content.ContextCompat;
 import android.view.View;
 
 import java.io.BufferedOutputStream;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/IntentUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/IntentUtils.java
index 6faa37d043..1e26dc8a9a 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/IntentUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/IntentUtils.java
@@ -8,8 +8,8 @@
 import android.os.Bundle;
 import android.provider.MediaStore;
 import android.provider.Settings;
-import android.support.annotation.RequiresPermission;
-import android.support.v4.content.FileProvider;
+import androidx.annotation.RequiresPermission;
+import androidx.core.content.FileProvider;
 
 import java.io.File;
 import java.util.ArrayList;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/KeyboardUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/KeyboardUtils.java
index cfa568fa7c..de3eb285cc 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/KeyboardUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/KeyboardUtils.java
@@ -7,7 +7,6 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.ResultReceiver;
-import android.support.annotation.NonNull;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewTreeObserver.OnGlobalLayoutListener;
@@ -16,6 +15,8 @@
 import android.view.inputmethod.InputMethodManager;
 import android.widget.FrameLayout;
 
+import androidx.annotation.NonNull;
+
 import java.lang.reflect.Field;
 
 /**
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/LogUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/LogUtils.java
index 1372ecd40b..9a7e11cbf5 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/LogUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/LogUtils.java
@@ -10,10 +10,10 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Environment;
-import android.support.annotation.IntDef;
-import android.support.annotation.IntRange;
-import android.support.annotation.RequiresApi;
-import android.support.v4.util.SimpleArrayMap;
+import androidx.annotation.IntDef;
+import androidx.annotation.IntRange;
+import androidx.annotation.RequiresApi;
+import androidx.collection.SimpleArrayMap;
 import android.util.Log;
 
 import com.google.gson.Gson;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/MetaDataUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/MetaDataUtils.java
index 6f6cf85b80..bd4b8da935 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/MetaDataUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/MetaDataUtils.java
@@ -8,7 +8,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
 
 /**
  * 
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/NetworkUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/NetworkUtils.java
index d59eb28240..24a05a26b7 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/NetworkUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/NetworkUtils.java
@@ -7,13 +7,14 @@
 import android.net.NetworkInfo;
 import android.net.wifi.WifiManager;
 import android.os.Build;
-import android.support.annotation.NonNull;
-import android.support.annotation.RequiresPermission;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.text.format.Formatter;
 import android.util.Log;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresPermission;
+
 import java.lang.reflect.Method;
 import java.net.InetAddress;
 import java.net.InterfaceAddress;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/NotificationUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/NotificationUtils.java
index b8163d2e66..73a900b465 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/NotificationUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/NotificationUtils.java
@@ -5,9 +5,9 @@
 import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
-import android.support.annotation.Nullable;
-import android.support.v4.app.NotificationCompat;
-import android.support.v4.app.NotificationManagerCompat;
+import androidx.annotation.Nullable;
+import androidx.core.app.NotificationCompat;
+import androidx.core.app.NotificationManagerCompat;
 
 /**
  * 
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ObjectUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ObjectUtils.java
index be5491ece0..3c0c087a39 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ObjectUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ObjectUtils.java
@@ -1,9 +1,9 @@
 package com.blankj.utilcode.util;
 
 import android.os.Build;
-import android.support.annotation.RequiresApi;
-import android.support.v4.util.LongSparseArray;
-import android.support.v4.util.SimpleArrayMap;
+import androidx.annotation.RequiresApi;
+import androidx.collection.LongSparseArray;
+import androidx.collection.SimpleArrayMap;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/PermissionUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/PermissionUtils.java
index d35cbcc620..602efcb5db 100755
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/PermissionUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/PermissionUtils.java
@@ -9,10 +9,10 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.provider.Settings;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.annotation.RequiresApi;
-import android.support.v4.content.ContextCompat;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RequiresApi;
+import androidx.core.content.ContextCompat;
 import android.util.Log;
 import android.view.MotionEvent;
 import android.view.WindowManager;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/PhoneUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/PhoneUtils.java
index 99068781a4..f407f81b5f 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/PhoneUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/PhoneUtils.java
@@ -7,7 +7,7 @@
 import android.content.pm.PackageManager;
 import android.net.Uri;
 import android.os.Build;
-import android.support.annotation.RequiresPermission;
+import androidx.annotation.RequiresPermission;
 import android.telephony.SmsManager;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ProcessUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ProcessUtils.java
index adcd265f72..619b175549 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ProcessUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ProcessUtils.java
@@ -10,8 +10,8 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.provider.Settings;
-import android.support.annotation.NonNull;
-import android.support.annotation.RequiresPermission;
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresPermission;
 import android.util.Log;
 
 import java.util.Arrays;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/RegexUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/RegexUtils.java
index ba57fab956..817a94149f 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/RegexUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/RegexUtils.java
@@ -1,6 +1,6 @@
 package com.blankj.utilcode.util;
 
-import android.support.v4.util.SimpleArrayMap;
+import androidx.collection.SimpleArrayMap;
 
 import com.blankj.utilcode.constant.RegexConstants;
 
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ResourceUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ResourceUtils.java
index 81d10f08cf..3fb515c06b 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ResourceUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ResourceUtils.java
@@ -1,6 +1,6 @@
 package com.blankj.utilcode.util;
 
-import android.support.annotation.RawRes;
+import androidx.annotation.RawRes;
 
 import java.io.BufferedOutputStream;
 import java.io.BufferedReader;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/SPStaticUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/SPStaticUtils.java
index d3e21fb873..21274c3023 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/SPStaticUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/SPStaticUtils.java
@@ -1,7 +1,7 @@
 package com.blankj.utilcode.util;
 
 import android.content.SharedPreferences;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
 
 import java.util.Map;
 import java.util.Set;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/SPUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/SPUtils.java
index 554a2ed586..a9d18a1a55 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/SPUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/SPUtils.java
@@ -3,7 +3,7 @@
 import android.annotation.SuppressLint;
 import android.content.Context;
 import android.content.SharedPreferences;
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
 
 import java.util.Collections;
 import java.util.HashMap;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ScreenUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ScreenUtils.java
index 7390fceed0..3245eb115c 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ScreenUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ScreenUtils.java
@@ -10,8 +10,8 @@
 import android.graphics.Point;
 import android.os.Build;
 import android.provider.Settings;
-import android.support.annotation.NonNull;
-import android.support.annotation.RequiresPermission;
+import androidx.annotation.NonNull;
+import androidx.annotation.RequiresPermission;
 import android.util.DisplayMetrics;
 import android.view.Surface;
 import android.view.View;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ShellUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ShellUtils.java
index b7ad2fa9d2..fc10a601ae 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ShellUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ShellUtils.java
@@ -1,6 +1,6 @@
 package com.blankj.utilcode.util;
 
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
 
 import java.io.BufferedReader;
 import java.io.DataOutputStream;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/SnackbarUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/SnackbarUtils.java
index b164e6154e..eab1990d29 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/SnackbarUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/SnackbarUtils.java
@@ -1,12 +1,12 @@
 package com.blankj.utilcode.util;
 
-import android.support.annotation.ColorInt;
-import android.support.annotation.DrawableRes;
-import android.support.annotation.IntDef;
-import android.support.annotation.IntRange;
-import android.support.annotation.LayoutRes;
-import android.support.annotation.NonNull;
-import android.support.design.widget.Snackbar;
+import androidx.annotation.ColorInt;
+import androidx.annotation.DrawableRes;
+import androidx.annotation.IntDef;
+import androidx.annotation.IntRange;
+import androidx.annotation.LayoutRes;
+import androidx.annotation.NonNull;
+import com.google.android.material.snackbar.Snackbar;
 import android.text.SpannableString;
 import android.text.Spanned;
 import android.text.style.ForegroundColorSpan;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/SpanUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/SpanUtils.java
index b8d9d53aed..4d49451ec0 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/SpanUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/SpanUtils.java
@@ -14,14 +14,14 @@
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
-import android.support.annotation.ColorInt;
-import android.support.annotation.DrawableRes;
-import android.support.annotation.FloatRange;
-import android.support.annotation.IntDef;
-import android.support.annotation.IntRange;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.v4.content.ContextCompat;
+import androidx.annotation.ColorInt;
+import androidx.annotation.DrawableRes;
+import androidx.annotation.FloatRange;
+import androidx.annotation.IntDef;
+import androidx.annotation.IntRange;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.content.ContextCompat;
 import android.text.Layout;
 import android.text.Layout.Alignment;
 import android.text.SpannableStringBuilder;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/StringUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/StringUtils.java
index c3254e3d32..70f0defe50 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/StringUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/StringUtils.java
@@ -1,8 +1,8 @@
 package com.blankj.utilcode.util;
 
 import android.content.res.Resources;
-import android.support.annotation.ArrayRes;
-import android.support.annotation.StringRes;
+import androidx.annotation.ArrayRes;
+import androidx.annotation.StringRes;
 
 /**
  * 
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ThreadUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ThreadUtils.java
index 0545a27fa0..19de94ca33 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ThreadUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ThreadUtils.java
@@ -2,10 +2,11 @@
 
 import android.os.Handler;
 import android.os.Looper;
-import android.support.annotation.IntRange;
-import android.support.annotation.NonNull;
 import android.util.Log;
 
+import androidx.annotation.IntRange;
+import androidx.annotation.NonNull;
+
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.Executor;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/TimeUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/TimeUtils.java
index adaa920474..a5286b0fbe 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/TimeUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/TimeUtils.java
@@ -1,6 +1,6 @@
 package com.blankj.utilcode.util;
 
-import android.support.annotation.NonNull;
+import androidx.annotation.NonNull;
 
 import com.blankj.utilcode.constant.TimeConstants;
 
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ToastUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ToastUtils.java
index 150425cdba..0dd47cfa3e 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/ToastUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/ToastUtils.java
@@ -12,11 +12,11 @@
 import android.os.Build;
 import android.os.Handler;
 import android.os.Message;
-import android.support.annotation.ColorInt;
-import android.support.annotation.DrawableRes;
-import android.support.annotation.LayoutRes;
-import android.support.annotation.StringRes;
-import android.support.v4.app.NotificationManagerCompat;
+import androidx.annotation.ColorInt;
+import androidx.annotation.DrawableRes;
+import androidx.annotation.LayoutRes;
+import androidx.annotation.StringRes;
+import androidx.core.app.NotificationManagerCompat;
 import android.util.Log;
 import android.view.Gravity;
 import android.view.LayoutInflater;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/UriUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/UriUtils.java
index 9ad408912a..20fdc39b81 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/UriUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/UriUtils.java
@@ -8,12 +8,14 @@
 import android.os.Environment;
 import android.provider.DocumentsContract;
 import android.provider.MediaStore;
-import android.support.annotation.NonNull;
-import android.support.v4.content.FileProvider;
+import android.text.TextUtils;
 import android.util.Log;
 
 import java.io.File;
 
+import androidx.annotation.NonNull;
+import androidx.core.content.FileProvider;
+
 /**
  * 
  *     author: Blankj
@@ -75,12 +77,19 @@ public static File uri2File(@NonNull final Uri uri) {
                 Log.d("UriUtils", uri.toString() + " parse failed. -> 1");
                 return null;
             } else if ("com.android.providers.downloads.documents".equals(authority)) {
-                final String id = DocumentsContract.getDocumentId(uri);
-                final Uri contentUri = ContentUris.withAppendedId(
-                        Uri.parse("content://downloads/public_downloads"),
-                        Long.valueOf(id)
-                );
-                return getFileFromUri(contentUri, 2);
+                String id = DocumentsContract.getDocumentId(uri);
+                if (!TextUtils.isEmpty(id)) {
+                    if (id.startsWith("raw:")) {
+                        return new File(id.substring(4));
+                    }
+                    final Uri contentUri = ContentUris.withAppendedId(
+                            Uri.parse(Environment.DIRECTORY_DOWNLOADS),
+                            Long.valueOf(id)
+                    );
+                    return getFileFromUri(contentUri, 2);
+                }
+                Log.d("UriUtils", uri.toString() + " parse failed. -> 3");
+                return null;
             } else if ("com.android.providers.media.documents".equals(authority)) {
                 final String docId = DocumentsContract.getDocumentId(uri);
                 final String[] split = docId.split(":");
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/Utils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/Utils.java
index d0c98afc96..1992a2c902 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/Utils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/Utils.java
@@ -13,13 +13,14 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
-import android.support.v4.content.FileProvider;
 import android.text.TextUtils;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.view.View;
 import android.view.inputmethod.InputMethodManager;
 
+import androidx.core.content.FileProvider;
+
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileReader;
diff --git a/utilcode/lib/src/main/java/com/blankj/utilcode/util/VibrateUtils.java b/utilcode/lib/src/main/java/com/blankj/utilcode/util/VibrateUtils.java
index a57bbb8241..622d657817 100644
--- a/utilcode/lib/src/main/java/com/blankj/utilcode/util/VibrateUtils.java
+++ b/utilcode/lib/src/main/java/com/blankj/utilcode/util/VibrateUtils.java
@@ -2,7 +2,7 @@
 
 import android.content.Context;
 import android.os.Vibrator;
-import android.support.annotation.RequiresPermission;
+import androidx.annotation.RequiresPermission;
 
 import static android.Manifest.permission.VIBRATE;
 
diff --git a/utilcode/lib/src/test/java/com/blankj/utilcode/util/BaseTest.java b/utilcode/lib/src/test/java/com/blankj/utilcode/util/BaseTest.java
index 85bc9d8ac2..2dadedff8c 100644
--- a/utilcode/lib/src/test/java/com/blankj/utilcode/util/BaseTest.java
+++ b/utilcode/lib/src/test/java/com/blankj/utilcode/util/BaseTest.java
@@ -1,8 +1,5 @@
 package com.blankj.utilcode.util;
 
-
-import android.support.annotation.NonNull;
-
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.RobolectricTestRunner;
@@ -29,7 +26,7 @@ public BaseTest() {
         ShadowLog.stream = System.out;
         ThreadUtils.setDeliver(new Executor() {
             @Override
-            public void execute(@NonNull Runnable command) {
+            public void execute(Runnable command) {
                 command.run();
             }
         });
@@ -201,8 +198,8 @@ public void onFail(Throwable t) {
     static class Person implements Comparable {
 
         String name;
-        int age;
-        int time;
+        int    age;
+        int    time;
 
         public Person(String name) {
             this.name = name;
@@ -220,7 +217,7 @@ public String toString() {
         }
 
         @Override
-        public int compareTo(@NonNull Person o) {
+        public int compareTo(Person o) {
             int res = o.age - age;
             if (res != 0) {
                 return res;
diff --git a/utilcode/lib/src/test/java/com/blankj/utilcode/util/ObjectUtilsTest.java b/utilcode/lib/src/test/java/com/blankj/utilcode/util/ObjectUtilsTest.java
index a0203f78fc..ed12c24d8d 100644
--- a/utilcode/lib/src/test/java/com/blankj/utilcode/util/ObjectUtilsTest.java
+++ b/utilcode/lib/src/test/java/com/blankj/utilcode/util/ObjectUtilsTest.java
@@ -1,7 +1,5 @@
 package com.blankj.utilcode.util;
 
-import android.support.v4.util.LongSparseArray;
-import android.support.v4.util.SimpleArrayMap;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
@@ -12,6 +10,9 @@
 import java.util.HashMap;
 import java.util.LinkedList;
 
+import androidx.collection.LongSparseArray;
+import androidx.collection.SimpleArrayMap;
+
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
diff --git a/utilcode/pkg/build.gradle b/utilcode/pkg/build.gradle
index 9fe360a5dd..881637b34a 100644
--- a/utilcode/pkg/build.gradle
+++ b/utilcode/pkg/build.gradle
@@ -4,5 +4,5 @@ apply {
 
 dependencies {
     implementation fileTree(dir: 'libs', include: ['*.jar'])
-    api project(':lib:base')
+    api gradle.ext.dep.lib_base
 }
\ No newline at end of file
diff --git a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/activity/ActivityActivity.kt b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/activity/ActivityActivity.kt
index e784f98401..9982c948b7 100644
--- a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/activity/ActivityActivity.kt
+++ b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/activity/ActivityActivity.kt
@@ -6,7 +6,7 @@ import android.graphics.Bitmap
 import android.graphics.drawable.BitmapDrawable
 import android.os.Build
 import android.os.Bundle
-import android.support.v4.app.ActivityOptionsCompat
+import androidx.core.app.ActivityOptionsCompat
 import android.view.View
 import android.view.Window
 import com.blankj.lib.base.BaseTitleActivity
diff --git a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/activity/SubActivityActivity.kt b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/activity/SubActivityActivity.kt
index 0c63773639..abf0151bbc 100644
--- a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/activity/SubActivityActivity.kt
+++ b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/activity/SubActivityActivity.kt
@@ -2,7 +2,7 @@ package com.blankj.utilcode.pkg.feature.activity
 
 import android.os.Build
 import android.os.Bundle
-import android.support.v4.app.ActivityCompat
+import androidx.core.app.ActivityCompat
 import android.view.View
 import android.view.Window
 import com.blankj.lib.base.BaseTitleActivity
diff --git a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/BarStatusFragmentActivity.kt b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/BarStatusFragmentActivity.kt
index d4f0d60530..fc8020b3e5 100644
--- a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/BarStatusFragmentActivity.kt
+++ b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/BarStatusFragmentActivity.kt
@@ -3,10 +3,10 @@ package com.blankj.utilcode.pkg.feature.bar
 import android.content.Context
 import android.content.Intent
 import android.os.Bundle
-import android.support.design.widget.BottomNavigationView
-import android.support.v4.app.Fragment
-import android.support.v4.app.FragmentPagerAdapter
-import android.support.v4.view.ViewPager
+import com.google.android.material.bottomnavigation.BottomNavigationView
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.FragmentPagerAdapter
+import androidx.viewpager.widget.ViewPager
 import android.view.View
 import com.blankj.lib.base.BaseActivity
 import com.blankj.utilcode.pkg.R
@@ -37,7 +37,7 @@ class BarStatusFragmentActivity : BaseActivity() {
             R.id.barStatusFragmentNavigationCustom
     )
 
-    private val mFragmentList = ArrayList()
+    private val mFragmentList = ArrayList()
 
     private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener l@{ item ->
         when (item.itemId) {
@@ -78,8 +78,8 @@ class BarStatusFragmentActivity : BaseActivity() {
         mFragmentList.add(BarStatusCustomFragment.newInstance())
 
         barStatusFragmentVp.offscreenPageLimit = 3
-        barStatusFragmentVp.adapter = object : FragmentPagerAdapter(supportFragmentManager) {
-            override fun getItem(position: Int): Fragment {
+        barStatusFragmentVp.adapter = object : androidx.fragment.app.FragmentPagerAdapter(supportFragmentManager) {
+            override fun getItem(position: Int): androidx.fragment.app.Fragment {
                 return mFragmentList[position]
             }
 
@@ -88,7 +88,7 @@ class BarStatusFragmentActivity : BaseActivity() {
             }
         }
 
-        barStatusFragmentVp.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
+        barStatusFragmentVp.addOnPageChangeListener(object : androidx.viewpager.widget.ViewPager.OnPageChangeListener {
             override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
 
             override fun onPageSelected(position: Int) {
diff --git a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/fragment/ContainerFragment.kt b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/fragment/ContainerFragment.kt
index ada9dd0d10..86972c449d 100644
--- a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/fragment/ContainerFragment.kt
+++ b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/fragment/ContainerFragment.kt
@@ -2,8 +2,8 @@ package com.blankj.utilcode.pkg.feature.fragment
 
 import android.os.Build
 import android.os.Bundle
-import android.support.annotation.RequiresApi
-import android.support.v4.app.Fragment
+import androidx.annotation.RequiresApi
+import androidx.fragment.app.Fragment
 import android.transition.*
 import android.view.View
 import com.blankj.lib.base.BaseLazyFragment
@@ -128,7 +128,7 @@ class ContainerFragment : BaseLazyFragment(), FragmentUtils.OnBackClickListener
         }
     }
 
-    private fun addSharedElement(fragment: Fragment): Fragment {
+    private fun addSharedElement(fragment: androidx.fragment.app.Fragment): androidx.fragment.app.Fragment {
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
             fragment.sharedElementEnterTransition = DetailTransition()
             fragment.enterTransition = Fade()
diff --git a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/fragment/FragmentActivity.kt b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/fragment/FragmentActivity.kt
index 446271b366..b18a2e236b 100644
--- a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/fragment/FragmentActivity.kt
+++ b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/fragment/FragmentActivity.kt
@@ -4,8 +4,8 @@ import android.content.Context
 import android.content.Intent
 import android.os.Bundle
 import android.os.PersistableBundle
-import android.support.design.widget.BottomNavigationView
-import android.support.v4.app.Fragment
+import com.google.android.material.bottomnavigation.BottomNavigationView
+import androidx.fragment.app.Fragment
 import android.view.View
 import com.blankj.lib.base.BaseActivity
 import com.blankj.utilcode.pkg.R
@@ -29,7 +29,7 @@ class FragmentActivity : BaseActivity() {
         }
     }
 
-    private val mFragments = arrayListOf()
+    private val mFragments = arrayListOf()
     private var curIndex: Int = 0
 
     private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
diff --git a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/image/ImageActivity.kt b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/image/ImageActivity.kt
index 0e092e0062..2c6656f220 100644
--- a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/image/ImageActivity.kt
+++ b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/image/ImageActivity.kt
@@ -6,12 +6,12 @@ import android.graphics.Bitmap
 import android.graphics.Color
 import android.os.Build
 import android.os.Bundle
-import android.support.annotation.StringRes
-import android.support.v7.widget.LinearLayoutManager
 import android.view.View
 import android.widget.Button
 import android.widget.ImageView
 import android.widget.TextView
+import androidx.annotation.StringRes
+import androidx.recyclerview.widget.LinearLayoutManager
 import com.blankj.lib.base.BaseTaskActivity
 import com.blankj.lib.base.rv.BaseAdapter
 import com.blankj.lib.base.rv.BaseCell
diff --git a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/snackbar/SnackbarActivity.kt b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/snackbar/SnackbarActivity.kt
index a0ea36d528..cd1c1b0d99 100644
--- a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/snackbar/SnackbarActivity.kt
+++ b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/snackbar/SnackbarActivity.kt
@@ -4,7 +4,7 @@ import android.content.Context
 import android.content.Intent
 import android.graphics.Color
 import android.os.Bundle
-import android.support.annotation.StringRes
+import androidx.annotation.StringRes
 import android.text.SpannableStringBuilder
 import android.view.View
 import android.view.ViewGroup
diff --git a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/span/SpanActivity.kt b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/span/SpanActivity.kt
index d84ced168c..202069ed61 100644
--- a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/span/SpanActivity.kt
+++ b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/span/SpanActivity.kt
@@ -5,7 +5,7 @@ import android.content.Context
 import android.content.Intent
 import android.graphics.*
 import android.os.Bundle
-import android.support.annotation.ColorInt
+import androidx.annotation.ColorInt
 import android.text.Layout
 import android.text.SpannableStringBuilder
 import android.text.TextPaint
diff --git a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/toast/CustomToast.kt b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/toast/CustomToast.kt
index 314ba33d59..458ecbb3fb 100644
--- a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/toast/CustomToast.kt
+++ b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/toast/CustomToast.kt
@@ -2,7 +2,7 @@ package com.blankj.utilcode.pkg.feature.toast
 
 import android.os.Handler
 import android.os.Looper
-import android.support.annotation.StringRes
+import androidx.annotation.StringRes
 import android.widget.TextView
 import android.widget.Toast
 
diff --git a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/toast/ToastActivity.kt b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/toast/ToastActivity.kt
index 51c9e53774..47f91e826e 100644
--- a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/toast/ToastActivity.kt
+++ b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/toast/ToastActivity.kt
@@ -4,7 +4,7 @@ import android.content.Context
 import android.content.Intent
 import android.graphics.Color
 import android.os.Bundle
-import android.support.v4.content.ContextCompat
+import androidx.core.content.ContextCompat
 import android.view.Gravity
 import android.view.View
 import com.blankj.lib.base.BaseTitleActivity
diff --git a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/helper/DialogHelper.kt b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/helper/DialogHelper.kt
index 344a69e448..a495a13013 100644
--- a/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/helper/DialogHelper.kt
+++ b/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/helper/DialogHelper.kt
@@ -3,7 +3,6 @@ package com.blankj.utilcode.pkg.helper
 import android.app.Dialog
 import android.graphics.Bitmap
 import android.graphics.drawable.ColorDrawable
-import android.support.v7.app.AlertDialog
 import android.text.method.ScrollingMovementMethod
 import android.view.Gravity
 import android.view.LayoutInflater
@@ -12,9 +11,9 @@ import android.widget.Button
 import android.widget.EditText
 import android.widget.ImageView
 import android.widget.TextView
+import androidx.appcompat.app.AlertDialog
 import com.blankj.utilcode.pkg.R
 import com.blankj.utilcode.util.*
-import com.blankj.utilcode.util.PermissionUtils.OnRationaleListener.ShouldRequest
 
 /**
  * ```
@@ -26,7 +25,7 @@ import com.blankj.utilcode.util.PermissionUtils.OnRationaleListener.ShouldReques
  */
 object DialogHelper {
 
-    fun showRationaleDialog(shouldRequest: ShouldRequest) {
+    fun showRationaleDialog(shouldRequest: PermissionUtils.OnRationaleListener.ShouldRequest) {
         val topActivity = ActivityUtils.getTopActivity()
         AlertDialog.Builder(topActivity)
                 .setTitle(android.R.string.dialog_alert_title)
diff --git a/utilcode/pkg/src/main/res/layout/activity_adaptscreen.xml b/utilcode/pkg/src/main/res/layout/activity_adaptscreen.xml
index 792ae5672e..9be8749952 100644
--- a/utilcode/pkg/src/main/res/layout/activity_adaptscreen.xml
+++ b/utilcode/pkg/src/main/res/layout/activity_adaptscreen.xml
@@ -1,5 +1,5 @@
 
-
 
-
+
diff --git a/utilcode/pkg/src/main/res/layout/activity_adaptscreen_close.xml b/utilcode/pkg/src/main/res/layout/activity_adaptscreen_close.xml
index ccc88dddb6..1522b0741b 100644
--- a/utilcode/pkg/src/main/res/layout/activity_adaptscreen_close.xml
+++ b/utilcode/pkg/src/main/res/layout/activity_adaptscreen_close.xml
@@ -8,7 +8,7 @@
     android:fillViewport="true"
     tools:context=".feature.adaptScreen.AdaptCloseActivity">
 
-    
 
@@ -43,6 +43,6 @@
             android:textSize="30pt"
             app:layout_constraintTop_toBottomOf="@id/adaptScreenCloseAdaptDpTv" />
 
-    
+    
 
 
\ No newline at end of file
diff --git a/utilcode/pkg/src/main/res/layout/activity_adaptscreen_height.xml b/utilcode/pkg/src/main/res/layout/activity_adaptscreen_height.xml
index 350921b04d..75fa87e8e5 100644
--- a/utilcode/pkg/src/main/res/layout/activity_adaptscreen_height.xml
+++ b/utilcode/pkg/src/main/res/layout/activity_adaptscreen_height.xml
@@ -1,13 +1,12 @@
 
-
 
-    
 
@@ -94,6 +93,6 @@
                 android:textSize="30pt" />
         
 
-    
+    
 
 
\ No newline at end of file
diff --git a/utilcode/pkg/src/main/res/layout/activity_adaptscreen_width.xml b/utilcode/pkg/src/main/res/layout/activity_adaptscreen_width.xml
index 121415e1b6..dd9f9f40c7 100644
--- a/utilcode/pkg/src/main/res/layout/activity_adaptscreen_width.xml
+++ b/utilcode/pkg/src/main/res/layout/activity_adaptscreen_width.xml
@@ -8,7 +8,7 @@
     android:fillViewport="true"
     tools:context=".feature.adaptScreen.AdaptWidthActivity">
 
-    
 
@@ -149,6 +149,6 @@
 
         
 
-    
+    
 
 
\ No newline at end of file
diff --git a/utilcode/pkg/src/main/res/layout/activity_bar_status_fragment.xml b/utilcode/pkg/src/main/res/layout/activity_bar_status_fragment.xml
index 3ce196004b..bd6e43e7a7 100644
--- a/utilcode/pkg/src/main/res/layout/activity_bar_status_fragment.xml
+++ b/utilcode/pkg/src/main/res/layout/activity_bar_status_fragment.xml
@@ -6,7 +6,7 @@
     android:layout_height="match_parent"
     android:orientation="vertical">
 
-    
 
-    
 
-    
-
Date: Sat, 29 Jun 2019 19:59:42 +0800
Subject: [PATCH 05/44] see 06/29 log

---
 .../test/java/com/blankj/utilcode/util/TimeUtilsTest.java    | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/utilcode/lib/src/test/java/com/blankj/utilcode/util/TimeUtilsTest.java b/utilcode/lib/src/test/java/com/blankj/utilcode/util/TimeUtilsTest.java
index 2ba0a41586..5ab8ee17eb 100644
--- a/utilcode/lib/src/test/java/com/blankj/utilcode/util/TimeUtilsTest.java
+++ b/utilcode/lib/src/test/java/com/blankj/utilcode/util/TimeUtilsTest.java
@@ -42,15 +42,14 @@ public class TimeUtilsTest  {
     public void millis2String() {
         assertEquals(timeString, TimeUtils.millis2String(timeMillis));
         assertEquals(timeStringFormat, TimeUtils.millis2String(timeMillis, mFormat));
-        assertEquals("2017年05月04日", TimeUtils.millis2String(timeMillis, "yyyy年MM月dd日"));
-        assertEquals("16时37分", TimeUtils.millis2String(timeMillis, "HH时mm分"));
+        assertEquals(timeStringFormat, TimeUtils.millis2String(timeMillis, "yyyy MM dd HH:mm:ss"));
     }
 
     @Test
     public void string2Millis() {
         assertEquals(timeMillis, TimeUtils.string2Millis(timeString));
         assertEquals(timeMillis, TimeUtils.string2Millis(timeStringFormat, mFormat));
-        assertEquals(timeMillis, TimeUtils.string2Millis(timeStringFormat, "yyyy年MM月dd日HH时mm分"));
+        assertEquals(timeMillis, TimeUtils.string2Millis(timeStringFormat, "yyyy MM dd HH:mm:ss"));
     }
 
     @Test

From 40c0e36fbb1dc33ebce09a6fa162e07380271cf9 Mon Sep 17 00:00:00 2001
From: Blankj <625783482@qq.com>
Date: Thu, 15 Aug 2019 01:36:03 +0800
Subject: [PATCH 06/44] see 08/15 log

---
 lib/utilcode/README-CN.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/utilcode/README-CN.md b/lib/utilcode/README-CN.md
index d610595e3c..cce78181fc 100644
--- a/lib/utilcode/README-CN.md
+++ b/lib/utilcode/README-CN.md
@@ -1185,7 +1185,7 @@ getComments       : 获取压缩文件中的注释链表
 [log.demo]: https://github.com/Blankj/AndroidUtilCode/blob/master/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/log/LogActivity.kt
 
 [map.java]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/main/java/com/blankj/utilcode/util/MapUtils.java
-[map.demo]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/test/java/com/blankj/utilcode/util/MapUtilsTest.java
+[map.test]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/test/java/com/blankj/utilcode/util/MapUtilsTest.java
 
 [metaData.java]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/src/main/java/com/blankj/utilcode/util/MetaDataUtils.java
 [metaData.demo]: https://github.com/Blankj/AndroidUtilCode/blob/master/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/metaData/MetaDataActivity.kt

From 73dc60c4cdfa10a2b296df3e28ce9af2784be582 Mon Sep 17 00:00:00 2001
From: Blankj <625783482@qq.com>
Date: Sat, 30 Nov 2019 13:03:30 +0800
Subject: [PATCH 07/44] see 11/30 log

---
 buildSrc/src/main/groovy/Config.groovy                        | 2 +-
 config.json                                                   | 2 +-
 .../pkg/src/main/java/com/blankj/main/pkg/MainActivity.kt     | 2 +-
 .../utilcode/pkg/feature/reflect/TestPrivateStaticFinal.java  | 2 +-
 lib/base/build.gradle                                         | 2 +-
 lib/subutil/build.gradle                                      | 4 ++--
 lib/utildebug/build.gradle                                    | 2 +-
 7 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/buildSrc/src/main/groovy/Config.groovy b/buildSrc/src/main/groovy/Config.groovy
index 03181d7927..cc279262a8 100644
--- a/buildSrc/src/main/groovy/Config.groovy
+++ b/buildSrc/src/main/groovy/Config.groovy
@@ -41,7 +41,7 @@ class Config {
             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_utilcodex              : new DepConfig(true, true, ":lib:utilcodex", "com.blankj:utilcodex: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*/
diff --git a/config.json b/config.json
index 188e2ff509..630e76de6a 100644
--- a/config.json
+++ b/config.json
@@ -20,7 +20,7 @@
     {"isApply": true, "useLocal": true, "localPath": ":lib:base"},
     {"isApply": true, "useLocal": true, "localPath": ":lib:common"},
     {"isApply": true, "useLocal": true, "localPath": ":lib:subutil"},
-    {"isApply": true, "useLocal": true, "localPath": ":lib:utilcode", "remotePath": "com.blankj:utilcode:1.26.0"},
+    {"isApply": true, "useLocal": true, "localPath": ":lib:utilcodex", "remotePath": "com.blankj:utilcodex:1.26.0"},
     {"isApply": true, "useLocal": true, "localPath": ":lib:utildebug", "remotePath": "com.blankj:utildebug:1.25.10-alpha5"},
     {"isApply": true, "useLocal": true, "localPath": ":lib:utildebug-no-op", "remotePath": "com.blankj:utildebug-no-op:1.25.10-alpha5"}
   ]
diff --git a/feature/main/pkg/src/main/java/com/blankj/main/pkg/MainActivity.kt b/feature/main/pkg/src/main/java/com/blankj/main/pkg/MainActivity.kt
index fb45369c5b..ccce008ded 100644
--- a/feature/main/pkg/src/main/java/com/blankj/main/pkg/MainActivity.kt
+++ b/feature/main/pkg/src/main/java/com/blankj/main/pkg/MainActivity.kt
@@ -2,8 +2,8 @@ package com.blankj.main.pkg
 
 import android.graphics.Color
 import android.os.Bundle
-import androidx.appcompat.app.ActionBarDrawerToggle
 import android.view.View
+import androidx.appcompat.app.ActionBarDrawerToggle
 import com.blankj.common.activity.CommonActivity
 import com.blankj.common.item.CommonItem
 import com.blankj.common.item.CommonItemClick
diff --git a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/reflect/TestPrivateStaticFinal.java b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/reflect/TestPrivateStaticFinal.java
index e62c518699..b7efb5f4d7 100644
--- a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/reflect/TestPrivateStaticFinal.java
+++ b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/reflect/TestPrivateStaticFinal.java
@@ -1,6 +1,6 @@
 package com.blankj.utilcode.pkg.feature.reflect;
 
-import android.support.annotation.Keep;
+import androidx.annotation.Keep;
 
 /**
  * 
diff --git a/lib/base/build.gradle b/lib/base/build.gradle
index 2285071b5e..6fffd3af61 100644
--- a/lib/base/build.gradle
+++ b/lib/base/build.gradle
@@ -1,7 +1,7 @@
 dependencies {
     implementation fileTree(include: ['*.jar'], dir: 'libs')
     api Config.depConfig.lib_subutil.dep
-    api Config.depConfig.lib_utilcode.dep
+    api Config.depConfig.lib_utilcodex.dep
 
     api Config.depConfig.support_appcompat.dep
     api Config.depConfig.support_material.dep
diff --git a/lib/subutil/build.gradle b/lib/subutil/build.gradle
index 662f2a4ec7..e7eaf45da1 100644
--- a/lib/subutil/build.gradle
+++ b/lib/subutil/build.gradle
@@ -13,14 +13,14 @@ readme {
 dependencies {
     compileOnly Config.depConfig.support_appcompat.dep
     compileOnly Config.depConfig.support_material.dep
-    compileOnly Config.depConfig.lib_utilcode.dep
+    compileOnly Config.depConfig.lib_utilcodex.dep
     api(Config.depConfig.glide.dep) {
         exclude group: "com.android.support"
     }
     api Config.depConfig.retrofit.dep
     api Config.depConfig.gson.dep
 
-    testImplementation Config.depConfig.lib_utilcode.dep
+    testImplementation Config.depConfig.lib_utilcodex.dep
     testImplementation Config.depConfig.test_junit.dep
     testImplementation Config.depConfig.test_robolectric.dep
 }
\ No newline at end of file
diff --git a/lib/utildebug/build.gradle b/lib/utildebug/build.gradle
index b6380100bb..558735162a 100644
--- a/lib/utildebug/build.gradle
+++ b/lib/utildebug/build.gradle
@@ -5,7 +5,7 @@ apply {
 }
 
 dependencies {
-    implementation Config.depConfig.lib_utilcode.dep
+    implementation Config.depConfig.lib_utilcodex.dep
     implementation Config.depConfig.swipe_panel.dep
     implementation Config.depConfig.photo_view.dep
     compileOnly Config.depConfig.support_appcompat.dep

From 3fd7a91e0e3bbd2ddbaf2b79163527b02dcc87d9 Mon Sep 17 00:00:00 2001
From: Blankj 
Date: Tue, 7 Apr 2020 00:11:37 +0800
Subject: [PATCH 08/44] see 04/07 log

---
 lib/utildebug/build.gradle | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lib/utildebug/build.gradle b/lib/utildebug/build.gradle
index b733473cf1..6e1157ef0b 100644
--- a/lib/utildebug/build.gradle
+++ b/lib/utildebug/build.gradle
@@ -9,4 +9,8 @@ dependencies {
     testImplementation Config.depConfig.test_junit.dep
     testImplementation Config.depConfig.test_robolectric.dep
     testImplementation Config.depConfig.support_appcompat.dep
+}
+
+afterEvaluate {
+    verifyReleaseResources.enabled(false)
 }
\ No newline at end of file

From 96c45acb8eb47a58c84bb467e6b126500765f5b2 Mon Sep 17 00:00:00 2001
From: Blankj 
Date: Tue, 7 Apr 2020 17:21:35 +0800
Subject: [PATCH 09/44] see 04/07 log

---
 .../src/test/java/com/blankj/utilcode/util/BaseTest.java  | 8 +++++---
 .../java/com/blankj/utilcode/util/UiMessageUtilsTest.java | 3 ++-
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/lib/utilcode/src/test/java/com/blankj/utilcode/util/BaseTest.java b/lib/utilcode/src/test/java/com/blankj/utilcode/util/BaseTest.java
index 6e097938bf..ebaa83564d 100644
--- a/lib/utilcode/src/test/java/com/blankj/utilcode/util/BaseTest.java
+++ b/lib/utilcode/src/test/java/com/blankj/utilcode/util/BaseTest.java
@@ -1,7 +1,5 @@
 package com.blankj.utilcode.util;
 
-import android.support.annotation.NonNull;
-import java.util.concurrent.Executor;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.RobolectricTestRunner;
@@ -9,6 +7,10 @@
 import org.robolectric.annotation.Config;
 import org.robolectric.shadows.ShadowLog;
 
+import java.util.concurrent.Executor;
+
+import androidx.annotation.NonNull;
+
 /**
  * 
  *     author: Blankj
@@ -18,7 +20,7 @@
  * 
*/ @RunWith(RobolectricTestRunner.class) -@Config(manifest = Config.NONE,shadows = { ShadowLog.class }) +@Config(manifest = Config.NONE, shadows = {ShadowLog.class}) public class BaseTest { @BusUtils.Bus(tag = "base") diff --git a/lib/utilcode/src/test/java/com/blankj/utilcode/util/UiMessageUtilsTest.java b/lib/utilcode/src/test/java/com/blankj/utilcode/util/UiMessageUtilsTest.java index 1ef00ee586..140dd77683 100644 --- a/lib/utilcode/src/test/java/com/blankj/utilcode/util/UiMessageUtilsTest.java +++ b/lib/utilcode/src/test/java/com/blankj/utilcode/util/UiMessageUtilsTest.java @@ -1,9 +1,10 @@ package com.blankj.utilcode.util; -import android.support.annotation.NonNull; import org.junit.Test; +import androidx.annotation.NonNull; + /** *
  *     author: blankj

From 7145da0408a6f5ed8f0bbd531245750eb1a1c75d Mon Sep 17 00:00:00 2001
From: Blankj 
Date: Tue, 5 May 2020 02:24:34 +0800
Subject: [PATCH 10/44] see 05/05 log

---
 buildSrc/src/main/groovy/Config.groovy | 8 ++++----
 lib/base/build.gradle                  | 8 ++++----
 lib/subutil/build.gradle               | 4 ++--
 lib/utilcode/build.gradle              | 8 ++++----
 lib/utildebug/build.gradle             | 6 +++---
 5 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/buildSrc/src/main/groovy/Config.groovy b/buildSrc/src/main/groovy/Config.groovy
index d8e41b3ca2..88b8eb9a5a 100644
--- a/buildSrc/src/main/groovy/Config.groovy
+++ b/buildSrc/src/main/groovy/Config.groovy
@@ -60,10 +60,10 @@ class Config {
             //./gradlew clean plugin:plugin_bus-gradle-plugin:mavenLocal     // 上传到本地 mavenLocal
             //./gradlew clean plugin:plugin_bus-gradle-plugin:bintrayUpload  // 上传到 jcenter
 
-            support_appcompat          : new DepConfig("androidx.appcompat:appcompat:$androidxVersion"),
-            support_material           : new DepConfig("com.google.android.material:material:$androidxVersion"),
-            support_multidex           : new DepConfig("com.android.support:multidex:1.0.2"),
-            support_constraint         : new DepConfig("com.android.support.constraint:constraint-layout:1.1.3"),
+            androidx_appcompat          : new DepConfig("androidx.appcompat:appcompat:$androidxVersion"),
+            androidx_material           : new DepConfig("com.google.android.material:material:$androidxVersion"),
+            androidx_multidex           : new DepConfig("androidx.multidex:multidex:2.0.0"),
+            androidx_constraint         : new DepConfig("androidx.constraintlayout:constraintlayout:1.1.3"),
 
             kotlin                     : new DepConfig("org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion"),
 
diff --git a/lib/base/build.gradle b/lib/base/build.gradle
index 9a1ac7b329..bb7fa31573 100644
--- a/lib/base/build.gradle
+++ b/lib/base/build.gradle
@@ -3,10 +3,10 @@ dependencies {
     api Config.depConfig.lib_subutil.dep
     api Config.depConfig.lib_utilcode.dep
 
-    api Config.depConfig.support_appcompat.dep
-    api Config.depConfig.support_material.dep
-    api Config.depConfig.support_multidex.dep
-    api Config.depConfig.support_constraint.dep
+    api Config.depConfig.androidx_appcompat.dep
+    api Config.depConfig.androidx_material.dep
+    api Config.depConfig.androidx_multidex.dep
+    api Config.depConfig.androidx_constraint.dep
     api Config.depConfig.kotlin.dep
     api Config.depConfig.free_proguard.dep
     api Config.depConfig.swipe_panel.dep
diff --git a/lib/subutil/build.gradle b/lib/subutil/build.gradle
index a8798fea1b..a561916f3e 100644
--- a/lib/subutil/build.gradle
+++ b/lib/subutil/build.gradle
@@ -9,8 +9,8 @@ readme {
 }
 
 dependencies {
-    compileOnly Config.depConfig.support_appcompat.dep
-    compileOnly Config.depConfig.support_material.dep
+    compileOnly Config.depConfig.androidx_appcompat.dep
+    compileOnly Config.depConfig.androidx_material.dep
     compileOnly Config.depConfig.lib_utilcode.dep
     api(Config.depConfig.glide.dep) {
         exclude group: "com.android.support"
diff --git a/lib/utilcode/build.gradle b/lib/utilcode/build.gradle
index a3ed94861c..891f7dbf40 100644
--- a/lib/utilcode/build.gradle
+++ b/lib/utilcode/build.gradle
@@ -29,13 +29,13 @@ android {
 dependencies {
     implementation Config.depConfig.gson.dep
 
-    compileOnly Config.depConfig.support_appcompat.dep
-    compileOnly Config.depConfig.support_material.dep
+    compileOnly Config.depConfig.androidx_appcompat.dep
+    compileOnly Config.depConfig.androidx_material.dep
 
     testImplementation Config.depConfig.test_junit.dep
     testImplementation Config.depConfig.test_robolectric.dep
-    testImplementation Config.depConfig.support_appcompat.dep
-    testImplementation Config.depConfig.support_material.dep
+    testImplementation Config.depConfig.androidx_appcompat.dep
+    testImplementation Config.depConfig.androidx_material.dep
     testImplementation Config.depConfig.eventbus_lib.dep
 }
 
diff --git a/lib/utildebug/build.gradle b/lib/utildebug/build.gradle
index 6e1157ef0b..82b55495b0 100644
--- a/lib/utildebug/build.gradle
+++ b/lib/utildebug/build.gradle
@@ -1,6 +1,6 @@
 dependencies {
-    compileOnly Config.depConfig.support_appcompat.dep
-    compileOnly Config.depConfig.support_material.dep
+    compileOnly Config.depConfig.androidx_appcompat.dep
+    compileOnly Config.depConfig.androidx_material.dep
 
     implementation Config.depConfig.lib_utilcode.dep
     implementation Config.depConfig.swipe_panel.dep
@@ -8,7 +8,7 @@ dependencies {
 
     testImplementation Config.depConfig.test_junit.dep
     testImplementation Config.depConfig.test_robolectric.dep
-    testImplementation Config.depConfig.support_appcompat.dep
+    testImplementation Config.depConfig.androidx_appcompat.dep
 }
 
 afterEvaluate {

From c7190639ec44b9ff4b5b35f5580458b77abd79c7 Mon Sep 17 00:00:00 2001
From: Blankj 
Date: Tue, 5 May 2020 02:26:00 +0800
Subject: [PATCH 11/44] see 05/05 log

---
 buildApp.gradle                        |  2 +-
 buildSrc/src/main/groovy/Config.groovy | 12 ++++++------
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/buildApp.gradle b/buildApp.gradle
index 2220ed6947..8cb7de95fe 100644
--- a/buildApp.gradle
+++ b/buildApp.gradle
@@ -68,7 +68,7 @@ android {
 
 dependencies {
     // LeakCanary
-    debugImplementation Config.depConfig.leakcanary_android.dep
+    debugImplementation Config.depConfig.leakcanary.dep
 
     debugImplementation Config.depConfig.lib_utildebug.dep
     releaseImplementation Config.depConfig.lib_utildebug_no_op.dep
diff --git a/buildSrc/src/main/groovy/Config.groovy b/buildSrc/src/main/groovy/Config.groovy
index 88b8eb9a5a..6074cf4d2e 100644
--- a/buildSrc/src/main/groovy/Config.groovy
+++ b/buildSrc/src/main/groovy/Config.groovy
@@ -20,7 +20,7 @@ class Config {
     // lib version
     static gradlePluginVersion = '3.5.2'
     static kotlinVersion = '1.3.50'
-    static androidxVersion = '1.0.0'
+    static androidxVersion = '1.1.0'
 
     static depConfig = [
             /*Never delete this line*/
@@ -60,14 +60,14 @@ class Config {
             //./gradlew clean plugin:plugin_bus-gradle-plugin:mavenLocal     // 上传到本地 mavenLocal
             //./gradlew clean plugin:plugin_bus-gradle-plugin:bintrayUpload  // 上传到 jcenter
 
-            androidx_appcompat          : new DepConfig("androidx.appcompat:appcompat:$androidxVersion"),
-            androidx_material           : new DepConfig("com.google.android.material:material:$androidxVersion"),
-            androidx_multidex           : new DepConfig("androidx.multidex:multidex:2.0.0"),
-            androidx_constraint         : new DepConfig("androidx.constraintlayout:constraintlayout:1.1.3"),
+            androidx_appcompat         : new DepConfig("androidx.appcompat:appcompat:$androidxVersion"),
+            androidx_material          : new DepConfig("com.google.android.material:material:$androidxVersion"),
+            androidx_multidex          : new DepConfig("androidx.multidex:multidex:2.0.0"),
+            androidx_constraint        : new DepConfig("androidx.constraintlayout:constraintlayout:1.1.3"),
 
             kotlin                     : new DepConfig("org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion"),
 
-            leakcanary_android         : new DepConfig("com.squareup.leakcanary:leakcanary-android:2.1"),
+            leakcanary                 : new DepConfig("com.squareup.leakcanary:leakcanary-android:2.1"),
 
             free_proguard              : new DepConfig("com.blankj:free-proguard:1.0.2"),
             swipe_panel                : new DepConfig("com.blankj:swipe-panel:1.2"),

From c351507a082875429db451bef2a818aead420077 Mon Sep 17 00:00:00 2001
From: Blankj 
Date: Sun, 25 Oct 2020 02:53:58 +0800
Subject: [PATCH 12/44] see 10/25 log

---
 .../com/blankj/utilcode/pkg/feature/mvp/MvpActivity.java   | 2 --
 lib/base/src/main/java/com/blankj/base/mvp/BaseModel.java  | 7 ++++---
 lib/base/src/main/java/com/blankj/base/mvp/BaseView.java   | 2 ++
 .../java/com/blankj/utilcode/util/DebouncingUtils.java     | 3 ++-
 .../src/main/java/com/blankj/utilcode/util/ViewUtils.java  | 3 ++-
 5 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/mvp/MvpActivity.java b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/mvp/MvpActivity.java
index 05ae20c92d..7fff29f4a7 100644
--- a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/mvp/MvpActivity.java
+++ b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/mvp/MvpActivity.java
@@ -1,7 +1,5 @@
 package com.blankj.utilcode.pkg.feature.mvp;
 
-import android.arch.lifecycle.ViewModel;
-import android.arch.lifecycle.ViewModelProvider;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
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 84c930fd74..2f2b81d6e0 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,11 @@
 package com.blankj.base.mvp;
 
-import android.arch.lifecycle.LiveData;
-import android.arch.lifecycle.MutableLiveData;
-import android.support.annotation.CallSuper;
 import android.util.Log;
 
+import androidx.annotation.CallSuper;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
+
 /**
  * 
  *     author: blankj
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 94f36bcdaa..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
@@ -5,10 +5,12 @@
 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;
 
 /**
  * 
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
index c9f2c8ff79..889ac86090 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/DebouncingUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/DebouncingUtils.java
@@ -1,7 +1,6 @@
 package com.blankj.utilcode.util;
 
 import android.os.SystemClock;
-import android.support.annotation.NonNull;
 import android.text.TextUtils;
 import android.view.View;
 
@@ -9,6 +8,8 @@
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
+import androidx.annotation.NonNull;
+
 /**
  * 
  *     author: Blankj
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/ViewUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/ViewUtils.java
index a06e3503bf..f0ef043322 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/ViewUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/ViewUtils.java
@@ -2,7 +2,6 @@
 
 import android.content.Context;
 import android.os.Build;
-import android.support.annotation.LayoutRes;
 import android.text.TextUtils;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -10,6 +9,8 @@
 
 import java.util.Locale;
 
+import androidx.annotation.LayoutRes;
+
 /**
  * 
  *     author: Blankj

From f14b404543d17cdba6680a78a15afdf7570a9248 Mon Sep 17 00:00:00 2001
From: jobs_xie 
Date: Thu, 22 Apr 2021 10:46:19 +0800
Subject: [PATCH 13/44] Fix: IllegalStateException: message is already in use

---
 .../src/main/java/com/blankj/utilcode/util/MessengerUtils.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/MessengerUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/MessengerUtils.java
index a764eb50b6..d1d4669dbe 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/MessengerUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/MessengerUtils.java
@@ -320,7 +320,7 @@ private void sendMsg2Client(final Message msg) {
             for (Messenger client : mClientMap.values()) {
                 try {
                     if (client != null) {
-                        client.send(msg);
+                        client.send(Message.obtain(msg));
                     }
                 } catch (RemoteException e) {
                     e.printStackTrace();

From e04bfdf9eff1cc82788a0255d38bdcb9f08180cc Mon Sep 17 00:00:00 2001
From: jobs_xie 
Date: Thu, 22 Apr 2021 10:58:44 +0800
Subject: [PATCH 14/44] Fix: IllegalStateException: message is already in use

---
 .../main/java/com/blankj/utilcode/util/MessengerUtils.java    | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/MessengerUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/MessengerUtils.java
index d1d4669dbe..61aa8e2543 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/MessengerUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/MessengerUtils.java
@@ -317,15 +317,17 @@ public int onStartCommand(Intent intent, int flags, int startId) {
         }
 
         private void sendMsg2Client(final Message msg) {
+           final Message obtain = Message.obtain(msg); //Copy the original
             for (Messenger client : mClientMap.values()) {
                 try {
                     if (client != null) {
-                        client.send(Message.obtain(msg));
+                        client.send(obtain);
                     }
                 } catch (RemoteException e) {
                     e.printStackTrace();
                 }
             }
+            obtain.recycle(); //Recycled copy
         }
 
         private void consumeServerProcessCallback(final Message msg) {

From ab073b7a4d856771822c08fbdf2a13f300420ce1 Mon Sep 17 00:00:00 2001
From: xiexin52k <517436384@qq.com>
Date: Thu, 22 Apr 2021 14:28:21 +0800
Subject: [PATCH 15/44] Update MessengerUtils.java

---
 .../src/main/java/com/blankj/utilcode/util/MessengerUtils.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/MessengerUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/MessengerUtils.java
index 61aa8e2543..71af539ab7 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/MessengerUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/MessengerUtils.java
@@ -321,7 +321,7 @@ private void sendMsg2Client(final Message msg) {
             for (Messenger client : mClientMap.values()) {
                 try {
                     if (client != null) {
-                        client.send(obtain);
+                        client.send(Message.obtain(obtain));
                     }
                 } catch (RemoteException e) {
                     e.printStackTrace();

From 20290bb808058d92cf52a2632fc463faccc10ff6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=A9=AC=E6=AD=87=E5=B0=94?= 
Date: Wed, 5 May 2021 02:51:15 +1000
Subject: [PATCH 16/44] Added 2 very useful methods

1. isFirstTimeInstall():
If you want to know whether this is the first time installation of this app in this device.
2. isAppUpgraded():
If you want to know whether the current version was installed over a previous version (update/upgrade) or if it is freshly installed (clean install).

Code:
/**
     * Return true if this is the first ever time that the application is installed on the device.
     *
     * @return true if this is the first ever time that the application is installed on the device.
     */
    public static boolean isFirstTimeInstall(){
        try {
            Long firstInstallTime = Utils.getApp().getPackageManager().getPackageInfo(this.getAppPackageName(), 0).firstInstallTime;
            Long lastUpdateTime = Utils.getApp().getPackageManager().getPackageInfo(this.getAppPackageName(), 0).lastUpdateTime;
            return firstInstallTime == lastUpdateTime;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * Return true if app was previously installed and this one is an update/upgrade to that one, returns false if this is a fresh installation and not an update/upgrade.
     *
     * @return true if app was previously installed and this one is an update/upgrade to that one, returns false if this is a fresh installation and not an update/upgrade.
     */
    public static boolean isAppUpgraded(){
        try {
            Long firstInstallTime = Utils.getApp().getPackageManager().getPackageInfo(this.getAppPackageName(), 0).firstInstallTime;
            Long lastUpdateTime = Utils.getApp().getPackageManager().getPackageInfo(this.getAppPackageName(), 0).lastUpdateTime;
            return firstInstallTime != lastUpdateTime;
        } catch (Exception e) {
            return false;
        }
    }
---
 .../com/blankj/utilcode/util/AppUtils.java    | 32 +++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/AppUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/AppUtils.java
index a8b65dfecf..1cc9112b16 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/AppUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/AppUtils.java
@@ -384,6 +384,38 @@ public static int getAppIconId(final String packageName) {
         }
     }
 
+    
+    /**
+     * Return true if this is the first ever time that the application is installed on the device.
+     *
+     * @return true if this is the first ever time that the application is installed on the device.
+     */
+    public static boolean isFirstTimeInstall(){
+        try {
+            Long firstInstallTime = Utils.getApp().getPackageManager().getPackageInfo(this.getAppPackageName(), 0).firstInstallTime;
+            Long lastUpdateTime = Utils.getApp().getPackageManager().getPackageInfo(this.getAppPackageName(), 0).lastUpdateTime;
+            return firstInstallTime == lastUpdateTime;
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    /**
+     * Return true if app was previously installed and this one is an update/upgrade to that one, returns false if this is a fresh installation and not an update/upgrade.
+     *
+     * @return true if app was previously installed and this one is an update/upgrade to that one, returns false if this is a fresh installation and not an update/upgrade.
+     */
+    public static boolean isAppUpgraded(){
+        try {
+            Long firstInstallTime = Utils.getApp().getPackageManager().getPackageInfo(this.getAppPackageName(), 0).firstInstallTime;
+            Long lastUpdateTime = Utils.getApp().getPackageManager().getPackageInfo(this.getAppPackageName(), 0).lastUpdateTime;
+            return firstInstallTime != lastUpdateTime;
+        } catch (Exception e) {
+            return false;
+        }
+    }
+    
+   
     /**
      * Return the application's package name.
      *

From cbea6b40658e04ee923c2e4c1d5fad0e18bae5ae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=A9=AC=E6=AD=87=E5=B0=94?= 
Date: Tue, 4 May 2021 18:56:24 +0200
Subject: [PATCH 17/44] Added yet another 2 very useful methods

1. isBehindProxy():
Returns true if device is connecting to the internet via a proxy, works for both Wi-Fi and Mobile Data.
2. isUsingVPN():
Returns true if device is connecting to the internet via a VPN.
---
 .../blankj/utilcode/util/NetworkUtils.java    | 28 +++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/NetworkUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/NetworkUtils.java
index 8f874dbf38..37104b1b43 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/NetworkUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/NetworkUtils.java
@@ -261,6 +261,34 @@ public static boolean getMobileDataEnabled() {
         }
         return false;
     }
+    
+     /**
+     * Returns true if device is connecting to the internet via a proxy, works for both Wi-Fi and Mobile Data.
+     *
+     * @return true if using proxy to connect to the internet.
+     */
+    public static boolean isBehindProxy(){
+        return !(System.getProperty("http.proxyHost") == null || System.getProperty("http.proxyPort") == null);
+    }
+
+    /**
+     * Returns true if device is connecting to the internet via a VPN.
+     *
+     * @return true if using VPN to conncet to the internet.
+     */
+    public static boolean isUsingVPN(){
+        ConnectivityManager cm = (ConnectivityManager) com.blankj.utilcode.util.Utils.getApp().getSystemService(Context.CONNECTIVITY_SERVICE);
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+            return cm.getNetworkInfo(ConnectivityManager.TYPE_VPN).isConnectedOrConnecting()
+        } else {
+            return cm.getNetworkInfo(NetworkCapabilities.TRANSPORT_VPN).isConnectedOrConnecting()
+        }
+    }
+
+    
+    
+    
+    
 
     /**
      * Return whether using mobile data.

From 402cc73a240a9527cea3180c6cf647223b3e6e91 Mon Sep 17 00:00:00 2001
From: caimengjie 
Date: Thu, 13 May 2021 01:09:26 +0800
Subject: [PATCH 18/44] add(publish): support publish mavenCentral

---
 CHANGELOG.md                                  |   1 +
 build.gradle                                  |  13 +-
 buildApp.gradle                               |  44 ++--
 buildCommon.gradle                            |  16 --
 buildSrc/src/main/groovy/Config.groovy        |   6 +-
 config/flavor.gradle                          |  22 ++
 config/publish.gradle                         | 237 ++++++++++++++++++
 feature/utilcode/export/build.gradle          |  14 +-
 gradle/publish.gradle                         | 237 ------------------
 gradle/wrapper/gradle-wrapper.properties      |   2 +-
 lib/subutil/build.gradle                      |   2 +-
 lib/utilcode/build.gradle                     |  15 +-
 lib/utilcode/src/main/AndroidManifest.xml     |   2 +-
 .../com/blankj/utilcode/util/IntentUtils.java |   2 +-
 .../com/blankj/utilcode/util/ToastUtils.java  |   2 +-
 .../com/blankj/utilcode/util/UriUtils.java    |   2 +-
 lib/utildebug/build.gradle                    |   4 -
 plugin/api-gradle-plugin/build.gradle         |   6 +-
 plugin/bus-gradle-plugin/build.gradle         |   6 +-
 plugin/lib/base-transform/build.gradle        |   6 +-
 script/clean.sh                               |   4 -
 script/gitHelp.sh                             |  45 ++++
 script/runDevDebug.sh                         |   9 +
 script/runProductionRelease.sh                |   9 +
 24 files changed, 380 insertions(+), 326 deletions(-)
 create mode 100644 config/flavor.gradle
 create mode 100644 config/publish.gradle
 delete mode 100644 gradle/publish.gradle
 delete mode 100755 script/clean.sh
 create mode 100755 script/gitHelp.sh
 create mode 100755 script/runDevDebug.sh
 create mode 100755 script/runProductionRelease.sh

diff --git a/CHANGELOG.md b/CHANGELOG.md
index db3e52985a..401a5071f8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,4 @@
+* `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.
diff --git a/build.gradle b/build.gradle
index dd27b98617..133f032278 100644
--- a/build.gradle
+++ b/build.gradle
@@ -2,11 +2,9 @@
 buildscript {
     ConfigUtils.init(gradle)
     repositories {
-        // use for debug plugin local
-        if (Config.depConfig.plugin_bus.useLocal || Config.depConfig.plugin_api.useLocal) {
-            maven() { url uri("${project.rootDir.path}/mavenLocal") }
-        }
+        mavenLocal()
         google()
+        mavenCentral()
         jcenter()
     }
 
@@ -19,9 +17,10 @@ buildscript {
 
 allprojects {
     repositories {
-        maven() { url uri("${project.rootDir.path}/mavenLocal") }
+        mavenLocal()
         maven { url "https://jitpack.io" }
         google()
+        mavenCentral()
         jcenter()
     }
 
@@ -29,8 +28,8 @@ allprojects {
         resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
 
         resolutionStrategy.eachDependency {
-            if (it.requested.group == 'com.android.support'
-                    && !it.requested.name.contains('multidex')) {
+            if (it.requested.group == 'com.android.support' && !it.requested.name.contains(
+                'multidex')) {
                 it.useVersion Config.supportVersion
             }
         }
diff --git a/buildApp.gradle b/buildApp.gradle
index 7aa523c466..d7ed2c75a3 100644
--- a/buildApp.gradle
+++ b/buildApp.gradle
@@ -1,6 +1,7 @@
 apply {
     plugin "com.android.application"
-    from  "${rootDir.path}/buildCommon.gradle"
+    from "${rootDir.path}/buildCommon.gradle"
+    from "${rootDir.path}/config/flavor.gradle"
     if (Config.depConfig.plugin_api.isApply) {
         plugin Config.depConfig.plugin_api.pluginId
     }
@@ -32,19 +33,11 @@ android {
     }
 
     buildTypes {
-        debug {
-            minifyEnabled false
-            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
-            applicationIdSuffix ".debug"
-            resValue "string", "app_name", Config.appName + suffix + ".debug"
-        }
+        debug {}
 
         release {
-            aaptOptions.cruncherEnabled = false
-            aaptOptions.useNewCruncher = false
             minifyEnabled true
             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
-            resValue "string", "app_name", Config.appName + suffix
         }
     }
 
@@ -58,8 +51,19 @@ 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
@@ -80,7 +84,9 @@ dependencies {
 
 def getSuffix() {
     if (project.name == "feature_launcher_app") return ""
-    return "." + project.name.substring("feature_".length(), project.name.length() - "_app".length())
+    return "." + project.
+        name.
+        substring("feature_".length(), project.name.length() - "_app".length())
 }
 
 def configSigning() {
@@ -110,12 +116,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
index f83f74f52d..8cbcc26255 100644
--- a/buildCommon.gradle
+++ b/buildCommon.gradle
@@ -22,20 +22,4 @@ android {
     lintOptions {
         abortOnError false
     }
-
-//    viewBinding {
-//        enabled = true
-//    }
-
-//    flavorDimensions "region"
-//
-//    productFlavors {
-//        china {
-//            dimension "region"
-//        }
-//
-//        oversea {
-//            dimension "region"
-//        }
-//    }
 }
\ No newline at end of file
diff --git a/buildSrc/src/main/groovy/Config.groovy b/buildSrc/src/main/groovy/Config.groovy
index 9b6e55d3bb..4fb2b7ef2f 100644
--- a/buildSrc/src/main/groovy/Config.groovy
+++ b/buildSrc/src/main/groovy/Config.groovy
@@ -15,10 +15,10 @@ class Config {
     static minSdkVersion = 14
     static targetSdkVersion = 29
     static versionCode = 1_030_006
-    static versionName = '1.30.6'// E.g. 1.9.72 => 1,009,072
+    static versionName = '1.30.7-alpha1'// E.g. 1.9.72 => 1,009,072
 
     // lib version
-    static gradlePluginVersion = '3.5.2'
+    static gradlePluginVersion = '4.1.0'
     static kotlinVersion = '1.3.72'
     static androidxVersion = '1.0.0'
 
@@ -47,8 +47,6 @@ class Config {
             /*Never delete this line*/
             plugin_gradle              : new DepConfig(pluginPath: "com.android.tools.build:gradle:$gradlePluginVersion"),
             plugin_kotlin              : new DepConfig(pluginPath: "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"),
-            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"),// 注解转非空判断
 
             // 上传新版本插件更新 pluginPath 中的版本号,并设置 isApply = false
diff --git a/config/flavor.gradle b/config/flavor.gradle
new file mode 100644
index 0000000000..25c1801983
--- /dev/null
+++ b/config/flavor.gradle
@@ -0,0 +1,22 @@
+android {
+    flavorDimensions "env"
+    productFlavors {
+        dev {
+            dimension "env"
+        }
+
+        production {
+            dimension "env"
+        }
+    }
+
+    variantFilter { variant ->
+        def flavorNames = variant.flavors*.name
+        def buildTypeName = variant.buildType.name
+
+        // production 包不允许 debug 构建
+        if (flavorNames.contains("production") && buildTypeName.contains("debug")) {
+            variant.setIgnore(true)
+        }
+    }
+}
\ No newline at end of file
diff --git a/config/publish.gradle b/config/publish.gradle
new file mode 100644
index 0000000000..af97da785b
--- /dev/null
+++ b/config/publish.gradle
@@ -0,0 +1,237 @@
+/*
+ 1. add
+    signing.keyId=xx
+    signing.password=xx
+    signing.secretKeyRingFile=/Users/xx/secring.gpg
+    ossrhUsername=xx
+    ossrhPassword=xx
+    in root local.properties
+
+ 2. copy the file to the directory of gradle, and apply the file in the module
+ ext {
+    groupId = Config.depConfig.lib_utilcode.groupId
+    artifactId = Config.depConfig.lib_utilcode.artifactId
+    version = Config.depConfig.lib_utilcode.version
+    website = "https://github.com/Blankj/AndroidUtilCode"
+}
+ apply from: "${rootDir.path}/config/publish.gradle"
+
+ 3. execute following command to publish
+ ./gradlew :xxmodule:publish2Local  -> upload to mavenCentral
+ ./gradlew :xxmodule:publish2Remote -> upload to mavenLocal
+*/
+
+apply plugin: 'maven-publish'
+apply plugin: 'signing'
+
+ext.multiPublishMode = true
+
+File localPropertiesFile = project.rootProject.file("local.properties");
+if (localPropertiesFile.exists()) {
+    Properties properties = new Properties()
+    properties.load(new FileInputStream(localPropertiesFile))
+    properties.each { name, value -> ext[name] = value }
+} else {
+    if (!ext["signing.keyId"] && !ext["signing.password"] &&
+        !ext["signing.secretKeyRingFile"] &&
+        !ext["ossrhUsername"] &&
+        !ext["ossrhPassword"]) {
+        throw new NullPointerException("U should set MavenCentral params in local.properties")
+    }
+}
+
+afterEvaluate {
+    def ext = project.ext
+    publishing {
+        publications {
+            release(MavenPublication) {
+                groupId ext.groupId
+                artifactId ext.artifactId
+                version ext.version
+
+                if (isAndroidEnv(project)) {
+                    if (project.ext.multiPublishMode) {
+                        artifact("$buildDir/outputs/aar/${project.getName()}-release.aar")
+                        artifact sourcesJar
+                    } else {
+                        from project.components.release
+                    }
+                } else {
+                    from project.components.java
+                }
+
+                pom {
+                    name = ext.artifactId
+                    description = ext.artifactId
+                    url = ext.website
+
+                    licenses {
+                        license {
+                            name = 'The Apache Software License, Version 2.0'
+                            url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+                        }
+                    }
+                    developers {
+                        developer {
+                            id = ext.ossrhUsername
+                            name = ext.ossrhUsername
+                        }
+                    }
+                    scm {
+                        url = ext.website
+                        connection = ext.website
+                        developerConnection = ext.website + ".git"
+                    }
+
+                    if (project.ext.multiPublishMode) {
+                        withXml {
+                            def dependenciesNode = asNode().getAt('dependencies')[0] ?:
+                                asNode().appendNode('dependencies')
+
+                            configurations.
+                                api.
+                                getDependencies().
+                                each { dep -> addDependency(project, dependenciesNode, dep, "compile") }
+                            configurations.
+                                implementation.
+                                getDependencies().
+                                each { dep -> addDependency(project, dependenciesNode, dep, "runtime") }
+                        }
+                    }
+                }
+            }
+        }
+
+        repositories {
+            maven {
+                // s01 is newest
+                def releasesUrl = "https://s01.oss.sonatype.org/content/repositories/releases/"
+                def snapshotUrl = "https://s01.oss.sonatype.org/content/repositories/snapshots/"
+                url = version.toUpperCase().endsWith('SNAPSHOT') ? snapshotUrl : releasesUrl
+
+                credentials {
+                    username ossrhUsername
+                    password ossrhPassword
+                }
+            }
+        }
+    }
+
+    signing {
+        sign publishing.publications
+    }
+}
+
+private void addDependency(Project project, def dependenciesNode, Dependency dep, String scope) {
+    if (dep.group == null || dep.version == null || dep.name == null || dep.name == "unspecified") {
+        return
+    }
+
+    final dependencyNode = dependenciesNode.appendNode('dependency')
+    dependencyNode.appendNode('scope', scope)
+
+    if (dep.version == 'unspecified') {
+        // 检测 module 中的 dependencies 是否有源码依赖
+        // 如果是源码依赖,而且没有在 config 中配置 remotePath,
+        // 那么发布到仓库,其他地方依赖该库时会找不到源码的那个库
+        println "publish -> module(unspecified) <${dep.group}:${dep.name}:${dep.version}>"
+        if (project.ext.groupId || project.ext.version) {
+            throw new GradleException(
+                "The module of <" + dep.name + "> should set groupId & version.")
+        }
+        // 源码依赖,但配置了 remotePath,让 pom 中写入 remotePath
+        println(
+            "publish -> module(wrapped) <${project.ext.groupId}:${name}:${project.ext.version}>")
+
+        dependencyNode.appendNode('groupId', project.ext.pomGroupID)
+        dependencyNode.appendNode('artifactId', dep.name)
+        dependencyNode.appendNode('version', project.ext.pomVersion)
+    } else {
+        dependencyNode.appendNode('groupId', dep.group)
+        dependencyNode.appendNode('artifactId', dep.name)
+        dependencyNode.appendNode('version', dep.version)
+        println("publish -> library <${dep.group}:${dep.name}:${dep.version}>")
+    }
+
+    if (!dep.transitive) {
+        // In case of non transitive dependency,
+        // all its dependencies should be force excluded from them POM file
+        final exclusionNode = dependencyNode.appendNode('exclusions').appendNode('exclusion')
+        exclusionNode.appendNode('groupId', '*')
+        exclusionNode.appendNode('artifactId', '*')
+    } else if (!dep.properties.excludeRules.empty) {
+        // For transitive with exclusions, all exclude rules should be added to the POM file
+        final exclusions = dependencyNode.appendNode('exclusions')
+        dep.properties.excludeRules.each { ExcludeRule rule ->
+            final exclusionNode = exclusions.appendNode('exclusion')
+            exclusionNode.appendNode('groupId', rule.group ?: '*')
+            exclusionNode.appendNode('artifactId', rule.module ?: '*')
+        }
+    }
+}
+
+if (isAndroidEnv(project)) {
+    // This generates sources.jar
+    task sourcesJar(type: Jar) {
+        classifier = 'sources'
+        from android.sourceSets.main.java.source
+    }
+
+    task javadoc(type: Javadoc) {
+        source = android.sourceSets.main.java.source
+        classpath += configurations.compile
+        classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
+    }
+
+    task javadocJar(type: Jar, dependsOn: javadoc) {
+        classifier = 'javadoc'
+        from javadoc.destinationDir
+    }
+} else {
+    task sourcesJar(type: Jar, dependsOn: classes) {
+        classifier = 'sources'
+        from sourceSets.main.allSource
+    }
+
+    task javadocJar(type: Jar, dependsOn: javadoc) {
+        classifier = 'javadoc'
+        from javadoc.destinationDir
+    }
+}
+
+if (project.hasProperty("kotlin")) {
+    // Disable creating javadocs
+    project.tasks.withType(Javadoc) {
+        enabled = false
+    }
+}
+
+javadoc {
+    options {
+        encoding "UTF-8"
+        charSet 'UTF-8'
+        author true
+        version project.ext.version
+        links "http://docs.oracle.com/javase/7/docs/api"
+        title "${project.ext.artifactId} ${project.ext.version}"
+    }
+}
+
+artifacts {
+    archives javadocJar
+    archives sourcesJar
+}
+
+static def isAndroidEnv(Project project) {
+    return project.getPlugins().hasPlugin('com.android.application') || project.
+        getPlugins().
+        hasPlugin('com.android.library')
+}
+
+task publish2Local(type: GradleBuild) {
+    tasks = ['clean', 'assemble', 'publishReleasePublicationToMavenLocal']
+}
+
+task publish2Remote(type: GradleBuild) {
+    tasks = ['clean', 'assemble', 'publishReleasePublicationToMavenRepository']
+}
\ No newline at end of file
diff --git a/feature/utilcode/export/build.gradle b/feature/utilcode/export/build.gradle
index cecc254461..815f9babe6 100644
--- a/feature/utilcode/export/build.gradle
+++ b/feature/utilcode/export/build.gradle
@@ -1,10 +1,8 @@
-apply from: "${rootDir.path}/gradle/publish.gradle"
-publish {
-    def depConfig = Config.depConfig.feature_utilcode_export
-    name = "UtilCodeExport"
-    groupId = depConfig.groupId
-    artifactId = depConfig.artifactId
-    version = depConfig.version
-    website = "https://github.com/Blankj/UtilCodeExport"
+ext {
+    groupId = Config.depConfig.feature_utilcode_export.groupId
+    artifactId = Config.depConfig.feature_utilcode_export.artifactId
+    version = Config.depConfig.feature_utilcode_export.version
+    website = "https://github.com/Blankj/AndroidUtilCode"
 }
+apply from: "${rootDir.path}/config/publish.gradle"
 //./gradlew :feature_utilcode_export:mavenLocal   // 上传到本地 mavenLocal
\ No newline at end of file
diff --git a/gradle/publish.gradle b/gradle/publish.gradle
deleted file mode 100644
index 76bb5fea66..0000000000
--- a/gradle/publish.gradle
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- 1. must add the following classpath in root build.gradle
- classpath "com.github.dcendents:android-maven-gradle-plugin:2.1"
- classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4"
-
- 2. add bintrayUser, bintrayKey in root local.properties
-
- 3. copy the file to the directory of gradle, and apply the file in the module
- apply from: "${rootDir.path}/gradle/publish.gradle"
- publish {
-    name = "UtilCode"
-    groupId = "com.blankj"
-    artifactId = "utilcode"
-    version = "xx.xx"
-    website = "https://github.com/Blankj/AndroidUtilCode"
- }
-
- 4. execute following command to publish
- ./gradlew bintrayUpload    -> upload to bintray
- ./gradlew mavenLocal       -> upload to local maven
-*/
-
-apply plugin: "com.github.dcendents.android-maven"
-apply plugin: "com.jfrog.bintray"
-
-extensions.create('publish', PublishExtension)
-
-afterEvaluate {
-    def ext = project['publish'] as PublishExtension
-    loadBintray(ext)
-    configMaven(project, ext)
-    configBintray(project, ext)
-    configJavadoc(project, ext)
-}
-
-private void loadBintray(PublishExtension ext) {
-    Properties properties = new Properties()
-    File localPropertiesFile = project.rootProject.file("local.properties");
-    if (localPropertiesFile.exists()) {
-        properties.load(localPropertiesFile.newDataInputStream())
-        ext.bintrayUser = properties.getProperty("bintrayUser")
-        ext.bintrayKey = properties.getProperty("bintrayKey")
-    }
-}
-
-def configMaven(Project project, PublishExtension ext) {
-    project.group = ext.groupId
-    project.version = ext.version
-
-    project.install {
-        repositories.mavenInstaller {
-            configPom(pom, ext)
-        }
-    }
-
-    project.tasks.create("mavenLocal", Upload) {
-        group("publishing")
-        configuration = project.configurations.archives
-
-        repositories.mavenDeployer {
-            repository(url: uri("${project.rootDir.path}/mavenLocal"))
-            configPom(pom, ext)
-        }
-
-        doFirst {
-            ext.check(false)
-        }
-    }
-
-    project.tasks.findByName("bintrayUpload").doFirst {
-        ext.check(true)
-    }
-}
-
-def configPom(pom, PublishExtension ext) {
-    pom.project {
-        name ext.name
-        groupId ext.groupId
-        artifactId ext.artifactId
-        version ext.version
-        packaging isAndroid() ? "aar" : "jar"
-        description ext.name
-        url ext.website
-
-        scm {
-            url ext.website
-            connection ext.website
-            developerConnection ext.website + ".git"
-        }
-
-        licenses {
-            license {
-                name 'The Apache Software License, Version 2.0'
-                url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
-            }
-        }
-
-        developers {
-            developer {
-                id ext.bintrayUser
-                name ext.bintrayUser
-            }
-        }
-    }
-
-    pom.whenConfigured {
-        // 检测 module 中的 dependencies 是否有源码依赖
-        // 如果是源码依赖,而且没有在 config 中配置 remotePath,那么发布到仓库,其他地方依赖该库时会找不到源码的那个库
-        it.dependencies.findAll { dep -> dep.version == "unspecified" }.collect { dep ->
-            DepConfig config = Config.depConfig.get(dep.artifactId)
-            if (config == null || config.version == null) {
-                // 源码依赖而且没有在 config 中配置 remotePath,直接报错
-                System.err.println("The module of <" + dep.artifactId + "> should publish to maven first.")
-                throw new RuntimeException()
-            }
-            dep.groupId = config.groupId
-            dep.version = config.version
-            // 源码依赖,但配置了 remotePath,让 pom 中写入 remotePath
-            GLog.l("Please check <${dep.groupId}:${dep.artifactId}:${dep.version}> is published.")
-        }
-    }
-}
-
-def configBintray(Project project, PublishExtension ext) {
-    project.bintray {
-        user = ext.bintrayUser
-        key = ext.bintrayKey
-        configurations = ['archives']
-        override = false
-        publish = true
-        pkg {
-            repo = "maven"
-            name = ext.name
-            websiteUrl = ext.website
-            vcsUrl = ext.website + '.git'
-            licenses = ["Apache-2.0"]
-        }
-    }
-}
-
-private void configJavadoc(Project project, PublishExtension ext) {
-    if (isAndroid()) {
-        // This generates sources.jar
-        task sourcesJar(type: Jar) {
-            classifier = 'sources'
-            from android.sourceSets.main.java.source
-        }
-
-        task javadoc(type: Javadoc) {
-            source = android.sourceSets.main.java.source
-            classpath += configurations.compile
-            classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
-        }
-
-        task javadocJar(type: Jar, dependsOn: javadoc) {
-            classifier = 'javadoc'
-            from javadoc.destinationDir
-        }
-    } else {
-        task sourcesJar(type: Jar, dependsOn: classes) {
-            classifier = 'sources'
-            from sourceSets.main.allSource
-        }
-
-        task javadocJar(type: Jar, dependsOn: javadoc) {
-            classifier = 'javadoc'
-            from javadoc.destinationDir
-        }
-    }
-
-    if (project.hasProperty("kotlin")) {
-        // Disable creating javadocs
-        project.tasks.withType(Javadoc) {
-            enabled = false
-        }
-    }
-
-    javadoc {
-        options {
-            encoding "UTF-8"
-            charSet 'UTF-8'
-            author true
-            version ext.version
-            links "http://docs.oracle.com/javase/7/docs/api"
-            title "${ext.name} ${ext.version}"
-        }
-    }
-
-    artifacts {
-        archives javadocJar
-        archives sourcesJar
-    }
-}
-
-def isAndroid() {
-    return project.getPlugins().hasPlugin('com.android.application') ||
-            project.getPlugins().hasPlugin('com.android.library')
-}
-
-class PublishExtension {
-    String name
-    String groupId
-    String artifactId
-    String version
-    String website
-
-    String bintrayUser
-    String bintrayKey
-
-    void check(boolean isBintray) {
-        checkField(name, "name")
-        checkField(groupId, "groupId")
-        checkField(artifactId, "artifactId")
-        checkField(version, "version")
-        checkField(website, "website")
-
-        if (isBintray) {
-            if (isBintrayEmpty()) {
-                throw new NullPointerException("U should set bintrayUser and bintrayKey in local.properties")
-            }
-        }
-    }
-
-    boolean isBintrayEmpty() {
-        return isEmpty(bintrayUser) || isEmpty(bintrayKey)
-    }
-
-    static void checkField(String field, String fieldName) {
-        if (isEmpty(field)) {
-            throw new NullPointerException("$fieldName is empty!!")
-        }
-    }
-
-    static boolean isEmpty(String str) {
-        return str == null || str.length() == 0
-    }
-}
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index e4718dff4d..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-5.4.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip
diff --git a/lib/subutil/build.gradle b/lib/subutil/build.gradle
index a561916f3e..1d2b458537 100644
--- a/lib/subutil/build.gradle
+++ b/lib/subutil/build.gradle
@@ -1,5 +1,5 @@
 apply {
-    plugin Config.depConfig.plugin_traute.pluginId
+//    plugin Config.depConfig.plugin_traute.pluginId
     plugin "readme-sub"
 }
 
diff --git a/lib/utilcode/build.gradle b/lib/utilcode/build.gradle
index 891f7dbf40..612969a45c 100644
--- a/lib/utilcode/build.gradle
+++ b/lib/utilcode/build.gradle
@@ -1,5 +1,5 @@
 apply {
-    plugin Config.depConfig.plugin_traute.pluginId
+    //    plugin Config.depConfig.plugin_traute.pluginId
     plugin "readme-core"
 }
 
@@ -29,7 +29,7 @@ android {
 dependencies {
     implementation Config.depConfig.gson.dep
 
-    compileOnly Config.depConfig.androidx_appcompat.dep
+    implementation Config.depConfig.androidx_appcompat.dep
     compileOnly Config.depConfig.androidx_material.dep
 
     testImplementation Config.depConfig.test_junit.dep
@@ -39,15 +39,10 @@ dependencies {
     testImplementation Config.depConfig.eventbus_lib.dep
 }
 
-afterEvaluate {
-    verifyReleaseResources.enabled(false)
-}
-
-apply from: "${rootDir.path}/gradle/publish.gradle"
-publish {
-    name = "UtilCodeX"
+ext {
     groupId = Config.depConfig.lib_utilcode.groupId
     artifactId = Config.depConfig.lib_utilcode.artifactId
     version = Config.depConfig.lib_utilcode.version
     website = "https://github.com/Blankj/AndroidUtilCode"
-}
\ No newline at end of file
+}
+apply from: "${rootDir.path}/config/publish.gradle"
\ No newline at end of file
diff --git a/lib/utilcode/src/main/AndroidManifest.xml b/lib/utilcode/src/main/AndroidManifest.xml
index 4cf4fe1090..fc5b75e0e3 100644
--- a/lib/utilcode/src/main/AndroidManifest.xml
+++ b/lib/utilcode/src/main/AndroidManifest.xml
@@ -18,7 +18,7 @@
 
         
             = Build.VERSION_CODES.N) {
-            String authority = Utils.getApp().getPackageName() + ".utilcode.provider";
+            String authority = Utils.getApp().getPackageName() + ".utilcode.fileprovider";
             return FileProvider.getUriForFile(Utils.getApp(), authority, file);
         } else {
             return Uri.fromFile(file);
diff --git a/lib/utildebug/build.gradle b/lib/utildebug/build.gradle
index 4dd4682f3c..22f1f7294b 100644
--- a/lib/utildebug/build.gradle
+++ b/lib/utildebug/build.gradle
@@ -1,7 +1,3 @@
-afterEvaluate {
-    verifyReleaseResources.enabled(false)
-}
-
 dependencies {
     compileOnly Config.depConfig.androidx_appcompat.dep
     compileOnly Config.depConfig.androidx_material.dep
diff --git a/plugin/api-gradle-plugin/build.gradle b/plugin/api-gradle-plugin/build.gradle
index 8b859f35a6..2f6b956ee0 100755
--- a/plugin/api-gradle-plugin/build.gradle
+++ b/plugin/api-gradle-plugin/build.gradle
@@ -31,14 +31,12 @@ sourceSets {
     }
 }
 
-apply from: "${rootDir.path}/gradle/publish.gradle"
-publish {
-    name = "ApiPlugin"
+ext {
     groupId = Config.depConfig.plugin_api.groupId
     artifactId = Config.depConfig.plugin_api.artifactId
     version = Config.depConfig.plugin_api.version
     website = "https://github.com/Blankj/AndroidUtilCode"
 }
-
+apply from: "${rootDir.path}/config/publish.gradle"
 //./gradlew clean :plugin_api-gradle-plugin:mavenLocal     // 上传到本地 mavenLocal
 //./gradlew clean :plugin_api-gradle-plugin:bintrayUpload  // 上传到 jcenter
diff --git a/plugin/bus-gradle-plugin/build.gradle b/plugin/bus-gradle-plugin/build.gradle
index ec264eaf4e..7cd24042a7 100755
--- a/plugin/bus-gradle-plugin/build.gradle
+++ b/plugin/bus-gradle-plugin/build.gradle
@@ -31,14 +31,12 @@ sourceSets {
     }
 }
 
-apply from: "${rootDir.path}/gradle/publish.gradle"
-publish {
-    name = "BusPlugin"
+ext {
     groupId = Config.depConfig.plugin_bus.groupId
     artifactId = Config.depConfig.plugin_bus.artifactId
     version = Config.depConfig.plugin_bus.version
     website = "https://github.com/Blankj/AndroidUtilCode"
 }
-
+apply from: "${rootDir.path}/config/publish.gradle"
 //./gradlew clean :plugin_bus-gradle-plugin:mavenLocal    // 上传到本地 mavenLocal
 //./gradlew clean :plugin_bus-gradle-plugin:bintrayUpload // 上传到 jcenter
\ No newline at end of file
diff --git a/plugin/lib/base-transform/build.gradle b/plugin/lib/base-transform/build.gradle
index 72d0abe453..3518481ebd 100755
--- a/plugin/lib/base-transform/build.gradle
+++ b/plugin/lib/base-transform/build.gradle
@@ -18,14 +18,12 @@ sourceSets {
     }
 }
 
-apply from: "${rootDir.path}/gradle/publish.gradle"
-publish {
-    name = "BaseTransform"
+ext {
     groupId = Config.depConfig.plugin_lib_base_transform.groupId
     artifactId = Config.depConfig.plugin_lib_base_transform.artifactId
     version = Config.depConfig.plugin_lib_base_transform.version
     website = "https://github.com/Blankj/AndroidUtilCode"
 }
-
+apply from: "${rootDir.path}/config/publish.gradle"
 //./gradlew clean plugin:lib:plugin_lib_base-transform:mavenLocal     // 上传到本地 mavenLocal
 //./gradlew clean plugin:lib:plugin_lib_base-transform:bintrayUpload  // 上传到 gradle 插件库中
diff --git a/script/clean.sh b/script/clean.sh
deleted file mode 100755
index 2ff72056bb..0000000000
--- a/script/clean.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/usr/bin/env bash
-rm -rf .idea
-find . -name "*.iml" -type f -exec rm -rf {} \;
-find . -name "build" -type d -exec rm -rf {} \;
\ No newline at end of file
diff --git a/script/gitHelp.sh b/script/gitHelp.sh
new file mode 100755
index 0000000000..af98ce2ac6
--- /dev/null
+++ b/script/gitHelp.sh
@@ -0,0 +1,45 @@
+#!/usr/bin/env bash
+while true; do
+  echo "                 ############## input command code #################"
+  echo "                 #          [1] Git Push                           #"
+  echo "                 #          [2] Git Push And Merge to Master       #"
+  echo "                 #          [other] exit                           #"
+  echo "                 ###################################################"
+
+  read which
+
+  case $which in
+  1)
+    curBranch=$(git symbolic-ref --short -q HEAD)
+    gitPush $curBranch
+    ;;
+  2)
+    curBranch=$(git symbolic-ref --short -q HEAD)
+    gitPush $curBranch
+    echo "git checkout master"
+    echo $(git checkout master)
+    echo "git merge $branchName"
+    echo $(git merge $branchName)
+    echo "git push origin master"
+    echo $(git push origin master)
+    echo "git checkout $branchName"
+    echo $(git checkout $branchName)
+    ;;
+  *)
+    echo "88"
+    break
+    ;;
+  esac
+done
+
+function gitPush() {
+  curBranch=$1
+  echo "curBranch = $curBranch"
+  echo "git add -A"
+  echo $(git add -A)
+  date=$(date "+%m/%d")
+  echo "git commit -m \"see $date log\""
+  echo $(git commit -m "see $date log")
+  echo "git push origin $curBranch"
+  echo $(git push origin $curBranch)
+}
diff --git a/script/runDevDebug.sh b/script/runDevDebug.sh
new file mode 100755
index 0000000000..e42394e0c8
--- /dev/null
+++ b/script/runDevDebug.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+
+set -e
+
+# build dev debug apk
+./gradlew --daemon installDevDebug
+
+# start main activity
+adb shell am start -n "com.blankj.androidutilcode.dev/com.blankj.main.pkg.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
\ No newline at end of file
diff --git a/script/runProductionRelease.sh b/script/runProductionRelease.sh
new file mode 100755
index 0000000000..a3d44d5ede
--- /dev/null
+++ b/script/runProductionRelease.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+
+set -e
+
+# build dev debug apk
+./gradlew --daemon installProductionRelease
+
+# start main activity
+adb shell am start -n "com.blankj.androidutilcode/com.blankj.main.pkg.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
\ No newline at end of file

From 8faee0b382724d3579921672f8a5dbb9c9360f30 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=A9=AC=E6=AD=87=E5=B0=94?= 
Date: Wed, 22 Sep 2021 13:39:01 -0600
Subject: [PATCH 19/44] isUsingNetworkProvidedTime()

Useful in situations where you want to verify that the device has a correct time set, to avoid fraud, or if you want to prevent the user from messing with the time and abusing your "one-time" and "expiring" features.
---
 .../java/com/blankj/utilcode/util/TimeUtils.java    | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/TimeUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/TimeUtils.java
index 2ab5370c82..88887b621f 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/TimeUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/TimeUtils.java
@@ -36,6 +36,19 @@ protected Map initialValue() {
     private static SimpleDateFormat getDefaultFormat() {
         return getSafeDateFormat("yyyy-MM-dd HH:mm:ss");
     }
+    /**
+     * Checks whether the device is using Network Provided Time or not.
+     *  Useful in situations where you want to verify that the device has a correct time set, to avoid fraud, or if you want to prevent the user from messing with the time and abusing your "one-time" and "expiring" features. 
+     * @return {@code true}: yes
{@code false}: no + */ + public static boolean isUsingNetworkProvidedTime() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + return Settings.Global.getInt(Utils.getApp().getContentResolver(), Settings.Global.AUTO_TIME, 0) == 1; + } else { + return android.provider.Settings.System.getInt(Utils.getApp().getContentResolver(), android.provider.Settings.System.AUTO_TIME, 0) == 1; + } + } + @SuppressLint("SimpleDateFormat") public static SimpleDateFormat getSafeDateFormat(String pattern) { From fb1f0d0a616bbbb326e9c7665887365c5dd064f9 Mon Sep 17 00:00:00 2001 From: jikun2008 Date: Wed, 10 Nov 2021 16:52:17 +0800 Subject: [PATCH 20/44] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BA=86=E4=B8=80?= =?UTF-8?q?=E4=B8=AA=E5=86=85=E5=AD=98=E6=B3=84=E6=BC=8F=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit //这里会发生内存泄漏 如果不设置为null contentView.setTag(TAG_ON_GLOBAL_LAYOUT_LISTENER, null); --- .../src/main/java/com/blankj/utilcode/util/KeyboardUtils.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/KeyboardUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/KeyboardUtils.java index 7f95fdee75..fd70fef220 100644 --- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/KeyboardUtils.java +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/KeyboardUtils.java @@ -238,6 +238,8 @@ public static void unregisterSoftInputChangedListener(@NonNull final Window wind if (tag instanceof OnGlobalLayoutListener) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { contentView.getViewTreeObserver().removeOnGlobalLayoutListener((OnGlobalLayoutListener) tag); + //这里会发生内存泄漏 如果不设置为null + contentView.setTag(TAG_ON_GLOBAL_LAYOUT_LISTENER, null); } } } From 9df5d7e15b06109153d0499c3f1ed1a3080c94ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E6=AD=87=E5=B0=94?= Date: Tue, 23 Nov 2021 22:19:24 +0100 Subject: [PATCH 21/44] 2 new methods: isJSONObject() and isJSONArray() Check if a given input is a JSONObject or a JSONArray. --- .../com/blankj/utilcode/util/JsonUtils.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/JsonUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/JsonUtils.java index ea40ac3162..43046adf5a 100644 --- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/JsonUtils.java +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/JsonUtils.java @@ -26,6 +26,27 @@ private JsonUtils() { throw new UnsupportedOperationException("u can't instantiate me..."); } + + /** + * Checks if a given input is a JSONObject. + * + * @param input Anything. + * @return true if it is a JSONObject. + */ + public static boolean isJSONObject(final T input) { + return input instanceof JSONObject; + } + + /** + * Checks if a given input is a JSONArray + * + * @param input Anything. + * @return true if it is a JSONArray. + */ + public static boolean isJSONArray(final T input) { + return input instanceof JSONArray; + } + public static boolean getBoolean(final JSONObject jsonObject, final String key) { return getBoolean(jsonObject, key, false); From e40b6d40b55cfb3608cd954d6bdd1feac67b94ca Mon Sep 17 00:00:00 2001 From: caimengjie Date: Mon, 6 Dec 2021 00:00:20 +0800 Subject: [PATCH 22/44] opt: Config --- build.gradle | 4 +- buildApp.gradle | 43 ++-- buildCommon.gradle | 5 + buildLib.gradle | 2 +- buildSrc/settings.gradle | 8 + buildSrc/src/main/groovy/Config.groovy | 114 ++++----- buildSrc/src/main/groovy/ConfigUtils.groovy | 45 ++-- buildSrc/src/main/groovy/DepConfig.groovy | 93 ------- buildSrc/src/main/groovy/GitUtils.groovy | 111 --------- buildSrc/src/main/groovy/LibConfig.groovy | 29 +++ buildSrc/src/main/groovy/ModuleConfig.groovy | 35 +++ buildSrc/src/main/groovy/PluginConfig.groovy | 35 +++ buildSrc/src/main/groovy/ShellUtils.java | 228 ------------------ .../src/main/groovy/TaskDurationUtils.groovy | 5 + config.json | 28 --- config/publish.gradle | 52 ++-- feature/launcher/app/build.gradle | 2 +- feature/utilcode/export/build.gradle | 8 +- gradle/wrapper/gradle-wrapper.jar | Bin 53636 -> 55616 bytes gradlew | 88 ++++--- gradlew.bat | 190 ++++++++------- lib/base/build.gradle | 23 +- .../java/com/blankj/base/rv/BaseItem.java | 6 +- lib/common/build.gradle | 2 +- lib/subutil/build.gradle | 19 +- lib/utilcode/README-CN.md | 1 + lib/utilcode/build.gradle | 23 +- .../blankj/utilcode/util/ActivityUtils.java | 3 +- .../com/blankj/utilcode/util/AppUtils.java | 16 ++ .../com/blankj/utilcode/util/CrashUtils.java | 30 ++- .../blankj/utilcode/util/KeyboardUtils.java | 127 ++++++---- .../blankj/utilcode/util/MetaDataUtils.java | 2 +- .../com/blankj/utilcode/util/SpanUtils.java | 26 +- .../util/UtilsActivityLifecycleImpl.java | 19 +- lib/utildebug/build.gradle | 16 +- .../com/blankj/utildebug/menu/DebugMenu.java | 1 + module_config.gradle | 72 ++++++ module_config.json | 30 +++ module_config.yaml | 91 +++++++ plugin/api-gradle-plugin/build.gradle | 20 +- plugin/buildSrc-plugin/.gitignore | 1 + plugin/buildSrc-plugin/build.gradle | 37 +++ .../com/blankj/buildSrc/BuildSrcPlugin.groovy | 13 + .../java/com/blankj/buildSrc/ModuleCfg.groovy | 80 ++++++ plugin/bus-gradle-plugin/build.gradle | 18 +- plugin/lib/base-transform/build.gradle | 14 +- settings.gradle | 112 +++------ 47 files changed, 968 insertions(+), 959 deletions(-) create mode 100644 buildSrc/settings.gradle delete mode 100644 buildSrc/src/main/groovy/DepConfig.groovy delete mode 100644 buildSrc/src/main/groovy/GitUtils.groovy create mode 100644 buildSrc/src/main/groovy/LibConfig.groovy create mode 100644 buildSrc/src/main/groovy/ModuleConfig.groovy create mode 100644 buildSrc/src/main/groovy/PluginConfig.groovy delete mode 100644 buildSrc/src/main/groovy/ShellUtils.java delete mode 100644 config.json create mode 100644 module_config.gradle create mode 100644 module_config.json create mode 100644 module_config.yaml create mode 100755 plugin/buildSrc-plugin/.gitignore create mode 100755 plugin/buildSrc-plugin/build.gradle create mode 100644 plugin/buildSrc-plugin/src/main/java/com/blankj/buildSrc/BuildSrcPlugin.groovy create mode 100644 plugin/buildSrc-plugin/src/main/java/com/blankj/buildSrc/ModuleCfg.groovy diff --git a/build.gradle b/build.gradle index 133f032278..e0f0f36c87 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ buildscript { dependencies { for (def entrySet : ConfigUtils.getApplyPlugins().entrySet()) { - classpath entrySet.value.dep + classpath entrySet.value.path } } } @@ -29,7 +29,7 @@ allprojects { resolutionStrategy.eachDependency { if (it.requested.group == 'com.android.support' && !it.requested.name.contains( - 'multidex')) { + 'multidex')) { it.useVersion Config.supportVersion } } diff --git a/buildApp.gradle b/buildApp.gradle index d7ed2c75a3..93f0b9b1d4 100644 --- a/buildApp.gradle +++ b/buildApp.gradle @@ -1,29 +1,30 @@ +apply plugin: "com.android.application" + apply { - plugin "com.android.application" from "${rootDir.path}/buildCommon.gradle" from "${rootDir.path}/config/flavor.gradle" - if (Config.depConfig.plugin_api.isApply) { - plugin Config.depConfig.plugin_api.pluginId + if (Config.plugins.plugin_api.isApply) { + plugin Config.plugins.plugin_api.id } - if (Config.depConfig.plugin_bus.isApply) { - plugin Config.depConfig.plugin_bus.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 { defaultConfig { @@ -67,18 +68,18 @@ android { dependencies { // LeakCanary - debugImplementation Config.depConfig.leakcanary.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 } } diff --git a/buildCommon.gradle b/buildCommon.gradle index 8cbcc26255..2cba3ffea2 100644 --- a/buildCommon.gradle +++ b/buildCommon.gradle @@ -19,6 +19,11 @@ android { } } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + lintOptions { abortOnError false } diff --git a/buildLib.gradle b/buildLib.gradle index ac9c42ac1c..aed207cbee 100644 --- a/buildLib.gradle +++ b/buildLib.gradle @@ -8,6 +8,6 @@ dependencies { api entrySet.value.dep } } else if (project.name.endsWith("_export")) { - api Config.depConfig.lib_common.dep + api Config.modules.lib_common.dep } } \ No newline at end of file diff --git a/buildSrc/settings.gradle b/buildSrc/settings.gradle new file mode 100644 index 0000000000..8a313c3b99 --- /dev/null +++ b/buildSrc/settings.gradle @@ -0,0 +1,8 @@ +//dependencyResolutionManagement { +// repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) +// repositories { +// google() +// mavenCentral() +// jcenter() // Warning: this repository is going to shut down soon +// } +//} \ No newline at end of file diff --git a/buildSrc/src/main/groovy/Config.groovy b/buildSrc/src/main/groovy/Config.groovy index 4fb2b7ef2f..4a0b27a980 100644 --- a/buildSrc/src/main/groovy/Config.groovy +++ b/buildSrc/src/main/groovy/Config.groovy @@ -1,11 +1,3 @@ -/** - *
- *     author: blankj
- *     blog  : http://blankj.com
- *     time  : 2019/07/13
- *     desc  :
- * 
- */ class Config { static applicationId = 'com.blankj.androidutilcode' @@ -14,74 +6,84 @@ class Config { static compileSdkVersion = 29 static minSdkVersion = 14 static targetSdkVersion = 29 - static versionCode = 1_030_006 - static versionName = '1.30.7-alpha1'// E.g. 1.9.72 => 1,009,072 + static versionCode = 1_030_007 + static versionName = '1.31.0'// E.g. 1.9.72 => 1,009,072 // lib version static gradlePluginVersion = '4.1.0' static kotlinVersion = '1.3.72' static androidxVersion = '1.0.0' - static depConfig = [ - /*Never delete this line*/ - /*Generated by "config.json"*/ - plugin_api_gradle_plugin : new DepConfig(true , true , ":plugin:api-gradle-plugin"), - plugin_bus_gradle_plugin : new DepConfig(true , true , ":plugin:bus-gradle-plugin"), - plugin_lib_base_transform : new DepConfig(true , false, ":plugin:lib:base-transform", "com.blankj:base-transform:1.0"), - 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", "com.blankj:utilcode-export:1.1"), - 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:utilcodex:$versionName"), - lib_utildebug : new DepConfig(true , true , ":lib:utildebug"), - lib_utildebug_no_op : new DepConfig(true , true , ":lib:utildebug-no-op"), - /*Never delete this line*/ - plugin_gradle : new DepConfig(pluginPath: "com.android.tools.build:gradle:$gradlePluginVersion"), - plugin_kotlin : new DepConfig(pluginPath: "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"), - 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: false, localPath: "./lib/utilcode", remotePath: "com.blankj:utilcode:$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"), - // 上传新版本插件更新 pluginPath 中的版本号,并设置 isApply = false + // 上传新版本插件更新 path 中的版本号,并设置 isApply = false // 通过 mavenLocal 上传本地版本,设置 isApply = true 即可应用插件来调试,最后通过 bintrayUpload 来发布插件 - plugin_api : new DepConfig(isApply: true, useLocal: false, pluginPath: "com.blankj:api-gradle-plugin:1.5", pluginId: "com.blankj.api"), + 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 DepConfig(isApply: true, useLocal: false, pluginPath: "com.blankj:bus-gradle-plugin:2.6", pluginId: "com.blankj.bus"), + 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: true, 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 + ] - androidx_appcompat : new DepConfig("androidx.appcompat:appcompat:$androidxVersion"), - androidx_material : new DepConfig("com.google.android.material:material:$androidxVersion"), - androidx_multidex : new DepConfig("androidx.multidex:multidex:2.0.0"), - androidx_constraint : new DepConfig("androidx.constraintlayout:constraintlayout: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:$kotlinVersion"), + kotlin : new LibConfig(path: "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion"), - leakcanary : new DepConfig("com.squareup.leakcanary:leakcanary-android:2.1"), + leakcanary : new LibConfig(path: "com.squareup.leakcanary:leakcanary-android:2.1"), - free_proguard : new DepConfig("com.blankj:free-proguard:1.0.2"), - 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.5"), - 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.3.1"), + test_junit : new LibConfig(path: "junit:junit:4.12"), + test_robolectric : new LibConfig(path: "org.robolectric:robolectric:4.3.1"), ] } //./gradlew clean :lib_utilcode:bintrayUpload \ No newline at end of file diff --git a/buildSrc/src/main/groovy/ConfigUtils.groovy b/buildSrc/src/main/groovy/ConfigUtils.groovy index d60518fac5..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 entry : Config.depConfig.entrySet()) { + for (Map.Entry entry : Config.modules.entrySet()) { def (name, config) = [entry.key, entry.value] - if (entry.value.pluginPath) { - config.dep = config.pluginPath + if (config.useLocal) { + config.dep = gradle.rootProject.findProject(name) } else { - if (config.useLocal) { - config.dep = gradle.rootProject.findProject(config.projectPath) - } else { - config.dep = config.remotePath - } + config.dep = config.remotePath } configs.put(name, config) } @@ -46,20 +41,18 @@ class ConfigUtils { @Override void beforeEvaluate(Project project) { // 在 project 的 build.gradle 前 do sth. - if (project.subprojects.isEmpty()) { - if (project.path.startsWith(":plugin")) { - return + if (project.name.contains("plugin")) { + return + } + if (project.name.endsWith("_app")) { + GLog.l(project.toString() + " applies buildApp.gradle") + project.apply { + from "${project.rootDir.path}/buildApp.gradle" } - if (project.name.endsWith("_app")) { - GLog.l(project.toString() + " applies buildApp.gradle") - project.apply { - from "${project.rootDir.path}/buildApp.gradle" - } - } else { - GLog.l(project.toString() + " applies buildLib.gradle") - project.apply { - from "${project.rootDir.path}/buildLib.gradle" - } + } else { + GLog.l(project.toString() + " applies buildLib.gradle") + project.apply { + from "${project.rootDir.path}/buildLib.gradle" } } } @@ -73,8 +66,8 @@ class ConfigUtils { static getApplyPlugins() { def plugins = [:] - for (Map.Entry entry : Config.depConfig.entrySet()) { - if (entry.value.isApply && entry.value.pluginPath) { + for (Map.Entry entry : Config.plugins.entrySet()) { + if (entry.value.isApply) { plugins.put(entry.key, entry.value) } } @@ -84,7 +77,7 @@ class ConfigUtils { static getApplyPkgs() { def pkgs = [:] - for (Map.Entry entry : Config.depConfig.entrySet()) { + for (Map.Entry entry : Config.modules.entrySet()) { if (entry.value.isApply && entry.key.endsWith("_pkg")) { pkgs.put(entry.key, entry.value) } @@ -95,7 +88,7 @@ class ConfigUtils { static getApplyExports() { def exports = [:] - for (Map.Entry entry : Config.depConfig.entrySet()) { + for (Map.Entry entry : Config.modules.entrySet()) { if (entry.value.isApply && entry.key.endsWith("_export")) { exports.put(entry.key, entry.value) } diff --git a/buildSrc/src/main/groovy/DepConfig.groovy b/buildSrc/src/main/groovy/DepConfig.groovy deleted file mode 100644 index 042b67036d..0000000000 --- a/buildSrc/src/main/groovy/DepConfig.groovy +++ /dev/null @@ -1,93 +0,0 @@ -/** - *
- *     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 - } - - String getProjectPath() { - return ":" + localPath.substring(1).replace(":", "_") - } - - @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 f525377a79..0000000000 --- a/buildSrc/src/main/groovy/GitUtils.groovy +++ /dev/null @@ -1,111 +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 Project rootProject; - - static void init(Gradle gradle) { - rootProject = gradle.rootProject - addGitHelpTask() - } - - static def addGitHelpTask() { - rootProject.task("gitHelp").doLast { - def commands = [ - " ############## input command code #################", - " # [1] Git Push #", - " # [2] Git Push And Merge to Master #", - " # [3] Git New Branch #", - " # [0] exit #", - " ###################################################", - ] - String commandTips = String.join(System.getProperty("line.separator"), commands) - while (true) { - GLog.l(commandTips) - Scanner scanner = new Scanner(System.in) - def input = scanner.next() - GLog.l(input) - switch (input) { - case "1": - gitPush() - break - case "2": - gitPushAndMerge2Master() - break - case "3": - gitNewBranch() - break - case "0": - return - } - } - } - } - - static void gitPush() { - String branchName = getGitBranch() - SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM/dd") - String date = simpleDateFormat.format(new Date()) - exeCmd( - "git add -A", - "git commit -m \"see $date log\"", - "git push origin $branchName" - ) - } - - static void gitPushAndMerge2Master() { - String branchName = getGitBranch() - SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM/dd") - String date = simpleDateFormat.format(new Date()) - exeCmd( - "git add -A", - "git commit -m \"see $date log\"", - "git push origin $branchName", - "git checkout master", - "git merge $branchName", - "git push origin master", - "git checkout $branchName" - ) - } - - static void gitNewBranch() { - exeCmd( - "git checkout master", - "git checkout -b ${Config.versionName}", - "git push origin ${Config.versionName}:${Config.versionName}", - ) - } - - private static def getGitBranch() { - return exeCmd("git symbolic-ref --short -q HEAD") - } - - private static def exeCmd(String... cmds) { - String output = "" - for (def cmd in cmds) { - output = _exeCmd(cmd) - } - return output - } - - private static def _exeCmd(String cmd) { - def output = new StringBuilder() - GLog.l("Execute command: ${cmd}") - def cmdResult = ShellUtils.execCmd(cmd) - GLog.l("$cmdResult") - return cmdResult.successMsg - } -} -// ./gradlew gitHelp diff --git a/buildSrc/src/main/groovy/LibConfig.groovy b/buildSrc/src/main/groovy/LibConfig.groovy new file mode 100644 index 0000000000..6369553ba0 --- /dev/null +++ b/buildSrc/src/main/groovy/LibConfig.groovy @@ -0,0 +1,29 @@ +class LibConfig { + + String path + + String getGroupId() { + String[] splits = path.split(":") + return splits.length == 3 ? splits[0] : null + } + + String getArtifactId() { + String[] splits = path.split(":") + return splits.length == 3 ? splits[1] : null + } + + String getVersion() { + String[] splits = path.split(":") + return splits.length == 3 ? splits[2] : null + } + + @Override + String toString() { + return "LibConfig { path = $path }" + } + + static String getFlag(boolean b) { + return b ? "✅" : "❌" + } +} + diff --git a/buildSrc/src/main/groovy/ModuleConfig.groovy b/buildSrc/src/main/groovy/ModuleConfig.groovy new file mode 100644 index 0000000000..291abd8ffe --- /dev/null +++ b/buildSrc/src/main/groovy/ModuleConfig.groovy @@ -0,0 +1,35 @@ +class ModuleConfig { + + boolean isApply // 是否应用 + boolean useLocal // 是否使用本地的 + String localPath // 本地路径 + String remotePath // 远程路径 + def dep // 根据条件生成项目最终的依赖项 + + String getGroupId() { + String[] splits = remotePath.split(":") + return splits.length == 3 ? splits[0] : null + } + + String getArtifactId() { + String[] splits = remotePath.split(":") + return splits.length == 3 ? splits[1] : null + } + + String getVersion() { + String[] splits = remotePath.split(":") + return splits.length == 3 ? splits[2] : null + } + + @Override + String toString() { + return "ModuleConfig { isApply = ${getFlag(isApply)}" + + ", dep = " + dep + + " }" + } + + static String getFlag(boolean b) { + return b ? "✅" : "❌" + } +} + diff --git a/buildSrc/src/main/groovy/PluginConfig.groovy b/buildSrc/src/main/groovy/PluginConfig.groovy new file mode 100644 index 0000000000..3811c6a0ca --- /dev/null +++ b/buildSrc/src/main/groovy/PluginConfig.groovy @@ -0,0 +1,35 @@ +final class PluginConfig { + + boolean isApply = true // 是否应用 + boolean useLocal // 是否使用本地的 + String path // 插件路径 + String id // 插件 ID + + String getGroupId() { + String[] splits = path.split(":") + return splits.length == 3 ? splits[0] : null + } + + String getArtifactId() { + String[] splits = path.split(":") + return splits.length == 3 ? splits[1] : null + } + + String getVersion() { + String[] splits = path.split(":") + return splits.length == 3 ? splits[2] : null + } + + @Override + String toString() { + return "PluginConfig { isApply = ${getFlag(isApply)}" + + ", useLocal = ${getFlag(useLocal)}" + + ", path = " + path + + ", id = " + id + + " }" + } + + static String getFlag(boolean b) { + return b ? "✅" : "❌" + } +} \ No newline at end of file diff --git a/buildSrc/src/main/groovy/ShellUtils.java b/buildSrc/src/main/groovy/ShellUtils.java deleted file mode 100644 index ef4917c68e..0000000000 --- a/buildSrc/src/main/groovy/ShellUtils.java +++ /dev/null @@ -1,228 +0,0 @@ -import java.io.BufferedReader; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.List; - -/** - *
- *     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 commands) { - return execCmd(commands == null ? null : commands.toArray(new String[]{}), false, true); - } - - /** - * Execute the command. - * - * @param commands The commands. - * @param isRooted True to use root, false otherwise. - * @return the single {@link CommandResult} instance - */ - public static CommandResult execCmd(final List commands, final boolean isRooted) { - return execCmd(commands == null ? null : commands.toArray(new String[]{}), isRooted, true); - } - - /** - * Execute the command. - * - * @param commands The commands. - * @return the single {@link CommandResult} instance - */ - public static CommandResult execCmd(final String[] commands) { - return execCmd(commands, false, true); - } - - /** - * Execute the command. - * - * @param commands The commands. - * @param isRooted True to use root, false otherwise. - * @return the single {@link CommandResult} instance - */ - public static CommandResult execCmd(final String[] commands, final boolean isRooted) { - return execCmd(commands, isRooted, true); - } - - /** - * Execute the command. - * - * @param command The command. - * @param isRooted True to use root, false otherwise. - * @param isNeedResultMsg True to return the message of result, false otherwise. - * @return the single {@link CommandResult} instance - */ - public static CommandResult execCmd(final String command, - final boolean isRooted, - final boolean isNeedResultMsg) { - return execCmd(new String[]{command}, isRooted, isNeedResultMsg); - } - - /** - * Execute the command. - * - * @param commands The commands. - * @param isRooted True to use root, false otherwise. - * @param isNeedResultMsg True to return the message of result, false otherwise. - * @return the single {@link CommandResult} instance - */ - public static CommandResult execCmd(final List commands, - final boolean isRooted, - final boolean isNeedResultMsg) { - return execCmd(commands == null ? null : commands.toArray(new String[]{}), - isRooted, - isNeedResultMsg); - } - - /** - * Execute the command. - * - * @param commands The commands. - * @param isRooted True to use root, false otherwise. - * @param isNeedResultMsg True to return the message of result, false otherwise. - * @return the single {@link CommandResult} instance - */ - public static CommandResult execCmd(final String[] commands, - final boolean isRooted, - final boolean isNeedResultMsg) { - int result = -1; - if (commands == null || commands.length == 0) { - return new CommandResult(result, "", ""); - } - Process process = null; - BufferedReader successResult = null; - BufferedReader errorResult = null; - StringBuilder successMsg = null; - StringBuilder errorMsg = null; - DataOutputStream os = null; - try { - process = Runtime.getRuntime().exec(isRooted ? "su" : "sh"); - os = new DataOutputStream(process.getOutputStream()); - for (String command : commands) { - if (command == null) continue; - os.write(command.getBytes()); - os.writeBytes(LINE_SEP); - os.flush(); - } - os.writeBytes("exit" + LINE_SEP); - os.flush(); - result = process.waitFor(); - if (isNeedResultMsg) { - successMsg = new StringBuilder(); - errorMsg = new StringBuilder(); - successResult = new BufferedReader( - new InputStreamReader(process.getInputStream(), "UTF-8") - ); - errorResult = new BufferedReader( - new InputStreamReader(process.getErrorStream(), "UTF-8") - ); - String line; - if ((line = successResult.readLine()) != null) { - successMsg.append(line); - while ((line = successResult.readLine()) != null) { - successMsg.append(LINE_SEP).append(line); - } - } - if ((line = errorResult.readLine()) != null) { - errorMsg.append(line); - while ((line = errorResult.readLine()) != null) { - errorMsg.append(LINE_SEP).append(line); - } - } - } - } catch (Exception e) { - e.printStackTrace(); - } finally { - try { - if (os != null) { - os.close(); - } - } catch (IOException e) { - e.printStackTrace(); - } - try { - if (successResult != null) { - successResult.close(); - } - } catch (IOException e) { - e.printStackTrace(); - } - try { - if (errorResult != null) { - errorResult.close(); - } - } catch (IOException e) { - e.printStackTrace(); - } - if (process != null) { - process.destroy(); - } - } - return new CommandResult( - result, - successMsg == null ? "" : successMsg.toString(), - errorMsg == null ? "" : errorMsg.toString() - ); - } - - /** - * The result of command. - */ - public static class CommandResult { - public int result; - public String successMsg; - public String errorMsg; - - public CommandResult(final int result, final String successMsg, final String errorMsg) { - this.result = result; - this.successMsg = successMsg; - this.errorMsg = errorMsg; - } - - @Override - public String toString() { - return "result: " + result + "\n" + - "successMsg: " + successMsg + "\n" + - "errorMsg: " + errorMsg; - } - } -} diff --git a/buildSrc/src/main/groovy/TaskDurationUtils.groovy b/buildSrc/src/main/groovy/TaskDurationUtils.groovy index 9ff2722345..6aacfcf30f 100644 --- a/buildSrc/src/main/groovy/TaskDurationUtils.groovy +++ b/buildSrc/src/main/groovy/TaskDurationUtils.groovy @@ -38,6 +38,11 @@ class TaskDurationUtils { } }) grd.addBuildListener(new BuildListener() { + @Override + void beforeSettings(Settings settings) { + super.beforeSettings(settings) + } + @Override void buildStarted(Gradle gradle) {} diff --git a/config.json b/config.json deleted file mode 100644 index c4c025e27b..0000000000 --- a/config.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "appConfigDesc": "appConfig 配置的是可以跑 app 的模块,git 提交务必只包含 launcher", - "appConfig": ["launcher"], - "pkgConfigDesc": "pkgConfig 配置的是要依赖的功能包,为空则依赖全部,git 提交务必为空", - "pkgConfig": [], - "proConfigDesc": "proConfig 配置的是使用本地还是仓库,优先级低于 appConfig 和 pkgConfig", - "proConfig": [ - {"isApply": true, "useLocal": true, "localPath": ":plugin:api-gradle-plugin"}, - {"isApply": true, "useLocal": true, "localPath": ":plugin:bus-gradle-plugin"}, - {"isApply": true, "useLocal": false, "localPath": ":plugin:lib:base-transform", "remotePath": "com.blankj:base-transform:1.0"}, - {"isApply": true, "useLocal": true, "localPath": ":feature:mock"}, - {"isApply": true, "useLocal": true, "localPath": ":feature:launcher:app"}, - {"isApply": true, "useLocal": true, "localPath": ":feature:main:app"}, - {"isApply": true, "useLocal": true, "localPath": ":feature:main:pkg"}, - {"isApply": true, "useLocal": true, "localPath": ":feature:subutil:app"}, - {"isApply": true, "useLocal": true, "localPath": ":feature:subutil:pkg"}, - {"isApply": true, "useLocal": true, "localPath": ":feature:subutil:export"}, - {"isApply": true, "useLocal": true, "localPath": ":feature:utilcode:app"}, - {"isApply": true, "useLocal": true, "localPath": ":feature:utilcode:pkg"}, - {"isApply": true, "useLocal": true, "localPath": ":feature:utilcode:export", "remotePath": "com.blankj:utilcode-export:1.1"}, - {"isApply": true, "useLocal": true, "localPath": ":lib:base"}, - {"isApply": true, "useLocal": true, "localPath": ":lib:common"}, - {"isApply": true, "useLocal": true, "localPath": ":lib:subutil"}, - {"isApply": true, "useLocal": true, "localPath": ":lib:utilcode", "remotePath": "com.blankj:utilcodex:$versionName"}, - {"isApply": true, "useLocal": true, "localPath": ":lib:utildebug"}, - {"isApply": true, "useLocal": true, "localPath": ":lib:utildebug-no-op"} - ] -} diff --git a/config/publish.gradle b/config/publish.gradle index af97da785b..fa8a449f3c 100644 --- a/config/publish.gradle +++ b/config/publish.gradle @@ -9,16 +9,16 @@ 2. copy the file to the directory of gradle, and apply the file in the module ext { - groupId = Config.depConfig.lib_utilcode.groupId - artifactId = Config.depConfig.lib_utilcode.artifactId - version = Config.depConfig.lib_utilcode.version + groupId = Config.modules.lib_utilcode.groupId + artifactId = Config.modules.lib_utilcode.artifactId + version = Config.modules.lib_utilcode.version website = "https://github.com/Blankj/AndroidUtilCode" } apply from: "${rootDir.path}/config/publish.gradle" 3. execute following command to publish - ./gradlew :xxmodule:publish2Local -> upload to mavenCentral - ./gradlew :xxmodule:publish2Remote -> upload to mavenLocal + ./gradlew :xxmodule:publish2Local -> upload to mavenLocal + ./gradlew :xxmodule:publish2Remote -> upload to mavenCentral */ apply plugin: 'maven-publish' @@ -32,10 +32,8 @@ if (localPropertiesFile.exists()) { properties.load(new FileInputStream(localPropertiesFile)) properties.each { name, value -> ext[name] = value } } else { - if (!ext["signing.keyId"] && !ext["signing.password"] && - !ext["signing.secretKeyRingFile"] && - !ext["ossrhUsername"] && - !ext["ossrhPassword"]) { + if (!ext["signing.keyId"] && !ext["signing.password"] && !ext["signing.secretKeyRingFile"] + && !ext["ossrhUsername"] && !ext["ossrhPassword"]) { throw new NullPointerException("U should set MavenCentral params in local.properties") } } @@ -86,16 +84,14 @@ afterEvaluate { if (project.ext.multiPublishMode) { withXml { def dependenciesNode = asNode().getAt('dependencies')[0] ?: - asNode().appendNode('dependencies') - - configurations. - api. - getDependencies(). - each { dep -> addDependency(project, dependenciesNode, dep, "compile") } - configurations. - implementation. - getDependencies(). - each { dep -> addDependency(project, dependenciesNode, dep, "runtime") } + asNode().appendNode('dependencies') + + configurations.api.getDependencies().each { + dep -> addDependency(project, dependenciesNode, dep, "compile") + } + configurations.implementation.getDependencies().each { + dep -> addDependency(project, dependenciesNode, dep, "runtime") + } } } } @@ -136,12 +132,10 @@ private void addDependency(Project project, def dependenciesNode, Dependency dep // 那么发布到仓库,其他地方依赖该库时会找不到源码的那个库 println "publish -> module(unspecified) <${dep.group}:${dep.name}:${dep.version}>" if (project.ext.groupId || project.ext.version) { - throw new GradleException( - "The module of <" + dep.name + "> should set groupId & version.") + throw new GradleException("The module of <" + dep.name + "> should set groupId & version.") } // 源码依赖,但配置了 remotePath,让 pom 中写入 remotePath - println( - "publish -> module(wrapped) <${project.ext.groupId}:${name}:${project.ext.version}>") + println("publish -> module(wrapped) <${project.ext.groupId}:${name}:${project.ext.version}>") dependencyNode.appendNode('groupId', project.ext.pomGroupID) dependencyNode.appendNode('artifactId', dep.name) @@ -223,15 +217,9 @@ artifacts { } static def isAndroidEnv(Project project) { - return project.getPlugins().hasPlugin('com.android.application') || project. - getPlugins(). - hasPlugin('com.android.library') + return project.getPlugins().hasPlugin('com.android.application') || project.getPlugins().hasPlugin('com.android.library') } -task publish2Local(type: GradleBuild) { - tasks = ['clean', 'assemble', 'publishReleasePublicationToMavenLocal'] -} +task publish2Local(type: GradleBuild, dependsOn: ['clean', 'assemble', 'publishReleasePublicationToMavenLocal']) {} -task publish2Remote(type: GradleBuild) { - tasks = ['clean', 'assemble', 'publishReleasePublicationToMavenRepository'] -} \ No newline at end of file +task publish2Remote(type: GradleBuild, dependsOn: ['clean', 'assemble', 'publishReleasePublicationToMavenRepository']) {} \ No newline at end of file diff --git a/feature/launcher/app/build.gradle b/feature/launcher/app/build.gradle index 408db62a67..8f2b6d205d 100644 --- a/feature/launcher/app/build.gradle +++ b/feature/launcher/app/build.gradle @@ -1,5 +1,5 @@ apply plugin: 'kotlin-kapt' dependencies { - kapt Config.depConfig.eventbus_processor.dep + kapt Config.libs.eventbus_processor.path } \ No newline at end of file diff --git a/feature/utilcode/export/build.gradle b/feature/utilcode/export/build.gradle index 815f9babe6..30e59272ee 100644 --- a/feature/utilcode/export/build.gradle +++ b/feature/utilcode/export/build.gradle @@ -1,8 +1,8 @@ ext { - groupId = Config.depConfig.feature_utilcode_export.groupId - artifactId = Config.depConfig.feature_utilcode_export.artifactId - version = Config.depConfig.feature_utilcode_export.version + groupId = Config.modules.feature_utilcode_export.groupId + artifactId = Config.modules.feature_utilcode_export.artifactId + version = Config.modules.feature_utilcode_export.version website = "https://github.com/Blankj/AndroidUtilCode" } -apply from: "${rootDir.path}/config/publish.gradle" +//apply from: "${rootDir.path}/config/publish.gradle" //./gradlew :feature_utilcode_export:mavenLocal // 上传到本地 mavenLocal \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 13372aef5e24af05341d49695ee84e5f9b594659..5c2d1cf016b3885f6930543d57b744ea8c220a1a 100644 GIT binary patch literal 55616 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�J+L&6O)2CL%pxI@Gv&XXKx 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 V&}jHG \(.*\)$'` + 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 bb7fa31573..b7eb9d588c 100644 --- a/lib/base/build.gradle +++ b/lib/base/build.gradle @@ -1,15 +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.androidx_appcompat.dep - api Config.depConfig.androidx_material.dep - api Config.depConfig.androidx_multidex.dep - api Config.depConfig.androidx_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 + 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/rv/BaseItem.java b/lib/base/src/main/java/com/blankj/base/rv/BaseItem.java index 885fe1a6a5..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 @@ -24,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); @@ -43,6 +44,7 @@ public void partialUpdate(List payloads) { } void bindViewHolder(@NonNull final ItemViewHolder holder, final int position) { + isBindViewHolder = true; if (mOnItemClickListener != null) { holder.itemView.setOnClickListener(new View.OnClickListener() { @Override @@ -73,7 +75,9 @@ public boolean onLongClick(View v) { bind(holder, position); } - public void onViewRecycled(@NonNull final ItemViewHolder holder, final int position) {/**/} + public void onViewRecycled(@NonNull final ItemViewHolder holder, final int position) { + isBindViewHolder = false; + } public long getItemId() { return RecyclerView.NO_ID; diff --git a/lib/common/build.gradle b/lib/common/build.gradle index c4bb45fba5..4993b43792 100644 --- a/lib/common/build.gradle +++ b/lib/common/build.gradle @@ -1,4 +1,4 @@ dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - api Config.depConfig.lib_base.dep + api Config.modules.lib_base.dep } \ No newline at end of file diff --git a/lib/subutil/build.gradle b/lib/subutil/build.gradle index 1d2b458537..8a697c5a1e 100644 --- a/lib/subutil/build.gradle +++ b/lib/subutil/build.gradle @@ -1,5 +1,4 @@ apply { -// plugin Config.depConfig.plugin_traute.pluginId plugin "readme-sub" } @@ -9,16 +8,16 @@ readme { } dependencies { - compileOnly Config.depConfig.androidx_appcompat.dep - compileOnly Config.depConfig.androidx_material.dep - compileOnly Config.depConfig.lib_utilcode.dep - api(Config.depConfig.glide.dep) { + compileOnly Config.libs.androidx_appcompat.path + compileOnly Config.libs.androidx_material.path + compileOnly Config.modules.lib_utilcode.dep + api(Config.libs.glide.path) { exclude group: "com.android.support" } - api Config.depConfig.retrofit.dep - api Config.depConfig.gson.dep + api Config.libs.retrofit.path + api Config.libs.gson.path - testImplementation Config.depConfig.lib_utilcode.dep - testImplementation Config.depConfig.test_junit.dep - testImplementation Config.depConfig.test_robolectric.dep + testImplementation Config.modules.lib_utilcode.dep + testImplementation Config.libs.test_junit.path + testImplementation Config.libs.test_robolectric.path } \ No newline at end of file diff --git a/lib/utilcode/README-CN.md b/lib/utilcode/README-CN.md index e8edeb5927..79b18eef15 100644 --- a/lib/utilcode/README-CN.md +++ b/lib/utilcode/README-CN.md @@ -78,6 +78,7 @@ getAppSignaturesMD5 : 获取应用签名的的 MD5 值 getAppInfo : 获取 App 信息 getAppsInfo : 获取所有已安装 App 信息 getApkInfo : 获取 Apk 信息 +isFirstTimeInstalled : 判断应用是否首次安装 ``` * ### 数组相关 -> [ArrayUtils.java][array.java] -> [Test][array.test] diff --git a/lib/utilcode/build.gradle b/lib/utilcode/build.gradle index 612969a45c..37a43b0a66 100644 --- a/lib/utilcode/build.gradle +++ b/lib/utilcode/build.gradle @@ -1,5 +1,4 @@ apply { - // plugin Config.depConfig.plugin_traute.pluginId plugin "readme-core" } @@ -27,22 +26,22 @@ android { } dependencies { - implementation Config.depConfig.gson.dep + implementation Config.libs.gson.path - implementation Config.depConfig.androidx_appcompat.dep - compileOnly Config.depConfig.androidx_material.dep + implementation Config.libs.androidx_appcompat.path + compileOnly Config.libs.androidx_material.path - testImplementation Config.depConfig.test_junit.dep - testImplementation Config.depConfig.test_robolectric.dep - testImplementation Config.depConfig.androidx_appcompat.dep - testImplementation Config.depConfig.androidx_material.dep - testImplementation Config.depConfig.eventbus_lib.dep + testImplementation Config.libs.test_junit.path + testImplementation Config.libs.test_robolectric.path + testImplementation Config.libs.androidx_appcompat.path + testImplementation Config.libs.androidx_material.path + testImplementation Config.libs.eventbus_lib.path } ext { - groupId = Config.depConfig.lib_utilcode.groupId - artifactId = Config.depConfig.lib_utilcode.artifactId - version = Config.depConfig.lib_utilcode.version + groupId = Config.modules.lib_utilcode.groupId + artifactId = Config.modules.lib_utilcode.artifactId + version = Config.modules.lib_utilcode.version website = "https://github.com/Blankj/AndroidUtilCode" } apply from: "${rootDir.path}/config/publish.gradle" \ No newline at end of file diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/ActivityUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/ActivityUtils.java index 8191618118..10858f75f4 100644 --- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/ActivityUtils.java +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/ActivityUtils.java @@ -96,7 +96,8 @@ public static void removeActivityLifecycleCallbacks(@Nullable final Activity act * @return the activity by context. */ @Nullable - public static Activity getActivityByContext(@NonNull Context context) { + public static Activity getActivityByContext(@Nullable Context context) { + if (context == null) return null; Activity activity = getActivityByContextInner(context); if (!isActivityAlive(activity)) return null; return activity; diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/AppUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/AppUtils.java index 2a5b2ed4ef..8848cbd193 100644 --- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/AppUtils.java +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/AppUtils.java @@ -774,6 +774,22 @@ public static AppUtils.AppInfo getApkInfo(final String apkFilePath) { return getBean(pm, pi); } + + /** + * Return whether the application was first installed. + * + * @return {@code true}: yes
{@code false}: no + */ + public static boolean isFirstTimeInstalled() { + try { + PackageInfo pi = Utils.getApp().getPackageManager().getPackageInfo(Utils.getApp().getPackageName(), 0); + return pi.firstInstallTime == pi.lastUpdateTime; + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + return true; + } + } + private static AppInfo getBean(final PackageManager pm, final PackageInfo pi) { if (pi == null) return null; String versionName = pi.versionName; 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 69ae961662..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,15 +1,12 @@ package com.blankj.utilcode.util; -import android.annotation.SuppressLint; - +import androidx.annotation.NonNull; import java.io.File; import java.lang.Thread.UncaughtExceptionHandler; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Map; -import androidx.annotation.NonNull; - /** *
  *     author: Blankj
@@ -22,7 +19,8 @@ public final class CrashUtils {
 
     private static final String FILE_SEP = System.getProperty("file.separator");
 
-    private static final UncaughtExceptionHandler DEFAULT_UNCAUGHT_EXCEPTION_HANDLER = Thread.getDefaultUncaughtExceptionHandler();
+    private static final UncaughtExceptionHandler DEFAULT_UNCAUGHT_EXCEPTION_HANDLER =
+        Thread.getDefaultUncaughtExceptionHandler();
 
     private CrashUtils() {
         throw new UnsupportedOperationException("u can't instantiate me...");
@@ -65,7 +63,7 @@ public static void init(final OnCrashListener onCrashListener) {
     /**
      * Initialization
      *
-     * @param crashDir        The directory of saving crash information.
+     * @param crashDir The directory of saving crash information.
      * @param onCrashListener The crash listener.
      */
     public static void init(@NonNull final File crashDir, final OnCrashListener onCrashListener) {
@@ -75,22 +73,23 @@ public static void init(@NonNull final File crashDir, final OnCrashListener onCr
     /**
      * Initialization
      *
-     * @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.
      */
     public static void init(final String crashDirPath, final OnCrashListener onCrashListener) {
         String dirPath;
         if (UtilsBridge.isSpace(crashDirPath)) {
             if (UtilsBridge.isSDCardEnableByEnvironment()
-                    && Utils.getApp().getExternalFilesDir(null) != null)
+                && Utils.getApp().getExternalFilesDir(null) != null) {
                 dirPath = Utils.getApp().getExternalFilesDir(null) + FILE_SEP + "crash" + FILE_SEP;
-            else {
+            } else {
                 dirPath = Utils.getApp().getFilesDir() + FILE_SEP + "crash" + FILE_SEP;
             }
         } else {
             dirPath = crashDirPath.endsWith(FILE_SEP) ? crashDirPath : crashDirPath + FILE_SEP;
         }
-        Thread.setDefaultUncaughtExceptionHandler(getUncaughtExceptionHandler(dirPath, onCrashListener));
+        Thread.setDefaultUncaughtExceptionHandler(
+            getUncaughtExceptionHandler(dirPath, onCrashListener));
     }
 
     private static UncaughtExceptionHandler getUncaughtExceptionHandler(final String dirPath,
@@ -100,15 +99,15 @@ private static UncaughtExceptionHandler getUncaughtExceptionHandler(final String
             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);
-                if (onCrashListener != null) {
-                    onCrashListener.onCrash(info);
-                }
                 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);
+                }
             }
         };
     }
@@ -123,7 +122,7 @@ public interface OnCrashListener {
 
     public static final class CrashInfo {
         private UtilsBridge.FileHead mFileHeadProvider;
-        private Throwable            mThrowable;
+        private Throwable mThrowable;
 
         private CrashInfo(String time, Throwable throwable) {
             mThrowable = throwable;
@@ -145,8 +144,7 @@ public final Throwable getThrowable() {
 
         @Override
         public String toString() {
-            return mFileHeadProvider.toString() +
-                    UtilsBridge.getFullStackTrace(mThrowable);
+            return mFileHeadProvider.toString() + UtilsBridge.getFullStackTrace(mThrowable);
         }
     }
 }
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/KeyboardUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/KeyboardUtils.java
index f2511e831f..c87687f8a1 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/KeyboardUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/KeyboardUtils.java
@@ -17,10 +17,9 @@
 import android.view.inputmethod.InputMethodManager;
 import android.widget.EditText;
 import android.widget.FrameLayout;
-
-import java.lang.reflect.Field;
-
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import java.lang.reflect.Field;
 
 /**
  * 
@@ -42,7 +41,8 @@ private KeyboardUtils() {
      * Show the soft input.
      */
     public static void showSoftInput() {
-        InputMethodManager imm = (InputMethodManager) Utils.getApp().getSystemService(Context.INPUT_METHOD_SERVICE);
+        InputMethodManager imm =
+            (InputMethodManager) Utils.getApp().getSystemService(Context.INPUT_METHOD_SERVICE);
         if (imm == null) {
             return;
         }
@@ -52,7 +52,10 @@ public static void showSoftInput() {
     /**
      * Show the soft input.
      */
-    public static void showSoftInput(@NonNull Activity activity) {
+    public static void showSoftInput(@Nullable Activity activity) {
+        if (activity == null) {
+            return;
+        }
         if (!isSoftInputVisible(activity)) {
             toggleSoftInput();
         }
@@ -70,14 +73,16 @@ public static void showSoftInput(@NonNull final View view) {
     /**
      * Show the soft input.
      *
-     * @param view  The view.
+     * @param view The view.
      * @param flags Provides additional operating flags.  Currently may be
-     *              0 or have the {@link InputMethodManager#SHOW_IMPLICIT} bit set.
+     * 0 or have the {@link InputMethodManager#SHOW_IMPLICIT} bit set.
      */
     public static void showSoftInput(@NonNull final View view, final int flags) {
         InputMethodManager imm =
-                (InputMethodManager) Utils.getApp().getSystemService(Context.INPUT_METHOD_SERVICE);
-        if (imm == null) return;
+            (InputMethodManager) Utils.getApp().getSystemService(Context.INPUT_METHOD_SERVICE);
+        if (imm == null) {
+            return;
+        }
         view.setFocusable(true);
         view.setFocusableInTouchMode(true);
         view.requestFocus();
@@ -85,7 +90,7 @@ public static void showSoftInput(@NonNull final View view, final int flags) {
             @Override
             protected void onReceiveResult(int resultCode, Bundle resultData) {
                 if (resultCode == InputMethodManager.RESULT_UNCHANGED_HIDDEN
-                        || resultCode == InputMethodManager.RESULT_HIDDEN) {
+                    || resultCode == InputMethodManager.RESULT_HIDDEN) {
                     toggleSoftInput();
                 }
             }
@@ -98,7 +103,10 @@ protected void onReceiveResult(int resultCode, Bundle resultData) {
      *
      * @param activity The activity.
      */
-    public static void hideSoftInput(@NonNull final Activity activity) {
+    public static void hideSoftInput(@Nullable final Activity activity) {
+        if (activity == null) {
+            return;
+        }
         hideSoftInput(activity.getWindow());
     }
 
@@ -107,7 +115,10 @@ public static void hideSoftInput(@NonNull final Activity activity) {
      *
      * @param window The window.
      */
-    public static void hideSoftInput(@NonNull final Window window) {
+    public static void hideSoftInput(@Nullable final Window window) {
+        if (window == null) {
+            return;
+        }
         View view = window.getCurrentFocus();
         if (view == null) {
             View decorView = window.getDecorView();
@@ -131,8 +142,10 @@ public static void hideSoftInput(@NonNull final Window window) {
      */
     public static void hideSoftInput(@NonNull final View view) {
         InputMethodManager imm =
-                (InputMethodManager) Utils.getApp().getSystemService(Context.INPUT_METHOD_SERVICE);
-        if (imm == null) return;
+            (InputMethodManager) Utils.getApp().getSystemService(Context.INPUT_METHOD_SERVICE);
+        if (imm == null) {
+            return;
+        }
         imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
     }
 
@@ -143,7 +156,10 @@ public static void hideSoftInput(@NonNull final View view) {
      *
      * @param activity The activity.
      */
-    public static void hideSoftInputByToggle(final Activity activity) {
+    public static void hideSoftInputByToggle(@Nullable final Activity activity) {
+        if (activity == null) {
+            return;
+        }
         long nowMillis = SystemClock.elapsedRealtime();
         long delta = nowMillis - millis;
         if (Math.abs(delta) > 500 && KeyboardUtils.isSoftInputVisible(activity)) {
@@ -157,8 +173,10 @@ public static void hideSoftInputByToggle(final Activity activity) {
      */
     public static void toggleSoftInput() {
         InputMethodManager imm =
-                (InputMethodManager) Utils.getApp().getSystemService(Context.INPUT_METHOD_SERVICE);
-        if (imm == null) return;
+            (InputMethodManager) Utils.getApp().getSystemService(Context.INPUT_METHOD_SERVICE);
+        if (imm == null) {
+            return;
+        }
         imm.toggleSoftInput(0, 0);
     }
 
@@ -178,8 +196,8 @@ private static int getDecorViewInvisibleHeight(@NonNull final Window window) {
         final View decorView = window.getDecorView();
         final Rect outRect = new Rect();
         decorView.getWindowVisibleDisplayFrame(outRect);
-        Log.d("KeyboardUtils", "getDecorViewInvisibleHeight: "
-                + (decorView.getBottom() - outRect.bottom));
+        Log.d("KeyboardUtils",
+            "getDecorViewInvisibleHeight: " + (decorView.getBottom() - outRect.bottom));
         int delta = Math.abs(decorView.getBottom() - outRect.bottom);
         if (delta <= UtilsBridge.getNavBarHeight() + UtilsBridge.getStatusBarHeight()) {
             sDecorViewDelta = delta;
@@ -195,24 +213,26 @@ private static int getDecorViewInvisibleHeight(@NonNull final Window window) {
      * @param listener The soft input changed listener.
      */
     public static void registerSoftInputChangedListener(@NonNull final Activity activity,
-                                                        @NonNull final OnSoftInputChangedListener listener) {
+                                                        @NonNull
+                                                        final OnSoftInputChangedListener listener) {
         registerSoftInputChangedListener(activity.getWindow(), listener);
     }
 
     /**
      * Register soft input changed listener.
      *
-     * @param window   The window.
+     * @param window The window.
      * @param listener The soft input changed listener.
      */
     public static void registerSoftInputChangedListener(@NonNull final Window window,
-                                                        @NonNull final OnSoftInputChangedListener listener) {
+                                                        @NonNull
+                                                        final OnSoftInputChangedListener listener) {
         final int flags = window.getAttributes().flags;
         if ((flags & WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS) != 0) {
             window.clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
         }
         final FrameLayout contentView = window.findViewById(android.R.id.content);
-        final int[] decorViewInvisibleHeightPre = {getDecorViewInvisibleHeight(window)};
+        final int[] decorViewInvisibleHeightPre = { getDecorViewInvisibleHeight(window) };
         OnGlobalLayoutListener onGlobalLayoutListener = new OnGlobalLayoutListener() {
             @Override
             public void onGlobalLayout() {
@@ -234,11 +254,14 @@ public void onGlobalLayout() {
      */
     public static void unregisterSoftInputChangedListener(@NonNull final Window window) {
         final View contentView = window.findViewById(android.R.id.content);
-        if (contentView == null) return;
+        if (contentView == null) {
+            return;
+        }
         Object tag = contentView.getTag(TAG_ON_GLOBAL_LAYOUT_LISTENER);
         if (tag instanceof OnGlobalLayoutListener) {
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
-                contentView.getViewTreeObserver().removeOnGlobalLayoutListener((OnGlobalLayoutListener) tag);
+                contentView.getViewTreeObserver()
+                    .removeOnGlobalLayoutListener((OnGlobalLayoutListener) tag);
             }
         }
     }
@@ -261,36 +284,35 @@ public static void fixAndroidBug5497(@NonNull final Activity activity) {
      */
     public static void fixAndroidBug5497(@NonNull final Window window) {
         int softInputMode = window.getAttributes().softInputMode;
-        window.setSoftInputMode(softInputMode & ~WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
+        window.setSoftInputMode(
+            softInputMode & ~WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
         final FrameLayout contentView = window.findViewById(android.R.id.content);
         final View contentViewChild = contentView.getChildAt(0);
         final int paddingBottom = contentViewChild.getPaddingBottom();
-        final int[] contentViewInvisibleHeightPre5497 = {getContentViewInvisibleHeight(window)};
-        contentView.getViewTreeObserver()
-                .addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
-                    @Override
-                    public void onGlobalLayout() {
-                        int height = getContentViewInvisibleHeight(window);
-                        if (contentViewInvisibleHeightPre5497[0] != height) {
-                            contentViewChild.setPadding(
-                                    contentViewChild.getPaddingLeft(),
-                                    contentViewChild.getPaddingTop(),
-                                    contentViewChild.getPaddingRight(),
-                                    paddingBottom + getDecorViewInvisibleHeight(window)
-                            );
-                            contentViewInvisibleHeightPre5497[0] = height;
-                        }
-                    }
-                });
+        final int[] contentViewInvisibleHeightPre5497 = { getContentViewInvisibleHeight(window) };
+        contentView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
+            @Override
+            public void onGlobalLayout() {
+                int height = getContentViewInvisibleHeight(window);
+                if (contentViewInvisibleHeightPre5497[0] != height) {
+                    contentViewChild.setPadding(contentViewChild.getPaddingLeft(),
+                        contentViewChild.getPaddingTop(), contentViewChild.getPaddingRight(),
+                        paddingBottom + getDecorViewInvisibleHeight(window));
+                    contentViewInvisibleHeightPre5497[0] = height;
+                }
+            }
+        });
     }
 
     private static int getContentViewInvisibleHeight(final Window window) {
         final View contentView = window.findViewById(android.R.id.content);
-        if (contentView == null) return 0;
+        if (contentView == null) {
+            return 0;
+        }
         final Rect outRect = new Rect();
         contentView.getWindowVisibleDisplayFrame(outRect);
-        Log.d("KeyboardUtils", "getContentViewInvisibleHeight: "
-                + (contentView.getBottom() - outRect.bottom));
+        Log.d("KeyboardUtils",
+            "getContentViewInvisibleHeight: " + (contentView.getBottom() - outRect.bottom));
         int delta = Math.abs(contentView.getBottom() - outRect.bottom);
         if (delta <= UtilsBridge.getStatusBarHeight() + UtilsBridge.getNavBarHeight()) {
             return 0;
@@ -314,9 +336,12 @@ public static void fixSoftInputLeaks(@NonNull final Activity activity) {
      */
     public static void fixSoftInputLeaks(@NonNull final Window window) {
         InputMethodManager imm =
-                (InputMethodManager) Utils.getApp().getSystemService(Context.INPUT_METHOD_SERVICE);
-        if (imm == null) return;
-        String[] leakViews = new String[]{"mLastSrvView", "mCurRootView", "mServedView", "mNextServedView"};
+            (InputMethodManager) Utils.getApp().getSystemService(Context.INPUT_METHOD_SERVICE);
+        if (imm == null) {
+            return;
+        }
+        String[] leakViews =
+            new String[] { "mLastSrvView", "mCurRootView", "mServedView", "mNextServedView" };
         for (String leakView : leakViews) {
             try {
                 Field leakViewField = InputMethodManager.class.getDeclaredField(leakView);
@@ -324,7 +349,9 @@ public static void fixSoftInputLeaks(@NonNull final Window window) {
                     leakViewField.setAccessible(true);
                 }
                 Object obj = leakViewField.get(imm);
-                if (!(obj instanceof View)) continue;
+                if (!(obj instanceof View)) {
+                    continue;
+                }
                 View view = (View) obj;
                 if (view.getRootView() == window.getDecorView().getRootView()) {
                     leakViewField.set(imm, null);
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/MetaDataUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/MetaDataUtils.java
index bd4b8da935..0ff8fa8798 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/MetaDataUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/MetaDataUtils.java
@@ -118,7 +118,7 @@ public static String getMetaDataInService(@NonNull final Class getActivitiesByReflect() {
         Activity topActivity = null;
         try {
             Object activityThread = getActivityThread();
+            if (activityThread == null) return list;
             Field mActivitiesField = activityThread.getClass().getDeclaredField("mActivities");
             mActivitiesField.setAccessible(true);
             Object mActivities = mActivitiesField.get(activityThread);
@@ -388,10 +381,10 @@ private List getActivitiesByReflect() {
                     if (!pausedField.getBoolean(activityRecord)) {
                         topActivity = activity;
                     } else {
-                        list.add(activity);
+                        list.addFirst(activity);
                     }
                 } else {
-                    list.add(activity);
+                    list.addFirst(activity);
                 }
             }
         } catch (Exception e) {
diff --git a/lib/utildebug/build.gradle b/lib/utildebug/build.gradle
index 22f1f7294b..d1c5a67273 100644
--- a/lib/utildebug/build.gradle
+++ b/lib/utildebug/build.gradle
@@ -1,12 +1,12 @@
 dependencies {
-    compileOnly Config.depConfig.androidx_appcompat.dep
-    compileOnly Config.depConfig.androidx_material.dep
+    compileOnly Config.libs.androidx_appcompat.path
+    compileOnly Config.libs.androidx_material.path
 
-    implementation Config.depConfig.lib_utilcode.dep
-    implementation Config.depConfig.swipe_panel.dep
-    implementation Config.depConfig.photo_view.dep
+    implementation Config.modules.lib_utilcode.dep
+    implementation Config.libs.swipe_panel.path
+    implementation Config.libs.photo_view.path
 
-    testImplementation Config.depConfig.test_junit.dep
-    testImplementation Config.depConfig.test_robolectric.dep
-    testImplementation Config.depConfig.androidx_appcompat.dep
+    testImplementation Config.libs.test_junit.path
+    testImplementation Config.libs.test_robolectric.path
+    testImplementation Config.libs.androidx_appcompat.path
 }
\ No newline at end of file
diff --git a/lib/utildebug/src/main/java/com/blankj/utildebug/menu/DebugMenu.java b/lib/utildebug/src/main/java/com/blankj/utildebug/menu/DebugMenu.java
index 37c53b89cb..8a0ac4f0f0 100644
--- a/lib/utildebug/src/main/java/com/blankj/utildebug/menu/DebugMenu.java
+++ b/lib/utildebug/src/main/java/com/blankj/utildebug/menu/DebugMenu.java
@@ -56,6 +56,7 @@ protected void onAttachedToWindow() {
 
     @Override
     protected void onDetachedFromWindow() {
+        int a = 0xe1;
         DebugIcon.setVisibility(true);
         super.onDetachedFromWindow();
     }
diff --git a/module_config.gradle b/module_config.gradle
new file mode 100644
index 0000000000..6be8429bd7
--- /dev/null
+++ b/module_config.gradle
@@ -0,0 +1,72 @@
+import groovy.json.JsonSlurper
+
+/**
+ * 在 module_config.json 中 根据 appConfig 和 pkgConfig 来 include 本地模块
+ * 可以考虑写成插件来更方便 apply
+ */
+
+def json = new JsonSlurper().parse(file("./module_config.json"))
+
+for (def module in json.moduleConfig) {
+    String moduleName = module.name
+
+    if (moduleName == "feature_mock") {
+        if (json.pkgConfig.isEmpty()) {
+            module.isApply = false
+        }
+    } else if (moduleName.endsWith("_app")) {
+        if (!json.appConfig.contains(moduleName)) {
+            module.isApply = false
+        }
+    } else if (moduleName.endsWith("_pkg")) {
+        if (!json.pkgConfig.isEmpty()) {
+            if (!json.pkgConfig.contains(moduleName)) {
+                module.isApply = false
+            }
+        }
+    }
+
+    if (module.useLocal && module.isApply) {
+        include moduleName
+        project(":$moduleName").projectDir = file(module.localPath)
+    }
+}
+
+def ls = System.getProperty("line.separator")
+
+List modules = []
+for (def module in json.moduleConfig) {
+    String name = module.name
+    boolean isApply = module.isApply
+    boolean useLocal = module.useLocal
+    String localPath = module.localPath
+    String remotePath = module.remotePath
+    if (localPath != null) localPath = "\"$localPath\""
+    if (remotePath != null) remotePath = "\"$remotePath\""
+    modules.add(String.format("%-12s%-27s: new ModuleConfig(isApply: %-5s, useLocal: %-5s, localPath: $localPath%s),",
+            "", name, isApply, useLocal, remotePath == null ? "" : ", remotePath: $remotePath"))
+}
+
+def configFile = file('./buildSrc/src/main/groovy/Config.groovy')
+def lines = configFile.readLines("utf8")
+def configContent = new StringBuilder()
+
+boolean enterNeverFlag = false
+for (def line : lines) {
+    if (enterNeverFlag) {
+        if (line.contains("/*Don't delete this line*/")) {
+            configContent.append(ls).append(line)
+            enterNeverFlag = false
+        }
+        continue
+    }
+    configContent.append(ls).append(line)
+    if (line.contains("/*Don't delete this line*/")) {
+        configContent.append(ls).append(String.format("%-12s/*Generated by \"module_config.json\"*/", ""))
+        enterNeverFlag = true
+        for (String m : modules) {
+            configContent.append(ls).append(m)
+        }
+    }
+}
+configFile.write(configContent.substring(ls.length()).toString())
\ No newline at end of file
diff --git a/module_config.json b/module_config.json
new file mode 100644
index 0000000000..18f416382a
--- /dev/null
+++ b/module_config.json
@@ -0,0 +1,30 @@
+{
+  "desc": "提交 git 时需要检查下配置是否正确!!!",
+  "appConfigDesc": "appConfig 配置的是可以跑 app 的模块",
+  "appConfig": ["feature_launcher_app"],
+  "pkgConfigDesc": "pkgConfig 配置的是要依赖的功能包,为空则依赖全部",
+  "pkgConfig": [],
+  "moduleConfigDesc": "moduleConfig 配置的是使用本地还是仓库,优先级低于 appConfig 和 pkgConfig",
+  "moduleConfig": [
+    {"name": "plugin_api_gradle_plugin",  "isApply": true, "useLocal": true, "localPath": "./plugin/api-gradle-plugin"},
+    {"name": "plugin_bus_gradle_plugin",  "isApply": true, "useLocal": true, "localPath": "./plugin/bus-gradle-plugin"},
+    {"name": "plugin_lib_base_transform", "isApply": true, "useLocal": true, "localPath": "./plugin/lib/base-transform", "remotePath": "com.blankj:base-transform:1.0"},
+    {"name": "plugin_buildSrc_plugin",    "isApply": true, "useLocal": true, "localPath": "./plugin/buildSrc-plugin"},
+    {"name": "feature_mock",              "isApply": true, "useLocal": true, "localPath": "./feature/mock"},
+    {"name": "feature_launcher_app",      "isApply": true, "useLocal": true, "localPath": "./feature/launcher/app"},
+    {"name": "feature_main_app",          "isApply": true, "useLocal": true, "localPath": "./feature/main/app"},
+    {"name": "feature_main_pkg",          "isApply": true, "useLocal": true, "localPath": "./feature/main/pkg"},
+    {"name": "feature_subutil_app",       "isApply": true, "useLocal": true, "localPath": "./feature/subutil/app"},
+    {"name": "feature_subutil_pkg",       "isApply": true, "useLocal": true, "localPath": "./feature/subutil/pkg"},
+    {"name": "feature_subutil_export",    "isApply": true, "useLocal": true, "localPath": "./feature/subutil/export"},
+    {"name": "feature_utilcode_app",      "isApply": true, "useLocal": true, "localPath": "./feature/utilcode/app"},
+    {"name": "feature_utilcode_pkg",      "isApply": true, "useLocal": true, "localPath": "./feature/utilcode/pkg"},
+    {"name": "feature_utilcode_export",   "isApply": true, "useLocal": true, "localPath": "./feature/utilcode/export", "remotePath": "com.blankj:utilcode-export:1.1"},
+    {"name": "lib_base",                  "isApply": true, "useLocal": true, "localPath": "./lib/base"},
+    {"name": "lib_common",                "isApply": true, "useLocal": true, "localPath": "./lib/common"},
+    {"name": "lib_subutil",               "isApply": true, "useLocal": true, "localPath": "./lib/subutil"},
+    {"name": "lib_utilcode",              "isApply": true, "useLocal": false, "localPath": "./lib/utilcode", "remotePath": "com.blankj:utilcodex:$Config.versionName"},
+    {"name": "lib_utildebug",             "isApply": true, "useLocal": true, "localPath": "./lib/utildebug"},
+    {"name": "lib_utildebug_no_op",       "isApply": true, "useLocal": true, "localPath": "./lib/utildebug-no-op"}
+  ]
+}
diff --git a/module_config.yaml b/module_config.yaml
new file mode 100644
index 0000000000..b10ce808e6
--- /dev/null
+++ b/module_config.yaml
@@ -0,0 +1,91 @@
+desc: 提交 git 时需要检查下配置是否正确!!!
+appConfigDesc: appConfig 配置的是可以跑 app 的模块
+appConfig:
+  - feature_launcher_app
+pkgConfigDesc: pkgConfig 配置的是要依赖的功能包,为空则依赖全部
+pkgConfig: [ ]
+moduleConfigDesc: moduleConfig 配置的是使用本地还是仓库,优先级低于 appConfig 和 pkgConfig
+moduleConfig:
+  - name: plugin_api_gradle_plugin
+      isApply: true
+      useLocal: true
+      localPath: ./plugin/api-gradle-plugin
+  - name: plugin_bus_gradle_plugin
+    isApply: true
+    useLocal: true
+    localPath: ./plugin/bus-gradle-plugin
+  - name: plugin_lib_base_transform
+    isApply: true
+    useLocal: true
+    localPath: ./plugin/lib/base-transform
+    remotePath: 'com.blankj:base-transform:1.0'
+  - name: plugin_buildSrc_plugin
+    isApply: true
+    useLocal: true
+    localPath: ./plugin/buildSrc-plugin
+  - name: feature_mock
+    isApply: true
+    useLocal: true
+    localPath: ./feature/mock
+  - name: feature_launcher_app
+    isApply: true
+    useLocal: true
+    localPath: ./feature/launcher/app
+  - name: feature_main_app
+    isApply: true
+    useLocal: true
+    localPath: ./feature/main/app
+  - name: feature_main_pkg
+    isApply: true
+    useLocal: true
+    localPath: ./feature/main/pkg
+  - name: feature_subutil_app
+    isApply: true
+    useLocal: true
+    localPath: ./feature/subutil/app
+  - name: feature_subutil_pkg
+    isApply: true
+    useLocal: true
+    localPath: ./feature/subutil/pkg
+  - name: feature_subutil_export
+    isApply: true
+    useLocal: true
+    localPath: ./feature/subutil/export
+  - name: feature_utilcode_app
+    isApply: true
+    useLocal: true
+    localPath: ./feature/utilcode/app
+  - name: feature_utilcode_pkg
+    isApply: true
+    useLocal: true
+    localPath: ./feature/utilcode/pkg
+  - name: feature_utilcode_export
+    isApply: true
+    useLocal: true
+    localPath: ./feature/utilcode/export
+    remotePath: 'com.blankj:utilcode-export:1.1'
+  - name: lib_base
+    isApply: true
+    useLocal: true
+    localPath: ./lib/base
+  - name: lib_common
+    isApply: true
+    useLocal: true
+    localPath: ./lib/common
+  - name: lib_subutil
+    isApply: true
+    useLocal: true
+    localPath: ./lib/subutil
+  - name: lib_utilcode
+    isApply: true
+    useLocal: true
+    localPath: ./lib/utilcode
+    remotePath: 'com.blankj:utilcode:$Config.versionName'
+  - name: lib_utildebug
+    isApply: true
+    useLocal: true
+    localPath: ./lib/utildebug
+  - name: lib_utildebug_no_op
+    isApply: true
+    useLocal: true
+    localPath: ./lib/utildebug-no-op
diff --git a/plugin/api-gradle-plugin/build.gradle b/plugin/api-gradle-plugin/build.gradle
index 2f6b956ee0..8a559c213d 100755
--- a/plugin/api-gradle-plugin/build.gradle
+++ b/plugin/api-gradle-plugin/build.gradle
@@ -6,21 +6,21 @@ apply {
 gradlePlugin {
     plugins {
         apiPlugin {
-            id = 'com.blankj.api'
+            id = Config.plugins.plugin_api.id
             implementationClass = 'com.blankj.api.ApiPlugin'
         }
     }
 }
 
 dependencies {
-    compileOnly Config.depConfig.plugin_gradle.dep
-    implementation Config.depConfig.commons_io.dep
-    implementation Config.depConfig.plugin_lib_base_transform.dep
+    compileOnly Config.plugins.plugin_gradle.path
+    implementation Config.libs.commons_io.path
+    implementation Config.modules.plugin_lib_base_transform.remotePath
     implementation gradleApi()
     implementation localGroovy()
 
-    testImplementation Config.depConfig.test_junit.dep
-    testImplementation Config.depConfig.plugin_gradle.dep
+    testImplementation Config.libs.test_junit.path
+    testImplementation Config.plugins.plugin_gradle.path
 }
 
 sourceSets {
@@ -32,11 +32,9 @@ sourceSets {
 }
 
 ext {
-    groupId = Config.depConfig.plugin_api.groupId
-    artifactId = Config.depConfig.plugin_api.artifactId
-    version = Config.depConfig.plugin_api.version
+    groupId = Config.plugins.plugin_api.groupId
+    artifactId = Config.plugins.plugin_api.artifactId
+    version = Config.plugins.plugin_api.version
     website = "https://github.com/Blankj/AndroidUtilCode"
 }
 apply from: "${rootDir.path}/config/publish.gradle"
-//./gradlew clean :plugin_api-gradle-plugin:mavenLocal     // 上传到本地 mavenLocal
-//./gradlew clean :plugin_api-gradle-plugin:bintrayUpload  // 上传到 jcenter
diff --git a/plugin/buildSrc-plugin/.gitignore b/plugin/buildSrc-plugin/.gitignore
new file mode 100755
index 0000000000..42afabfd2a
--- /dev/null
+++ b/plugin/buildSrc-plugin/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/plugin/buildSrc-plugin/build.gradle b/plugin/buildSrc-plugin/build.gradle
new file mode 100755
index 0000000000..567fbcef2d
--- /dev/null
+++ b/plugin/buildSrc-plugin/build.gradle
@@ -0,0 +1,37 @@
+apply {
+    plugin "groovy"
+    plugin "java-gradle-plugin"
+}
+
+gradlePlugin {
+    plugins {
+        apiPlugin {
+            id = 'com.blankj.buildSrc'
+            implementationClass = 'com.blankj.buildSrc.BuildSrcPlugin'
+        }
+    }
+}
+
+dependencies {
+    compileOnly Config.plugins.plugin_gradle.path
+    implementation Config.libs.commons_io.path
+    implementation gradleApi()
+    implementation localGroovy()
+}
+
+sourceSets {
+    main {
+        groovy {
+            srcDirs += 'src/main/java'
+        }
+    }
+}
+
+ext {
+    groupId = Config.plugins.plugin_buildSrc.groupId
+    artifactId = Config.plugins.plugin_buildSrc.artifactId
+    version = Config.plugins.plugin_buildSrc.version
+    website = "https://github.com/Blankj/AndroidUtilCode"
+}
+apply from: "${rootDir.path}/config/publish.gradle"
+//./gradlew clean plugin:plugin_buildSrc-plugin:publish2Local     // 上传到本地 mavenLocal
diff --git a/plugin/buildSrc-plugin/src/main/java/com/blankj/buildSrc/BuildSrcPlugin.groovy b/plugin/buildSrc-plugin/src/main/java/com/blankj/buildSrc/BuildSrcPlugin.groovy
new file mode 100644
index 0000000000..2915b3ffe1
--- /dev/null
+++ b/plugin/buildSrc-plugin/src/main/java/com/blankj/buildSrc/BuildSrcPlugin.groovy
@@ -0,0 +1,13 @@
+package com.blankj.buildSrc;
+
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+
+class BuildSrcPlugin implements Plugin {
+
+    @Override
+    void apply(Project project) {
+        println 'apply BuildSrcPlugin'
+        ModuleCfg.main()
+    }
+}
\ No newline at end of file
diff --git a/plugin/buildSrc-plugin/src/main/java/com/blankj/buildSrc/ModuleCfg.groovy b/plugin/buildSrc-plugin/src/main/java/com/blankj/buildSrc/ModuleCfg.groovy
new file mode 100644
index 0000000000..d52675d158
--- /dev/null
+++ b/plugin/buildSrc-plugin/src/main/java/com/blankj/buildSrc/ModuleCfg.groovy
@@ -0,0 +1,80 @@
+package com.blankj.buildSrc
+
+import groovy.json.JsonSlurper
+
+
+/**
+ * 在 config.json 中 根据 appConfig 和 pkgConfig 来 include 本地模块
+ * 可以考虑写成插件来更方便 apply
+ */
+
+println 'exe ModuleCfg.groovy'
+
+def config = new JsonSlurper().parse(file("./config.json"))
+
+for (def pro in config.proConfig) {
+    String localPath = pro.localPath
+
+    if (localPath == ":feature:mock") {
+        if (config.pkgConfig.isEmpty()) {
+            pro.isApply = false
+        }
+    } else if (localPath.endsWith(":app")) {
+        def appName = localPath.substring(":feature:".length(), localPath.length() - 4)
+        if (!config.appConfig.contains(appName)) {
+            pro.isApply = false
+        }
+    } else if (localPath.endsWith(":pkg")) {
+        if (!config.pkgConfig.isEmpty()) {
+            def pkgName = localPath.substring(":feature:".length(), localPath.length() - 4)
+            if (!config.pkgConfig.contains(pkgName)) {
+                pro.isApply = false
+            }
+        }
+    }
+
+    if (pro.useLocal && pro.isApply) {
+        def projectPath = ":" + localPath.substring(1).replace(":", "_")
+        include projectPath
+        project(projectPath).projectDir = file(localPath.substring(1).replace(":", "/"))
+    }
+}
+
+def ls = System.getProperty("line.separator")
+
+List proDeps = []
+for (def pro in config.proConfig) {
+    boolean useLocal = pro.useLocal
+    String localPath = pro.localPath
+    String remotePath = pro.remotePath
+    String name = localPath.replace(":", "_").replace("-", "_").substring(1)
+    if (localPath != null) localPath = "\"$localPath\""
+    if (remotePath != null) remotePath = "\"$remotePath\""
+    boolean isApply = pro.isApply
+    proDeps.add(String.format("%-12s%-27s: new DepConfig(%-5s, %-5s, $localPath%s),",
+            "", name, isApply, useLocal, remotePath == null ? "" : ", $remotePath"))
+}
+
+def configFile = file('./buildSrc/src/main/groovy/ModuleConfig.groovy')
+def lines = configFile.readLines("utf8")
+def configContent = new StringBuilder()
+
+boolean enterNeverFlag = false
+for (def line : lines) {
+    if (enterNeverFlag) {
+        if (line.contains("/*Never")) {
+            configContent.append(ls).append(line)
+            enterNeverFlag = false
+        }
+        continue
+    }
+    configContent.append(ls).append(line)
+    if (line.contains("/*Never")) {
+        configContent.append(ls).append(String.format("%-12s/*Generated by \"config.json\"*/", ""))
+        enterNeverFlag = true
+        for (String dep : proDeps) {
+            configContent.append(ls).append(dep)
+        }
+    }
+}
+configFile.write(configContent.substring(ls.length()).toString())
\ No newline at end of file
diff --git a/plugin/bus-gradle-plugin/build.gradle b/plugin/bus-gradle-plugin/build.gradle
index 7cd24042a7..68e43c6867 100755
--- a/plugin/bus-gradle-plugin/build.gradle
+++ b/plugin/bus-gradle-plugin/build.gradle
@@ -6,21 +6,21 @@ apply {
 gradlePlugin {
     plugins {
         busPlugin {
-            id = 'com.blankj.bus'
+            id = Config.plugins.plugin_bus.id
             implementationClass = 'com.blankj.bus.BusPlugin'
         }
     }
 }
 
 dependencies {
-    compileOnly Config.depConfig.plugin_gradle.dep
-    implementation Config.depConfig.commons_io.dep
-    implementation Config.depConfig.plugin_lib_base_transform.dep
+    compileOnly Config.plugins.plugin_gradle.path
+    implementation Config.modules.plugin_lib_base_transform.remotePath
+    implementation Config.libs.commons_io.path
     implementation gradleApi()
     implementation localGroovy()
 
-    testImplementation Config.depConfig.test_junit.dep
-    testImplementation Config.depConfig.plugin_gradle.dep
+    testImplementation Config.libs.test_junit.path
+    testImplementation Config.plugins.plugin_gradle.path
 }
 
 sourceSets {
@@ -32,9 +32,9 @@ sourceSets {
 }
 
 ext {
-    groupId = Config.depConfig.plugin_bus.groupId
-    artifactId = Config.depConfig.plugin_bus.artifactId
-    version = Config.depConfig.plugin_bus.version
+    groupId = Config.plugins.plugin_bus.groupId
+    artifactId = Config.plugins.plugin_bus.artifactId
+    version = Config.plugins.plugin_bus.version
     website = "https://github.com/Blankj/AndroidUtilCode"
 }
 apply from: "${rootDir.path}/config/publish.gradle"
diff --git a/plugin/lib/base-transform/build.gradle b/plugin/lib/base-transform/build.gradle
index 3518481ebd..8eac0ab6d3 100755
--- a/plugin/lib/base-transform/build.gradle
+++ b/plugin/lib/base-transform/build.gradle
@@ -4,8 +4,8 @@ apply {
 }
 
 dependencies {
-    compileOnly Config.depConfig.plugin_gradle.dep
-    implementation Config.depConfig.commons_io.dep
+    compileOnly Config.plugins.plugin_gradle.path
+    implementation Config.libs.commons_io.path
     implementation gradleApi()
     implementation localGroovy()
 }
@@ -19,11 +19,11 @@ sourceSets {
 }
 
 ext {
-    groupId = Config.depConfig.plugin_lib_base_transform.groupId
-    artifactId = Config.depConfig.plugin_lib_base_transform.artifactId
-    version = Config.depConfig.plugin_lib_base_transform.version
+    groupId = Config.modules.plugin_lib_base_transform.groupId
+    artifactId = Config.modules.plugin_lib_base_transform.artifactId
+    version = Config.modules.plugin_lib_base_transform.version
     website = "https://github.com/Blankj/AndroidUtilCode"
 }
 apply from: "${rootDir.path}/config/publish.gradle"
-//./gradlew clean plugin:lib:plugin_lib_base-transform:mavenLocal     // 上传到本地 mavenLocal
-//./gradlew clean plugin:lib:plugin_lib_base-transform:bintrayUpload  // 上传到 gradle 插件库中
+//./gradlew clean :plugin_lib_base-transform:mavenLocal     // 上传到本地 mavenLocal
+//./gradlew clean :plugin_lib_base-transform:bintrayUpload  // 上传到 gradle 插件库中
diff --git a/settings.gradle b/settings.gradle
index 2d1b907aca..3fb2a0a2be 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,73 +1,39 @@
-import groovy.json.JsonSlurper
-
-/**
- * 在 config.json 中 根据 appConfig 和 pkgConfig 来 include 本地模块
- */
-def config = new JsonSlurper().parse(file("./config.json"))
-
-for (def pro in config.proConfig) {
-    String localPath = pro.localPath
-
-    if (localPath == ":feature:mock") {
-        if (config.pkgConfig.isEmpty()) {
-            pro.isApply = false
-        }
-    } else if (localPath.endsWith(":app")) {
-        def appName = localPath.substring(":feature:".length(), localPath.length() - 4)
-        if (!config.appConfig.contains(appName)) {
-            pro.isApply = false
-        }
-    } else if (localPath.endsWith(":pkg")) {
-        if (!config.pkgConfig.isEmpty()) {
-            def pkgName = localPath.substring(":feature:".length(), localPath.length() - 4)
-            if (!config.pkgConfig.contains(pkgName)) {
-                pro.isApply = false
-            }
-        }
-    }
-
-    if (pro.useLocal && pro.isApply) {
-        def projectPath = ":" + localPath.substring(1).replace(":", "_")
-        include projectPath
-        project(projectPath).projectDir = file(localPath.substring(1).replace(":", "/"))
-    }
-}
-
-def ls = System.getProperty("line.separator")
-
-List proDeps = []
-for (def pro in config.proConfig) {
-    boolean useLocal = pro.useLocal
-    String localPath = pro.localPath
-    String remotePath = pro.remotePath
-    String name = localPath.replace(":", "_").replace("-", "_").substring(1)
-    if (localPath != null) localPath = "\"$localPath\""
-    if (remotePath != null) remotePath = "\"$remotePath\""
-    boolean isApply = pro.isApply
-    proDeps.add(String.format("%-12s%-27s: new DepConfig(%-5s, %-5s, $localPath%s),",
-            "", name, isApply, useLocal, remotePath == null ? "" : ", $remotePath"))
-}
-
-def configFile = file('./buildSrc/src/main/groovy/Config.groovy')
-def lines = configFile.readLines("utf8")
-def configContent = new StringBuilder()
-
-boolean enterNeverFlag = false
-for (def line : lines) {
-    if (enterNeverFlag) {
-        if (line.contains("/*Never")) {
-            configContent.append(ls).append(line)
-            enterNeverFlag = false
-        }
-        continue
-    }
-    configContent.append(ls).append(line)
-    if (line.contains("/*Never")) {
-        configContent.append(ls).append(String.format("%-12s/*Generated by \"config.json\"*/", ""))
-        enterNeverFlag = true
-        for (String dep : proDeps) {
-            configContent.append(ls).append(dep)
-        }
-    }
-}
-configFile.write(configContent.substring(ls.length()).toString())
\ No newline at end of file
+//includeBuild 'configPlugin'
+
+//buildscript {
+////    ConfigUtils.init(gradle)
+//    repositories {
+//        mavenLocal()
+//        mavenCentral()
+//    }
+//
+//    dependencies {
+//        classpath 'com.blankj:buildSrc-plugin:1.0'
+//    }
+//}
+
+//apply plugin: "com.blankj.buildSrc"
+
+
+//dependencyResolutionManagement {
+//    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+//    repositories {
+//        google()
+//        mavenCentral()
+//        jcenter() // Warning: this repository is going to shut down soon
+//        maven {url 'https://jetpack.io'} // Warning: this repository is going to shut down soon
+//    }
+//
+////    configurations.all {
+////        resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
+////
+////        resolutionStrategy.eachDependency {
+////            if (it.requested.group == 'com.android.support' && !it.requested.name.contains(
+////                    'multidex')) {
+////                it.useVersion Config.supportVersion
+////            }
+////        }
+////    }
+//}
+
+apply from: 'module_config.gradle'

From d0b890e106be3658d259ca7ec52e232b991f67f1 Mon Sep 17 00:00:00 2001
From: caimengjie 
Date: Mon, 6 Dec 2021 01:45:43 +0800
Subject: [PATCH 23/44] opt: publish v1.31.0

---
 module_config.yaml | 91 ----------------------------------------------
 1 file changed, 91 deletions(-)
 delete mode 100644 module_config.yaml

diff --git a/module_config.yaml b/module_config.yaml
deleted file mode 100644
index b10ce808e6..0000000000
--- a/module_config.yaml
+++ /dev/null
@@ -1,91 +0,0 @@
-desc: 提交 git 时需要检查下配置是否正确!!!
-appConfigDesc: appConfig 配置的是可以跑 app 的模块
-appConfig:
-  - feature_launcher_app
-pkgConfigDesc: pkgConfig 配置的是要依赖的功能包,为空则依赖全部
-pkgConfig: [ ]
-moduleConfigDesc: moduleConfig 配置的是使用本地还是仓库,优先级低于 appConfig 和 pkgConfig
-moduleConfig:
-  - name: plugin_api_gradle_plugin
-      isApply: true
-      useLocal: true
-      localPath: ./plugin/api-gradle-plugin
-  - name: plugin_bus_gradle_plugin
-    isApply: true
-    useLocal: true
-    localPath: ./plugin/bus-gradle-plugin
-  - name: plugin_lib_base_transform
-    isApply: true
-    useLocal: true
-    localPath: ./plugin/lib/base-transform
-    remotePath: 'com.blankj:base-transform:1.0'
-  - name: plugin_buildSrc_plugin
-    isApply: true
-    useLocal: true
-    localPath: ./plugin/buildSrc-plugin
-  - name: feature_mock
-    isApply: true
-    useLocal: true
-    localPath: ./feature/mock
-  - name: feature_launcher_app
-    isApply: true
-    useLocal: true
-    localPath: ./feature/launcher/app
-  - name: feature_main_app
-    isApply: true
-    useLocal: true
-    localPath: ./feature/main/app
-  - name: feature_main_pkg
-    isApply: true
-    useLocal: true
-    localPath: ./feature/main/pkg
-  - name: feature_subutil_app
-    isApply: true
-    useLocal: true
-    localPath: ./feature/subutil/app
-  - name: feature_subutil_pkg
-    isApply: true
-    useLocal: true
-    localPath: ./feature/subutil/pkg
-  - name: feature_subutil_export
-    isApply: true
-    useLocal: true
-    localPath: ./feature/subutil/export
-  - name: feature_utilcode_app
-    isApply: true
-    useLocal: true
-    localPath: ./feature/utilcode/app
-  - name: feature_utilcode_pkg
-    isApply: true
-    useLocal: true
-    localPath: ./feature/utilcode/pkg
-  - name: feature_utilcode_export
-    isApply: true
-    useLocal: true
-    localPath: ./feature/utilcode/export
-    remotePath: 'com.blankj:utilcode-export:1.1'
-  - name: lib_base
-    isApply: true
-    useLocal: true
-    localPath: ./lib/base
-  - name: lib_common
-    isApply: true
-    useLocal: true
-    localPath: ./lib/common
-  - name: lib_subutil
-    isApply: true
-    useLocal: true
-    localPath: ./lib/subutil
-  - name: lib_utilcode
-    isApply: true
-    useLocal: true
-    localPath: ./lib/utilcode
-    remotePath: 'com.blankj:utilcode:$Config.versionName'
-  - name: lib_utildebug
-    isApply: true
-    useLocal: true
-    localPath: ./lib/utildebug
-  - name: lib_utildebug_no_op
-    isApply: true
-    useLocal: true
-    localPath: ./lib/utildebug-no-op

From ccba200fd83bc6479b8b8065a4824cd0e5fd67c2 Mon Sep 17 00:00:00 2001
From: caimengjie 
Date: Mon, 6 Dec 2021 01:47:28 +0800
Subject: [PATCH 24/44] opt: publish v1.31.0

---
 CHANGELOG.md                                   |  1 +
 buildSrc/src/main/groovy/Config.groovy         |  2 +-
 config/publish.gradle                          |  8 ++++++--
 lib/utilcode/README-CN.md                      |  7 ++++---
 lib/utilcode/README.md                         |  7 ++++---
 .../com/blankj/utilcode/util/AppUtils.java     | 18 +++++++++---------
 .../com/blankj/utilcode/util/NetworkUtils.java |  5 +++--
 .../com/blankj/utilcode/util/TimeUtils.java    |  2 ++
 module_config.json                             |  2 +-
 9 files changed, 31 insertions(+), 21 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 401a5071f8..c4bcc19c85 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,4 @@
+* `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.
diff --git a/buildSrc/src/main/groovy/Config.groovy b/buildSrc/src/main/groovy/Config.groovy
index 4a0b27a980..2465570d82 100644
--- a/buildSrc/src/main/groovy/Config.groovy
+++ b/buildSrc/src/main/groovy/Config.groovy
@@ -34,7 +34,7 @@ class Config {
             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: false, localPath: "./lib/utilcode", remotePath: "com.blankj:utilcode:$Config.versionName"),
+            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*/
diff --git a/config/publish.gradle b/config/publish.gradle
index fa8a449f3c..91f749a86d 100644
--- a/config/publish.gradle
+++ b/config/publish.gradle
@@ -220,6 +220,10 @@ static def isAndroidEnv(Project project) {
     return project.getPlugins().hasPlugin('com.android.application') || project.getPlugins().hasPlugin('com.android.library')
 }
 
-task publish2Local(type: GradleBuild, dependsOn: ['clean', 'assemble', 'publishReleasePublicationToMavenLocal']) {}
+task publish2Local(type: GradleBuild) {
+    tasks = ['assemble', 'publishReleasePublicationToMavenLocal']
+}
 
-task publish2Remote(type: GradleBuild, dependsOn: ['clean', 'assemble', 'publishReleasePublicationToMavenRepository']) {}
\ No newline at end of file
+task publish2Remote(type: GradleBuild) {
+    tasks = ['assemble', 'publishReleasePublicationToMavenRepository']
+}
\ No newline at end of file
diff --git a/lib/utilcode/README-CN.md b/lib/utilcode/README-CN.md
index 79b18eef15..0e4e93f3a0 100644
--- a/lib/utilcode/README-CN.md
+++ b/lib/utilcode/README-CN.md
@@ -2,10 +2,11 @@
 
 Gradle:
 ```groovy
-implementation 'com.blankj:utilcode:1.30.6'
-
 // if u use AndroidX, use the following
-implementation 'com.blankj:utilcodex:1.30.6'
+implementation 'com.blankj:utilcodex:1.31.0'
+
+// Not in maintenance
+implementation 'com.blankj:utilcode:1.30.6'
 ```
 
 
diff --git a/lib/utilcode/README.md b/lib/utilcode/README.md
index 63f7a83ba7..cdabfba45a 100644
--- a/lib/utilcode/README.md
+++ b/lib/utilcode/README.md
@@ -2,10 +2,11 @@
 
 Gradle:
 ```groovy
-implementation 'com.blankj:utilcode:1.30.6'
-
 // if u use AndroidX, use the following
-implementation 'com.blankj:utilcodex:1.30.6'
+implementation 'com.blankj:utilcodex:1.31.0'
+
+// Not in maintenance
+implementation 'com.blankj:utilcode:1.30.6'
 ```
 
 
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/AppUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/AppUtils.java
index fe8301f9ec..8f03e1cf1f 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/AppUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/AppUtils.java
@@ -385,16 +385,16 @@ public static int getAppIconId(final String packageName) {
         }
     }
 
-    
+
     /**
      * Return true if this is the first ever time that the application is installed on the device.
      *
      * @return true if this is the first ever time that the application is installed on the device.
      */
-    public static boolean isFirstTimeInstall(){
+    public static boolean isFirstTimeInstall() {
         try {
-            Long firstInstallTime = Utils.getApp().getPackageManager().getPackageInfo(this.getAppPackageName(), 0).firstInstallTime;
-            Long lastUpdateTime = Utils.getApp().getPackageManager().getPackageInfo(this.getAppPackageName(), 0).lastUpdateTime;
+            long firstInstallTime = Utils.getApp().getPackageManager().getPackageInfo(getAppPackageName(), 0).firstInstallTime;
+            long lastUpdateTime = Utils.getApp().getPackageManager().getPackageInfo(getAppPackageName(), 0).lastUpdateTime;
             return firstInstallTime == lastUpdateTime;
         } catch (Exception e) {
             return false;
@@ -406,17 +406,17 @@ public static boolean isFirstTimeInstall(){
      *
      * @return true if app was previously installed and this one is an update/upgrade to that one, returns false if this is a fresh installation and not an update/upgrade.
      */
-    public static boolean isAppUpgraded(){
+    public static boolean isAppUpgraded() {
         try {
-            Long firstInstallTime = Utils.getApp().getPackageManager().getPackageInfo(this.getAppPackageName(), 0).firstInstallTime;
-            Long lastUpdateTime = Utils.getApp().getPackageManager().getPackageInfo(this.getAppPackageName(), 0).lastUpdateTime;
+            long firstInstallTime = Utils.getApp().getPackageManager().getPackageInfo(getAppPackageName(), 0).firstInstallTime;
+            long lastUpdateTime = Utils.getApp().getPackageManager().getPackageInfo(getAppPackageName(), 0).lastUpdateTime;
             return firstInstallTime != lastUpdateTime;
         } catch (Exception e) {
             return false;
         }
     }
-    
-   
+
+
     /**
      * Return the application's package name.
      *
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/NetworkUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/NetworkUtils.java
index b2c64a6416..e73b6487db 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/NetworkUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/NetworkUtils.java
@@ -6,6 +6,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.net.ConnectivityManager;
+import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiInfo;
@@ -280,9 +281,9 @@ public static boolean isBehindProxy(){
     public static boolean isUsingVPN(){
         ConnectivityManager cm = (ConnectivityManager) com.blankj.utilcode.util.Utils.getApp().getSystemService(Context.CONNECTIVITY_SERVICE);
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
-            return cm.getNetworkInfo(ConnectivityManager.TYPE_VPN).isConnectedOrConnecting()
+            return cm.getNetworkInfo(ConnectivityManager.TYPE_VPN).isConnectedOrConnecting();
         } else {
-            return cm.getNetworkInfo(NetworkCapabilities.TRANSPORT_VPN).isConnectedOrConnecting()
+            return cm.getNetworkInfo(NetworkCapabilities.TRANSPORT_VPN).isConnectedOrConnecting();
         }
     }
 
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/TimeUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/TimeUtils.java
index 8a38efd195..ee700cbeb7 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/TimeUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/TimeUtils.java
@@ -1,6 +1,8 @@
 package com.blankj.utilcode.util;
 
 import android.annotation.SuppressLint;
+import android.os.Build;
+import android.provider.Settings;
 
 import com.blankj.utilcode.constant.TimeConstants;
 
diff --git a/module_config.json b/module_config.json
index 18f416382a..87233122b9 100644
--- a/module_config.json
+++ b/module_config.json
@@ -23,7 +23,7 @@
     {"name": "lib_base",                  "isApply": true, "useLocal": true, "localPath": "./lib/base"},
     {"name": "lib_common",                "isApply": true, "useLocal": true, "localPath": "./lib/common"},
     {"name": "lib_subutil",               "isApply": true, "useLocal": true, "localPath": "./lib/subutil"},
-    {"name": "lib_utilcode",              "isApply": true, "useLocal": false, "localPath": "./lib/utilcode", "remotePath": "com.blankj:utilcodex:$Config.versionName"},
+    {"name": "lib_utilcode",              "isApply": true, "useLocal": true, "localPath": "./lib/utilcode", "remotePath": "com.blankj:utilcodex:$Config.versionName"},
     {"name": "lib_utildebug",             "isApply": true, "useLocal": true, "localPath": "./lib/utildebug"},
     {"name": "lib_utildebug_no_op",       "isApply": true, "useLocal": true, "localPath": "./lib/utildebug-no-op"}
   ]

From ac872f8fb52d569d252e5fe136b0f7af14798f5a Mon Sep 17 00:00:00 2001
From: caimengjie 
Date: Mon, 6 Dec 2021 01:51:47 +0800
Subject: [PATCH 25/44] fix: ci

---
 buildSrc/src/main/groovy/Config.groovy |  4 ++--
 config/publish.gradle                  | 15 ++++++---------
 module_config.json                     |  2 +-
 3 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/buildSrc/src/main/groovy/Config.groovy b/buildSrc/src/main/groovy/Config.groovy
index 2465570d82..268ec666ce 100644
--- a/buildSrc/src/main/groovy/Config.groovy
+++ b/buildSrc/src/main/groovy/Config.groovy
@@ -34,7 +34,7 @@ class Config {
             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_utilcode               : new ModuleConfig(isApply: true , useLocal: false, 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*/
@@ -54,7 +54,7 @@ class Config {
             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: true, useLocal: false, path: "com.blankj:buildSrc-plugin:1.0", id: "com.blankj.buildSrc"),
+            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
     ]
diff --git a/config/publish.gradle b/config/publish.gradle
index 91f749a86d..7608215123 100644
--- a/config/publish.gradle
+++ b/config/publish.gradle
@@ -27,17 +27,14 @@ apply plugin: 'signing'
 ext.multiPublishMode = true
 
 File localPropertiesFile = project.rootProject.file("local.properties");
-if (localPropertiesFile.exists()) {
-    Properties properties = new Properties()
-    properties.load(new FileInputStream(localPropertiesFile))
-    properties.each { name, value -> ext[name] = value }
-} else {
-    if (!ext["signing.keyId"] && !ext["signing.password"] && !ext["signing.secretKeyRingFile"]
-            && !ext["ossrhUsername"] && !ext["ossrhPassword"]) {
-        throw new NullPointerException("U should set MavenCentral params in local.properties")
-    }
+if (!localPropertiesFile.exists()) {
+    return
 }
 
+Properties properties = new Properties()
+properties.load(new FileInputStream(localPropertiesFile))
+properties.each { name, value -> ext[name] = value }
+
 afterEvaluate {
     def ext = project.ext
     publishing {
diff --git a/module_config.json b/module_config.json
index 87233122b9..18f416382a 100644
--- a/module_config.json
+++ b/module_config.json
@@ -23,7 +23,7 @@
     {"name": "lib_base",                  "isApply": true, "useLocal": true, "localPath": "./lib/base"},
     {"name": "lib_common",                "isApply": true, "useLocal": true, "localPath": "./lib/common"},
     {"name": "lib_subutil",               "isApply": true, "useLocal": true, "localPath": "./lib/subutil"},
-    {"name": "lib_utilcode",              "isApply": true, "useLocal": true, "localPath": "./lib/utilcode", "remotePath": "com.blankj:utilcodex:$Config.versionName"},
+    {"name": "lib_utilcode",              "isApply": true, "useLocal": false, "localPath": "./lib/utilcode", "remotePath": "com.blankj:utilcodex:$Config.versionName"},
     {"name": "lib_utildebug",             "isApply": true, "useLocal": true, "localPath": "./lib/utildebug"},
     {"name": "lib_utildebug_no_op",       "isApply": true, "useLocal": true, "localPath": "./lib/utildebug-no-op"}
   ]

From f9a1dbf0dfa8ad5bd20fe4f72bb72a4470b248db Mon Sep 17 00:00:00 2001
From: Absinthe 
Date: Sat, 11 Dec 2021 11:59:28 +0800
Subject: [PATCH 26/44] Explicitly specify `android:exported` to make
 compatible with Android 12.

---
 lib/utilcode/src/main/AndroidManifest.xml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lib/utilcode/src/main/AndroidManifest.xml b/lib/utilcode/src/main/AndroidManifest.xml
index fc5b75e0e3..d45dd57787 100644
--- a/lib/utilcode/src/main/AndroidManifest.xml
+++ b/lib/utilcode/src/main/AndroidManifest.xml
@@ -5,12 +5,14 @@
 
         
 
         
Date: Wed, 25 May 2022 11:18:02 +0800
Subject: [PATCH 27/44] fix bug

---
 lib/utilcode/src/main/res/xml/util_code_provider_paths.xml | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/lib/utilcode/src/main/res/xml/util_code_provider_paths.xml b/lib/utilcode/src/main/res/xml/util_code_provider_paths.xml
index ed731a2299..b88716480c 100644
--- a/lib/utilcode/src/main/res/xml/util_code_provider_paths.xml
+++ b/lib/utilcode/src/main/res/xml/util_code_provider_paths.xml
@@ -23,4 +23,9 @@
     
-
\ No newline at end of file
+      
+    
+

From 8dc01389ee5599c44c7ae26a8c26411b63bfa564 Mon Sep 17 00:00:00 2001
From: Justson 
Date: Wed, 8 Jun 2022 10:55:22 +0800
Subject: [PATCH 28/44] Update README-CN.md

---
 lib/utilcode/README-CN.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/utilcode/README-CN.md b/lib/utilcode/README-CN.md
index 0e4e93f3a0..260cabac24 100644
--- a/lib/utilcode/README-CN.md
+++ b/lib/utilcode/README-CN.md
@@ -6,7 +6,7 @@ Gradle:
 implementation 'com.blankj:utilcodex:1.31.0'
 
 // Not in maintenance
-implementation 'com.blankj:utilcode:1.30.6'
+implementation 'com.blankj:utilcode:1.30.7'
 ```
 
 

From ed848ebd638507a492946e6300b057fb621b5dba Mon Sep 17 00:00:00 2001
From: NH002 
Date: Thu, 9 Jun 2022 09:06:11 +0200
Subject: [PATCH 29/44] Added uri2FileNoCacheCopy

---
 .../main/java/com/blankj/utilcode/util/UriUtils.java  | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/UriUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/UriUtils.java
index 322b9d1190..c22d1bba38 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/UriUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/UriUtils.java
@@ -77,6 +77,17 @@ public static File uri2File(final Uri uri) {
         return copyUri2Cache(uri);
     }
 
+    /**
+     * Uri to file, without creating the cache copy if the path cannot be resolved.
+     *
+     * @param uri The uri.
+     * @return file
+     */
+    public static File uri2FileNoCacheCopy(final Uri uri) {
+        if (uri == null) return null;
+        return uri2FileReal(uri);
+    }
+    
     /**
      * Uri to file.
      *

From da8b04946981398dfb217825946af55cba3b3444 Mon Sep 17 00:00:00 2001
From: taochen <935612713@qq.com>
Date: Mon, 18 Jul 2022 16:12:33 +0800
Subject: [PATCH 30/44] =?UTF-8?q?[M]=20BarUtils=E6=B7=BB=E5=8A=A0transpare?=
 =?UTF-8?q?ntNavBar=E5=AE=9E=E7=8E=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../pkg/feature/bar/nav/BarNavActivity.kt     | 42 +++++++++++++------
 .../com/blankj/utilcode/util/BarUtils.java    | 32 +++++++++++---
 2 files changed, 57 insertions(+), 17 deletions(-)

diff --git a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/nav/BarNavActivity.kt b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/nav/BarNavActivity.kt
index 1b3032974f..48a738ecd7 100644
--- a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/nav/BarNavActivity.kt
+++ b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/nav/BarNavActivity.kt
@@ -12,7 +12,6 @@ import com.blankj.utilcode.pkg.R
 import com.blankj.utilcode.util.BarUtils
 import com.blankj.utilcode.util.CollectionUtils
 import com.blankj.utilcode.util.ColorUtils
-import com.blankj.utilcode.util.Utils
 
 /**
  * ```
@@ -41,24 +40,43 @@ class BarNavActivity : CommonActivity() {
             add(CommonItemTitle("isSupportNavBar", BarUtils.isSupportNavBar().toString()))
             if (BarUtils.isSupportNavBar()) {
                 add(CommonItemSwitch(
-                        R.string.bar_nav_visibility,
-                        { BarUtils.isNavBarVisible(this@BarNavActivity) },
-                        { BarUtils.setNavBarVisibility(this@BarNavActivity, it) }
+                    R.string.bar_nav_visibility,
+                    { BarUtils.isNavBarVisible(this@BarNavActivity) },
+                    { BarUtils.setNavBarVisibility(this@BarNavActivity, it) }
                 ))
 
                 add(CommonItemSwitch(
-                        R.string.bar_nav_light_mode,
-                        { BarUtils.isNavBarLightMode(this@BarNavActivity) },
-                        { BarUtils.setNavBarLightMode(this@BarNavActivity, it) }
+                    R.string.bar_nav_light_mode,
+                    { BarUtils.isNavBarLightMode(this@BarNavActivity) },
+                    { BarUtils.setNavBarLightMode(this@BarNavActivity, it) }
                 ))
 
                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-                    add(CommonItemClick("getNavBarColor: ${ColorUtils.int2ArgbString(BarUtils.getNavBarColor(this@BarNavActivity))}").setOnItemClickListener() { _, item, _ ->
-                        BarUtils.setNavBarColor(this@BarNavActivity, ColorUtils.getRandomColor())
-                        itemsView.updateItems(bindItems())
-                        item.title = "getNavBarColor: ${ColorUtils.int2ArgbString(BarUtils.getNavBarColor(this@BarNavActivity))}"
-                    })
+                    add(
+                        CommonItemClick(
+                            "getNavBarColor: ${
+                                ColorUtils.int2ArgbString(
+                                    BarUtils.getNavBarColor(
+                                        this@BarNavActivity
+                                    )
+                                )
+                            }"
+                        ).setOnItemClickListener() { _, item, _ ->
+                            BarUtils.setNavBarColor(
+                                this@BarNavActivity,
+                                ColorUtils.getRandomColor()
+                            )
+                            itemsView.updateItems(bindItems())
+                            item.title = "getNavBarColor: ${
+                                ColorUtils.int2ArgbString(
+                                    BarUtils.getNavBarColor(this@BarNavActivity)
+                                )
+                            }"
+                        })
                 }
+                add(CommonItemClick("transparentNavBar").setOnItemClickListener() { _, item, _ ->
+                    BarUtils.transparentNavBar(this@BarNavActivity)
+                })
             }
         }
     }
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 af9dbc4fcd..ece4f7faba 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,5 +1,7 @@
 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;
@@ -19,15 +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...");
@@ -715,4 +715,26 @@ public static boolean isNavBarLightMode(@NonNull final Window window) {
         }
         return false;
     }
+
+    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);
+            }
+        }
+        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);
+    }
 }

From 0a1be7ec672053012b2bdae6259037765ff0af14 Mon Sep 17 00:00:00 2001
From: taochen <935612713@qq.com>
Date: Mon, 18 Jul 2022 17:02:24 +0800
Subject: [PATCH 31/44] =?UTF-8?q?[M]=20=E4=BF=AE=E6=94=B9BarUtils=E6=96=B9?=
 =?UTF-8?q?=E6=B3=95=E5=88=97=E8=A1=A8=E5=8F=8A=E6=8F=8F=E8=BF=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lib/utilcode/README-CN.md | 1 +
 lib/utilcode/README.md    | 1 +
 2 files changed, 2 insertions(+)

diff --git a/lib/utilcode/README-CN.md b/lib/utilcode/README-CN.md
index 0e4e93f3a0..f7523783f9 100644
--- a/lib/utilcode/README-CN.md
+++ b/lib/utilcode/README-CN.md
@@ -141,6 +141,7 @@ getNavBarColor                       : 获取导航栏颜色
 isSupportNavBar                      : 判断是否支持导航栏
 setNavBarLightMode                   : 设置导航栏是否为浅色模式
 isNavBarLightMode                    : 判断导航栏是否为浅色模式
+transparentNavBar                    : 透明导航栏
 ```
 
 * ### 亮度相关 -> [BrightnessUtils.java][brightness.java] -> [Demo][brightness.demo]
diff --git a/lib/utilcode/README.md b/lib/utilcode/README.md
index cdabfba45a..9d2025ebb0 100644
--- a/lib/utilcode/README.md
+++ b/lib/utilcode/README.md
@@ -140,6 +140,7 @@ getNavBarColor
 isSupportNavBar
 setNavBarLightMode
 isNavBarLightMode
+transparentNavBar
 ```
 
 * ### About Brightness -> [BrightnessUtils.java][brightness.java] -> [Demo][brightness.demo]

From cf983059a82e0306ea1bdaa773f9fec0ed03ad22 Mon Sep 17 00:00:00 2001
From: taochen <935612713@qq.com>
Date: Tue, 19 Jul 2022 12:00:46 +0800
Subject: [PATCH 32/44] =?UTF-8?q?[F]=20TargetSdkVersion=2030=20AppUtils.is?=
 =?UTF-8?q?AppInstalled=E8=BF=94=E5=9B=9E=E9=94=99=E8=AF=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 lib/utilcode/src/main/AndroidManifest.xml | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/lib/utilcode/src/main/AndroidManifest.xml b/lib/utilcode/src/main/AndroidManifest.xml
index fc5b75e0e3..4d2b38e471 100644
--- a/lib/utilcode/src/main/AndroidManifest.xml
+++ b/lib/utilcode/src/main/AndroidManifest.xml
@@ -1,6 +1,15 @@
 
 
+    
+        
+            
+        
+        
+            
+        
+    
+
     
 
         
Date: Tue, 19 Jul 2022 17:31:46 +0800
Subject: [PATCH 33/44] =?UTF-8?q?[M]=20AppUtils=E5=A2=9E=E5=8A=A0getAppMin?=
 =?UTF-8?q?SdkVersion,=20getAppTargetSdkVersion=E6=94=AF=E6=8C=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../utilcode/pkg/feature/app/AppActivity.kt   | 108 ++++++++--------
 lib/utilcode/README-CN.md                     |   2 +
 lib/utilcode/README.md                        |   2 +
 .../com/blankj/utilcode/util/AppUtils.java    | 115 ++++++++++++++++--
 .../debug/tool/appInfo/AppInfoItem.java       |  15 ++-
 5 files changed, 173 insertions(+), 69 deletions(-)

diff --git a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/app/AppActivity.kt b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/app/AppActivity.kt
index 175fa1bc3b..21eb351146 100644
--- a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/app/AppActivity.kt
+++ b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/app/AppActivity.kt
@@ -54,7 +54,10 @@ class AppActivity : CommonActivity(), Utils.OnAppStatusChangedListener {
 
     override fun bindItems(): MutableList> {
         return CollectionUtils.newArrayList(
-                CommonItemSwitch("registerAppStatusChangedListener", { isRegisterAppStatusChangedListener }, {
+            CommonItemSwitch(
+                "registerAppStatusChangedListener",
+                { isRegisterAppStatusChangedListener },
+                {
                     isRegisterAppStatusChangedListener = it
                     if (it) {
                         AppUtils.registerAppStatusChangedListener(this)
@@ -62,55 +65,63 @@ class AppActivity : CommonActivity(), Utils.OnAppStatusChangedListener {
                         AppUtils.unregisterAppStatusChangedListener(this)
                     }
                 }),
-                CommonItemTitle("isAppRoot", AppUtils.isAppRoot().toString()),
-                CommonItemTitle("isAppDebug", AppUtils.isAppDebug().toString()),
-                CommonItemTitle("isAppSystem", AppUtils.isAppSystem().toString()),
-                CommonItemTitle("isAppForeground", AppUtils.isAppForeground(AppUtils.getAppPackageName()).toString()),
-                CommonItemTitle("isAppRunning", AppUtils.isAppRunning(AppUtils.getAppPackageName()).toString()),
-                CommonItemImage("getAppIcon") {
-                    it.setImageDrawable(AppUtils.getAppIcon())
-                },
-                CommonItemTitle("getAppPackageName", AppUtils.getAppPackageName()),
-                CommonItemTitle("getAppName", AppUtils.getAppName()),
-                CommonItemTitle("getAppPath", AppUtils.getAppPath()),
-                CommonItemTitle("getAppVersionName", AppUtils.getAppVersionName()),
-                CommonItemTitle("getAppVersionCode", AppUtils.getAppVersionCode().toString()),
-                CommonItemTitle("getAppSignaturesSHA1", AppUtils.getAppSignaturesSHA1().toString()),
-                CommonItemTitle("getAppSignaturesSHA256", AppUtils.getAppSignaturesSHA256().toString()),
-                CommonItemTitle("getAppSignaturesMD5", AppUtils.getAppSignaturesMD5().toString()),
-                CommonItemTitle("getAppUid", AppUtils.getAppUid().toString()),
-                CommonItemTitle("getApkInfo", AppUtils.getApkInfo(AppUtils.getAppPath()).toString()),
-
-                CommonItemClick(R.string.app_install) {
-                    if (AppUtils.isAppInstalled(Config.TEST_PKG)) {
-                        ToastUtils.showShort(R.string.app_install_tips)
+            CommonItemTitle("isAppRoot", AppUtils.isAppRoot().toString()),
+            CommonItemTitle("isAppDebug", AppUtils.isAppDebug().toString()),
+            CommonItemTitle("isAppSystem", AppUtils.isAppSystem().toString()),
+            CommonItemTitle(
+                "isAppForeground",
+                AppUtils.isAppForeground(AppUtils.getAppPackageName()).toString()
+            ),
+            CommonItemTitle(
+                "isAppRunning",
+                AppUtils.isAppRunning(AppUtils.getAppPackageName()).toString()
+            ),
+            CommonItemImage("getAppIcon") {
+                it.setImageDrawable(AppUtils.getAppIcon())
+            },
+            CommonItemTitle("getAppPackageName", AppUtils.getAppPackageName()),
+            CommonItemTitle("getAppName", AppUtils.getAppName()),
+            CommonItemTitle("getAppPath", AppUtils.getAppPath()),
+            CommonItemTitle("getAppVersionName", AppUtils.getAppVersionName()),
+            CommonItemTitle("getAppVersionCode", AppUtils.getAppVersionCode().toString()),
+            CommonItemTitle("getAppMinSdkVersion", AppUtils.getAppMinSdkVersion().toString()),
+            CommonItemTitle("getAppTargetSdkVersion", AppUtils.getAppTargetSdkVersion().toString()),
+            CommonItemTitle("getAppSignaturesSHA1", AppUtils.getAppSignaturesSHA1().toString()),
+            CommonItemTitle("getAppSignaturesSHA256", AppUtils.getAppSignaturesSHA256().toString()),
+            CommonItemTitle("getAppSignaturesMD5", AppUtils.getAppSignaturesMD5().toString()),
+            CommonItemTitle("getAppUid", AppUtils.getAppUid().toString()),
+            CommonItemTitle("getApkInfo", AppUtils.getApkInfo(AppUtils.getAppPath()).toString()),
+
+            CommonItemClick(R.string.app_install) {
+                if (AppUtils.isAppInstalled(Config.TEST_PKG)) {
+                    ToastUtils.showShort(R.string.app_install_tips)
+                } else {
+                    if (!FileUtils.isFileExists(Config.TEST_APK_PATH)) {
+                        ReleaseInstallApkTask(listener).execute()
                     } else {
-                        if (!FileUtils.isFileExists(Config.TEST_APK_PATH)) {
-                            ReleaseInstallApkTask(listener).execute()
-                        } else {
-                            listener.onReleased()
-                        }
+                        listener.onReleased()
                     }
-                },
-                CommonItemClick(R.string.app_uninstall) {
-                    if (AppUtils.isAppInstalled(Config.TEST_PKG)) {
-                        AppUtils.uninstallApp(Config.TEST_PKG)
-                    } else {
-                        ToastUtils.showShort(R.string.app_uninstall_tips)
-                    }
-                },
-                CommonItemClick(R.string.app_launch) {
-                    AppUtils.launchApp(this.packageName)
-                },
-                CommonItemClick(R.string.app_relaunch) {
-                    AppUtils.relaunchApp()
-                },
-                CommonItemClick(R.string.app_launch_details_settings, true) {
-                    AppUtils.launchAppDetailsSettings()
-                },
-                CommonItemClick(R.string.app_exit) {
-                    AppUtils.exitApp()
                 }
+            },
+            CommonItemClick(R.string.app_uninstall) {
+                if (AppUtils.isAppInstalled(Config.TEST_PKG)) {
+                    AppUtils.uninstallApp(Config.TEST_PKG)
+                } else {
+                    ToastUtils.showShort(R.string.app_uninstall_tips)
+                }
+            },
+            CommonItemClick(R.string.app_launch) {
+                AppUtils.launchApp(this.packageName)
+            },
+            CommonItemClick(R.string.app_relaunch) {
+                AppUtils.relaunchApp()
+            },
+            CommonItemClick(R.string.app_launch_details_settings, true) {
+                AppUtils.launchAppDetailsSettings()
+            },
+            CommonItemClick(R.string.app_exit) {
+                AppUtils.exitApp()
+            }
         )
     }
 
@@ -130,7 +141,8 @@ class AppActivity : CommonActivity(), Utils.OnAppStatusChangedListener {
     }
 }
 
-class ReleaseInstallApkTask(private val mListener: OnReleasedListener) : ThreadUtils.SimpleTask() {
+class ReleaseInstallApkTask(private val mListener: OnReleasedListener) :
+    ThreadUtils.SimpleTask() {
 
     override fun doInBackground() {
         ResourceUtils.copyFileFromAssets("test_install", Config.TEST_APK_PATH)
diff --git a/lib/utilcode/README-CN.md b/lib/utilcode/README-CN.md
index f7523783f9..641e96ff1d 100644
--- a/lib/utilcode/README-CN.md
+++ b/lib/utilcode/README-CN.md
@@ -72,6 +72,8 @@ getAppName                        : 获取 App 名称
 getAppPath                        : 获取 App 路径
 getAppVersionName                 : 获取 App 版本号
 getAppVersionCode                 : 获取 App 版本码
+getAppMinSdkVersion               : 获取 App 支持最低系统版本号
+getAppTargetSdkVersion            : 获取 App 目标系统版本号
 getAppSignatures                  : 获取 App 签名
 getAppSignaturesSHA1              : 获取应用签名的的 SHA1 值
 getAppSignaturesSHA256            : 获取应用签名的的 SHA256 值
diff --git a/lib/utilcode/README.md b/lib/utilcode/README.md
index 9d2025ebb0..b88bcbcfbd 100644
--- a/lib/utilcode/README.md
+++ b/lib/utilcode/README.md
@@ -72,6 +72,8 @@ getAppName
 getAppPath
 getAppVersionName
 getAppVersionCode
+getAppMinSdkVersion
+getAppTargetSdkVersion
 getAppSignatures
 getAppSignaturesSHA1
 getAppSignaturesSHA256
diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/AppUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/AppUtils.java
index 8f03e1cf1f..3a07653fb0 100644
--- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/AppUtils.java
+++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/AppUtils.java
@@ -14,13 +14,13 @@
 import android.os.Build;
 import android.util.Log;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
 import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
 
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
 /**
  * 
  *     author: Blankj
@@ -541,6 +541,65 @@ public static int getAppVersionCode(final String packageName) {
         }
     }
 
+    /**
+     * Return the application's minimum sdk version code.
+     *
+     * @return the application's minimum sdk version code
+     */
+    public static int getAppMinSdkVersion() {
+        return getAppMinSdkVersion(Utils.getApp().getPackageName());
+    }
+
+    /**
+     * Return the application's minimum sdk version code.
+     *
+     * @param packageName The name of the package.
+     * @return the application's minimum sdk version code
+     */
+    public static int getAppMinSdkVersion(final String packageName) {
+        if (UtilsBridge.isSpace(packageName)) return -1;
+        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.N) return -1;
+        try {
+            PackageManager pm = Utils.getApp().getPackageManager();
+            PackageInfo pi = pm.getPackageInfo(packageName, 0);
+            if (null == pi) return -1;
+            ApplicationInfo ai = pi.applicationInfo;
+            return null == ai ? -1 : ai.minSdkVersion;
+        } catch (PackageManager.NameNotFoundException e) {
+            e.printStackTrace();
+            return -1;
+        }
+    }
+
+    /**
+     * Return the application's target sdk version code.
+     *
+     * @return the application's target sdk version code
+     */
+    public static int getAppTargetSdkVersion() {
+        return getAppTargetSdkVersion(Utils.getApp().getPackageName());
+    }
+
+    /**
+     * Return the application's target sdk version code.
+     *
+     * @param packageName The name of the package.
+     * @return the application's target sdk version code
+     */
+    public static int getAppTargetSdkVersion(final String packageName) {
+        if (UtilsBridge.isSpace(packageName)) return -1;
+        try {
+            PackageManager pm = Utils.getApp().getPackageManager();
+            PackageInfo pi = pm.getPackageInfo(packageName, 0);
+            if (null == pi) return -1;
+            ApplicationInfo ai = pi.applicationInfo;
+            return null == ai ? -1 : ai.targetSdkVersion;
+        } catch (PackageManager.NameNotFoundException e) {
+            e.printStackTrace();
+            return -1;
+        }
+    }
+
     /**
      * Return the application's signature.
      *
@@ -721,6 +780,8 @@ private static List getAppSignaturesHash(final String packageName, final
      * 
  • path of package
  • *
  • version name
  • *
  • version code
  • + *
  • minimum sdk version code
  • + *
  • target sdk version code
  • *
  • is system
  • * * @@ -740,6 +801,8 @@ public static AppInfo getAppInfo() { *
  • path of package
  • *
  • version name
  • *
  • version code
  • + *
  • minimum sdk version code
  • + *
  • target sdk version code
  • *
  • is system
  • * * @@ -829,13 +892,18 @@ private static AppInfo getBean(final PackageManager pm, final PackageInfo pi) { String packageName = pi.packageName; ApplicationInfo ai = pi.applicationInfo; if (ai == null) { - return new AppInfo(packageName, "", null, "", versionName, versionCode, false); + return new AppInfo(packageName, "", null, "", versionName, versionCode, -1, -1, false); } String name = ai.loadLabel(pm).toString(); Drawable icon = ai.loadIcon(pm); String packagePath = ai.sourceDir; + int minSdkVersion = -1; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { + minSdkVersion = ai.minSdkVersion; + } + int targetSdkVersion = ai.targetSdkVersion; boolean isSystem = (ApplicationInfo.FLAG_SYSTEM & ai.flags) != 0; - return new AppInfo(packageName, name, icon, packagePath, versionName, versionCode, isSystem); + return new AppInfo(packageName, name, icon, packagePath, versionName, versionCode, minSdkVersion, targetSdkVersion, isSystem); } /** @@ -843,13 +911,15 @@ private static AppInfo getBean(final PackageManager pm, final PackageInfo pi) { */ public static class AppInfo { - private String packageName; - private String name; + private String packageName; + private String name; private Drawable icon; - private String packagePath; - private String versionName; - private int versionCode; - private boolean isSystem; + private String packagePath; + private String versionName; + private int versionCode; + private int minSdkVersion; + private int targetSdkVersion; + private boolean isSystem; public Drawable getIcon() { return icon; @@ -907,14 +977,31 @@ public void setVersionName(final String versionName) { this.versionName = versionName; } - public AppInfo(String packageName, String name, Drawable icon, String packagePath, - String versionName, int versionCode, boolean isSystem) { + public int getMinSdkVersion() { + return minSdkVersion; + } + + public void setMinSdkVersion(int minSdkVersion) { + this.minSdkVersion = minSdkVersion; + } + + public int getTargetSdkVersion() { + return targetSdkVersion; + } + + public void setTargetSdkVersion(int targetSdkVersion) { + this.targetSdkVersion = targetSdkVersion; + } + + public AppInfo(String packageName, String name, Drawable icon, String packagePath, String versionName, int versionCode, int minSdkVersion, int targetSdkVersion, boolean isSystem) { this.setName(name); this.setIcon(icon); this.setPackageName(packageName); this.setPackagePath(packagePath); this.setVersionName(versionName); this.setVersionCode(versionCode); + this.setMinSdkVersion(minSdkVersion); + this.setTargetSdkVersion(targetSdkVersion); this.setSystem(isSystem); } @@ -928,6 +1015,8 @@ public String toString() { "\n app path: " + getPackagePath() + "\n app v name: " + getVersionName() + "\n app v code: " + getVersionCode() + + "\n app v min: " + getMinSdkVersion() + + "\n app v target: " + getTargetSdkVersion() + "\n is system: " + isSystem() + "\n}"; } diff --git a/lib/utildebug/src/main/java/com/blankj/utildebug/debug/tool/appInfo/AppInfoItem.java b/lib/utildebug/src/main/java/com/blankj/utildebug/debug/tool/appInfo/AppInfoItem.java index 76351e4b10..54895ee71f 100644 --- a/lib/utildebug/src/main/java/com/blankj/utildebug/debug/tool/appInfo/AppInfoItem.java +++ b/lib/utildebug/src/main/java/com/blankj/utildebug/debug/tool/appInfo/AppInfoItem.java @@ -5,10 +5,12 @@ import android.view.View.OnClickListener; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; + import com.blankj.utilcode.util.AppUtils; import com.blankj.utilcode.util.ClickUtils; import com.blankj.utilcode.util.StringUtils; -import com.blankj.utildebug.DebugUtils; import com.blankj.utildebug.R; import com.blankj.utildebug.base.rv.BaseItem; import com.blankj.utildebug.base.rv.ItemViewHolder; @@ -16,9 +18,6 @@ import java.util.ArrayList; import java.util.List; -import androidx.annotation.NonNull; -import androidx.annotation.StringRes; - /** *
      *     author: blankj
    @@ -29,8 +28,8 @@
      */
     public class AppInfoItem extends BaseItem {
     
    -    private String          mTitle;
    -    private String          mContent;
    +    private String mTitle;
    +    private String mContent;
         private OnClickListener mListener;
     
         private TextView titleTv;
    @@ -71,9 +70,9 @@ public static List getAppInfoItems() {
             appInfoItems.add(new AppInfoItem(R.string.du_app_info_version_name, AppUtils.getAppVersionName()));
             appInfoItems.add(new AppInfoItem(R.string.du_app_info_version_code, String.valueOf(AppUtils.getAppVersionCode())));
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    -            appInfoItems.add(new AppInfoItem(R.string.du_app_info_min_sdk_version, String.valueOf(DebugUtils.getApp().getApplicationInfo().minSdkVersion)));
    +            appInfoItems.add(new AppInfoItem(R.string.du_app_info_min_sdk_version, String.valueOf(AppUtils.getAppMinSdkVersion())));
             }
    -        appInfoItems.add(new AppInfoItem(R.string.du_app_info_target_sdk_version, String.valueOf(DebugUtils.getApp().getApplicationInfo().targetSdkVersion)));
    +        appInfoItems.add(new AppInfoItem(R.string.du_app_info_target_sdk_version, String.valueOf(AppUtils.getAppTargetSdkVersion())));
             appInfoItems.add(new AppInfoItem(R.string.du_app_info_open_app_info_page, "", new OnClickListener() {
                 @Override
                 public void onClick(View v) {
    
    From 718f281a3da9d4e4e6c3298faf4da9e4563e7d50 Mon Sep 17 00:00:00 2001
    From: taochen <935612713@qq.com>
    Date: Mon, 18 Jul 2022 16:12:33 +0800
    Subject: [PATCH 34/44] =?UTF-8?q?[M]=20BarUtils=E6=B7=BB=E5=8A=A0transpare?=
     =?UTF-8?q?ntNavBar=E5=AE=9E=E7=8E=B0?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    ---
     .../pkg/feature/bar/nav/BarNavActivity.kt     | 42 +++++++++++++------
     .../com/blankj/utilcode/util/BarUtils.java    | 32 +++++++++++---
     2 files changed, 57 insertions(+), 17 deletions(-)
    
    diff --git a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/nav/BarNavActivity.kt b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/nav/BarNavActivity.kt
    index 1b3032974f..48a738ecd7 100644
    --- a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/nav/BarNavActivity.kt
    +++ b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/nav/BarNavActivity.kt
    @@ -12,7 +12,6 @@ import com.blankj.utilcode.pkg.R
     import com.blankj.utilcode.util.BarUtils
     import com.blankj.utilcode.util.CollectionUtils
     import com.blankj.utilcode.util.ColorUtils
    -import com.blankj.utilcode.util.Utils
     
     /**
      * ```
    @@ -41,24 +40,43 @@ class BarNavActivity : CommonActivity() {
                 add(CommonItemTitle("isSupportNavBar", BarUtils.isSupportNavBar().toString()))
                 if (BarUtils.isSupportNavBar()) {
                     add(CommonItemSwitch(
    -                        R.string.bar_nav_visibility,
    -                        { BarUtils.isNavBarVisible(this@BarNavActivity) },
    -                        { BarUtils.setNavBarVisibility(this@BarNavActivity, it) }
    +                    R.string.bar_nav_visibility,
    +                    { BarUtils.isNavBarVisible(this@BarNavActivity) },
    +                    { BarUtils.setNavBarVisibility(this@BarNavActivity, it) }
                     ))
     
                     add(CommonItemSwitch(
    -                        R.string.bar_nav_light_mode,
    -                        { BarUtils.isNavBarLightMode(this@BarNavActivity) },
    -                        { BarUtils.setNavBarLightMode(this@BarNavActivity, it) }
    +                    R.string.bar_nav_light_mode,
    +                    { BarUtils.isNavBarLightMode(this@BarNavActivity) },
    +                    { BarUtils.setNavBarLightMode(this@BarNavActivity, it) }
                     ))
     
                     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    -                    add(CommonItemClick("getNavBarColor: ${ColorUtils.int2ArgbString(BarUtils.getNavBarColor(this@BarNavActivity))}").setOnItemClickListener() { _, item, _ ->
    -                        BarUtils.setNavBarColor(this@BarNavActivity, ColorUtils.getRandomColor())
    -                        itemsView.updateItems(bindItems())
    -                        item.title = "getNavBarColor: ${ColorUtils.int2ArgbString(BarUtils.getNavBarColor(this@BarNavActivity))}"
    -                    })
    +                    add(
    +                        CommonItemClick(
    +                            "getNavBarColor: ${
    +                                ColorUtils.int2ArgbString(
    +                                    BarUtils.getNavBarColor(
    +                                        this@BarNavActivity
    +                                    )
    +                                )
    +                            }"
    +                        ).setOnItemClickListener() { _, item, _ ->
    +                            BarUtils.setNavBarColor(
    +                                this@BarNavActivity,
    +                                ColorUtils.getRandomColor()
    +                            )
    +                            itemsView.updateItems(bindItems())
    +                            item.title = "getNavBarColor: ${
    +                                ColorUtils.int2ArgbString(
    +                                    BarUtils.getNavBarColor(this@BarNavActivity)
    +                                )
    +                            }"
    +                        })
                     }
    +                add(CommonItemClick("transparentNavBar").setOnItemClickListener() { _, item, _ ->
    +                    BarUtils.transparentNavBar(this@BarNavActivity)
    +                })
                 }
             }
         }
    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 af9dbc4fcd..ece4f7faba 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,5 +1,7 @@
     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;
    @@ -19,15 +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...");
    @@ -715,4 +715,26 @@ public static boolean isNavBarLightMode(@NonNull final Window window) {
             }
             return false;
         }
    +
    +    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);
    +            }
    +        }
    +        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);
    +    }
     }
    
    From afaea3eb6b29d24c18cfbcb4a103310fd380b16e Mon Sep 17 00:00:00 2001
    From: Justson 
    Date: Wed, 8 Jun 2022 10:55:22 +0800
    Subject: [PATCH 35/44] Update README-CN.md
    
    ---
     lib/utilcode/README-CN.md | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/lib/utilcode/README-CN.md b/lib/utilcode/README-CN.md
    index 0e4e93f3a0..260cabac24 100644
    --- a/lib/utilcode/README-CN.md
    +++ b/lib/utilcode/README-CN.md
    @@ -6,7 +6,7 @@ Gradle:
     implementation 'com.blankj:utilcodex:1.31.0'
     
     // Not in maintenance
    -implementation 'com.blankj:utilcode:1.30.6'
    +implementation 'com.blankj:utilcode:1.30.7'
     ```
     
     
    
    From 555cca99df44edc2025db0a3cbe9dc1b4b65db31 Mon Sep 17 00:00:00 2001
    From: sth0409 <97033765@qq.com>
    Date: Wed, 25 May 2022 11:18:02 +0800
    Subject: [PATCH 36/44] fix bug
    
    ---
     lib/utilcode/src/main/res/xml/util_code_provider_paths.xml | 7 ++++++-
     1 file changed, 6 insertions(+), 1 deletion(-)
    
    diff --git a/lib/utilcode/src/main/res/xml/util_code_provider_paths.xml b/lib/utilcode/src/main/res/xml/util_code_provider_paths.xml
    index ed731a2299..b88716480c 100644
    --- a/lib/utilcode/src/main/res/xml/util_code_provider_paths.xml
    +++ b/lib/utilcode/src/main/res/xml/util_code_provider_paths.xml
    @@ -23,4 +23,9 @@
         
    -
    \ No newline at end of file
    +      
    +    
    +
    
    From 862088e4b85a0621f184f6ecea71367d05f9ba72 Mon Sep 17 00:00:00 2001
    From: Absinthe 
    Date: Sat, 11 Dec 2021 11:59:28 +0800
    Subject: [PATCH 37/44] Explicitly specify `android:exported` to make
     compatible with Android 12.
    
    ---
     lib/utilcode/src/main/AndroidManifest.xml | 2 ++
     1 file changed, 2 insertions(+)
    
    diff --git a/lib/utilcode/src/main/AndroidManifest.xml b/lib/utilcode/src/main/AndroidManifest.xml
    index fc5b75e0e3..d45dd57787 100644
    --- a/lib/utilcode/src/main/AndroidManifest.xml
    +++ b/lib/utilcode/src/main/AndroidManifest.xml
    @@ -5,12 +5,14 @@
     
             
     
             
    Date: Mon, 18 Jul 2022 17:02:24 +0800
    Subject: [PATCH 38/44] =?UTF-8?q?[M]=20=E4=BF=AE=E6=94=B9BarUtils=E6=96=B9?=
     =?UTF-8?q?=E6=B3=95=E5=88=97=E8=A1=A8=E5=8F=8A=E6=8F=8F=E8=BF=B0?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    ---
     lib/utilcode/README-CN.md | 1 +
     lib/utilcode/README.md    | 1 +
     2 files changed, 2 insertions(+)
    
    diff --git a/lib/utilcode/README-CN.md b/lib/utilcode/README-CN.md
    index 260cabac24..a6ab4b3d09 100644
    --- a/lib/utilcode/README-CN.md
    +++ b/lib/utilcode/README-CN.md
    @@ -141,6 +141,7 @@ getNavBarColor                       : 获取导航栏颜色
     isSupportNavBar                      : 判断是否支持导航栏
     setNavBarLightMode                   : 设置导航栏是否为浅色模式
     isNavBarLightMode                    : 判断导航栏是否为浅色模式
    +transparentNavBar                    : 透明导航栏
     ```
     
     * ### 亮度相关 -> [BrightnessUtils.java][brightness.java] -> [Demo][brightness.demo]
    diff --git a/lib/utilcode/README.md b/lib/utilcode/README.md
    index cdabfba45a..9d2025ebb0 100644
    --- a/lib/utilcode/README.md
    +++ b/lib/utilcode/README.md
    @@ -140,6 +140,7 @@ getNavBarColor
     isSupportNavBar
     setNavBarLightMode
     isNavBarLightMode
    +transparentNavBar
     ```
     
     * ### About Brightness -> [BrightnessUtils.java][brightness.java] -> [Demo][brightness.demo]
    
    From 62bf1646bf43427de4f30ff0653a3dfe6da90634 Mon Sep 17 00:00:00 2001
    From: taochen <935612713@qq.com>
    Date: Tue, 19 Jul 2022 12:00:46 +0800
    Subject: [PATCH 39/44] =?UTF-8?q?[F]=20TargetSdkVersion=2030=20AppUtils.is?=
     =?UTF-8?q?AppInstalled=E8=BF=94=E5=9B=9E=E9=94=99=E8=AF=AF?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    ---
     lib/utilcode/src/main/AndroidManifest.xml | 9 +++++++++
     1 file changed, 9 insertions(+)
    
    diff --git a/lib/utilcode/src/main/AndroidManifest.xml b/lib/utilcode/src/main/AndroidManifest.xml
    index d45dd57787..ab497595d4 100644
    --- a/lib/utilcode/src/main/AndroidManifest.xml
    +++ b/lib/utilcode/src/main/AndroidManifest.xml
    @@ -1,6 +1,15 @@
     
     
    +    
    +        
    +            
    +        
    +        
    +            
    +        
    +    
    +
         
     
             
    Date: Tue, 19 Jul 2022 17:31:46 +0800
    Subject: [PATCH 40/44] =?UTF-8?q?[M]=20AppUtils=E5=A2=9E=E5=8A=A0getAppMin?=
     =?UTF-8?q?SdkVersion,=20getAppTargetSdkVersion=E6=94=AF=E6=8C=81?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    ---
     .../utilcode/pkg/feature/app/AppActivity.kt   | 108 ++++++++--------
     lib/utilcode/README-CN.md                     |   2 +
     lib/utilcode/README.md                        |   2 +
     .../com/blankj/utilcode/util/AppUtils.java    | 115 ++++++++++++++++--
     .../debug/tool/appInfo/AppInfoItem.java       |  15 ++-
     5 files changed, 173 insertions(+), 69 deletions(-)
    
    diff --git a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/app/AppActivity.kt b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/app/AppActivity.kt
    index 175fa1bc3b..21eb351146 100644
    --- a/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/app/AppActivity.kt
    +++ b/feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/app/AppActivity.kt
    @@ -54,7 +54,10 @@ class AppActivity : CommonActivity(), Utils.OnAppStatusChangedListener {
     
         override fun bindItems(): MutableList> {
             return CollectionUtils.newArrayList(
    -                CommonItemSwitch("registerAppStatusChangedListener", { isRegisterAppStatusChangedListener }, {
    +            CommonItemSwitch(
    +                "registerAppStatusChangedListener",
    +                { isRegisterAppStatusChangedListener },
    +                {
                         isRegisterAppStatusChangedListener = it
                         if (it) {
                             AppUtils.registerAppStatusChangedListener(this)
    @@ -62,55 +65,63 @@ class AppActivity : CommonActivity(), Utils.OnAppStatusChangedListener {
                             AppUtils.unregisterAppStatusChangedListener(this)
                         }
                     }),
    -                CommonItemTitle("isAppRoot", AppUtils.isAppRoot().toString()),
    -                CommonItemTitle("isAppDebug", AppUtils.isAppDebug().toString()),
    -                CommonItemTitle("isAppSystem", AppUtils.isAppSystem().toString()),
    -                CommonItemTitle("isAppForeground", AppUtils.isAppForeground(AppUtils.getAppPackageName()).toString()),
    -                CommonItemTitle("isAppRunning", AppUtils.isAppRunning(AppUtils.getAppPackageName()).toString()),
    -                CommonItemImage("getAppIcon") {
    -                    it.setImageDrawable(AppUtils.getAppIcon())
    -                },
    -                CommonItemTitle("getAppPackageName", AppUtils.getAppPackageName()),
    -                CommonItemTitle("getAppName", AppUtils.getAppName()),
    -                CommonItemTitle("getAppPath", AppUtils.getAppPath()),
    -                CommonItemTitle("getAppVersionName", AppUtils.getAppVersionName()),
    -                CommonItemTitle("getAppVersionCode", AppUtils.getAppVersionCode().toString()),
    -                CommonItemTitle("getAppSignaturesSHA1", AppUtils.getAppSignaturesSHA1().toString()),
    -                CommonItemTitle("getAppSignaturesSHA256", AppUtils.getAppSignaturesSHA256().toString()),
    -                CommonItemTitle("getAppSignaturesMD5", AppUtils.getAppSignaturesMD5().toString()),
    -                CommonItemTitle("getAppUid", AppUtils.getAppUid().toString()),
    -                CommonItemTitle("getApkInfo", AppUtils.getApkInfo(AppUtils.getAppPath()).toString()),
    -
    -                CommonItemClick(R.string.app_install) {
    -                    if (AppUtils.isAppInstalled(Config.TEST_PKG)) {
    -                        ToastUtils.showShort(R.string.app_install_tips)
    +            CommonItemTitle("isAppRoot", AppUtils.isAppRoot().toString()),
    +            CommonItemTitle("isAppDebug", AppUtils.isAppDebug().toString()),
    +            CommonItemTitle("isAppSystem", AppUtils.isAppSystem().toString()),
    +            CommonItemTitle(
    +                "isAppForeground",
    +                AppUtils.isAppForeground(AppUtils.getAppPackageName()).toString()
    +            ),
    +            CommonItemTitle(
    +                "isAppRunning",
    +                AppUtils.isAppRunning(AppUtils.getAppPackageName()).toString()
    +            ),
    +            CommonItemImage("getAppIcon") {
    +                it.setImageDrawable(AppUtils.getAppIcon())
    +            },
    +            CommonItemTitle("getAppPackageName", AppUtils.getAppPackageName()),
    +            CommonItemTitle("getAppName", AppUtils.getAppName()),
    +            CommonItemTitle("getAppPath", AppUtils.getAppPath()),
    +            CommonItemTitle("getAppVersionName", AppUtils.getAppVersionName()),
    +            CommonItemTitle("getAppVersionCode", AppUtils.getAppVersionCode().toString()),
    +            CommonItemTitle("getAppMinSdkVersion", AppUtils.getAppMinSdkVersion().toString()),
    +            CommonItemTitle("getAppTargetSdkVersion", AppUtils.getAppTargetSdkVersion().toString()),
    +            CommonItemTitle("getAppSignaturesSHA1", AppUtils.getAppSignaturesSHA1().toString()),
    +            CommonItemTitle("getAppSignaturesSHA256", AppUtils.getAppSignaturesSHA256().toString()),
    +            CommonItemTitle("getAppSignaturesMD5", AppUtils.getAppSignaturesMD5().toString()),
    +            CommonItemTitle("getAppUid", AppUtils.getAppUid().toString()),
    +            CommonItemTitle("getApkInfo", AppUtils.getApkInfo(AppUtils.getAppPath()).toString()),
    +
    +            CommonItemClick(R.string.app_install) {
    +                if (AppUtils.isAppInstalled(Config.TEST_PKG)) {
    +                    ToastUtils.showShort(R.string.app_install_tips)
    +                } else {
    +                    if (!FileUtils.isFileExists(Config.TEST_APK_PATH)) {
    +                        ReleaseInstallApkTask(listener).execute()
                         } else {
    -                        if (!FileUtils.isFileExists(Config.TEST_APK_PATH)) {
    -                            ReleaseInstallApkTask(listener).execute()
    -                        } else {
    -                            listener.onReleased()
    -                        }
    +                        listener.onReleased()
                         }
    -                },
    -                CommonItemClick(R.string.app_uninstall) {
    -                    if (AppUtils.isAppInstalled(Config.TEST_PKG)) {
    -                        AppUtils.uninstallApp(Config.TEST_PKG)
    -                    } else {
    -                        ToastUtils.showShort(R.string.app_uninstall_tips)
    -                    }
    -                },
    -                CommonItemClick(R.string.app_launch) {
    -                    AppUtils.launchApp(this.packageName)
    -                },
    -                CommonItemClick(R.string.app_relaunch) {
    -                    AppUtils.relaunchApp()
    -                },
    -                CommonItemClick(R.string.app_launch_details_settings, true) {
    -                    AppUtils.launchAppDetailsSettings()
    -                },
    -                CommonItemClick(R.string.app_exit) {
    -                    AppUtils.exitApp()
                     }
    +            },
    +            CommonItemClick(R.string.app_uninstall) {
    +                if (AppUtils.isAppInstalled(Config.TEST_PKG)) {
    +                    AppUtils.uninstallApp(Config.TEST_PKG)
    +                } else {
    +                    ToastUtils.showShort(R.string.app_uninstall_tips)
    +                }
    +            },
    +            CommonItemClick(R.string.app_launch) {
    +                AppUtils.launchApp(this.packageName)
    +            },
    +            CommonItemClick(R.string.app_relaunch) {
    +                AppUtils.relaunchApp()
    +            },
    +            CommonItemClick(R.string.app_launch_details_settings, true) {
    +                AppUtils.launchAppDetailsSettings()
    +            },
    +            CommonItemClick(R.string.app_exit) {
    +                AppUtils.exitApp()
    +            }
             )
         }
     
    @@ -130,7 +141,8 @@ class AppActivity : CommonActivity(), Utils.OnAppStatusChangedListener {
         }
     }
     
    -class ReleaseInstallApkTask(private val mListener: OnReleasedListener) : ThreadUtils.SimpleTask() {
    +class ReleaseInstallApkTask(private val mListener: OnReleasedListener) :
    +    ThreadUtils.SimpleTask() {
     
         override fun doInBackground() {
             ResourceUtils.copyFileFromAssets("test_install", Config.TEST_APK_PATH)
    diff --git a/lib/utilcode/README-CN.md b/lib/utilcode/README-CN.md
    index a6ab4b3d09..d8b9591fe7 100644
    --- a/lib/utilcode/README-CN.md
    +++ b/lib/utilcode/README-CN.md
    @@ -72,6 +72,8 @@ getAppName                        : 获取 App 名称
     getAppPath                        : 获取 App 路径
     getAppVersionName                 : 获取 App 版本号
     getAppVersionCode                 : 获取 App 版本码
    +getAppMinSdkVersion               : 获取 App 支持最低系统版本号
    +getAppTargetSdkVersion            : 获取 App 目标系统版本号
     getAppSignatures                  : 获取 App 签名
     getAppSignaturesSHA1              : 获取应用签名的的 SHA1 值
     getAppSignaturesSHA256            : 获取应用签名的的 SHA256 值
    diff --git a/lib/utilcode/README.md b/lib/utilcode/README.md
    index 9d2025ebb0..b88bcbcfbd 100644
    --- a/lib/utilcode/README.md
    +++ b/lib/utilcode/README.md
    @@ -72,6 +72,8 @@ getAppName
     getAppPath
     getAppVersionName
     getAppVersionCode
    +getAppMinSdkVersion
    +getAppTargetSdkVersion
     getAppSignatures
     getAppSignaturesSHA1
     getAppSignaturesSHA256
    diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/AppUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/AppUtils.java
    index 8f03e1cf1f..3a07653fb0 100644
    --- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/AppUtils.java
    +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/AppUtils.java
    @@ -14,13 +14,13 @@
     import android.os.Build;
     import android.util.Log;
     
    +import androidx.annotation.NonNull;
    +import androidx.annotation.Nullable;
    +
     import java.io.File;
     import java.util.ArrayList;
     import java.util.List;
     
    -import androidx.annotation.NonNull;
    -import androidx.annotation.Nullable;
    -
     /**
      * 
      *     author: Blankj
    @@ -541,6 +541,65 @@ public static int getAppVersionCode(final String packageName) {
             }
         }
     
    +    /**
    +     * Return the application's minimum sdk version code.
    +     *
    +     * @return the application's minimum sdk version code
    +     */
    +    public static int getAppMinSdkVersion() {
    +        return getAppMinSdkVersion(Utils.getApp().getPackageName());
    +    }
    +
    +    /**
    +     * Return the application's minimum sdk version code.
    +     *
    +     * @param packageName The name of the package.
    +     * @return the application's minimum sdk version code
    +     */
    +    public static int getAppMinSdkVersion(final String packageName) {
    +        if (UtilsBridge.isSpace(packageName)) return -1;
    +        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.N) return -1;
    +        try {
    +            PackageManager pm = Utils.getApp().getPackageManager();
    +            PackageInfo pi = pm.getPackageInfo(packageName, 0);
    +            if (null == pi) return -1;
    +            ApplicationInfo ai = pi.applicationInfo;
    +            return null == ai ? -1 : ai.minSdkVersion;
    +        } catch (PackageManager.NameNotFoundException e) {
    +            e.printStackTrace();
    +            return -1;
    +        }
    +    }
    +
    +    /**
    +     * Return the application's target sdk version code.
    +     *
    +     * @return the application's target sdk version code
    +     */
    +    public static int getAppTargetSdkVersion() {
    +        return getAppTargetSdkVersion(Utils.getApp().getPackageName());
    +    }
    +
    +    /**
    +     * Return the application's target sdk version code.
    +     *
    +     * @param packageName The name of the package.
    +     * @return the application's target sdk version code
    +     */
    +    public static int getAppTargetSdkVersion(final String packageName) {
    +        if (UtilsBridge.isSpace(packageName)) return -1;
    +        try {
    +            PackageManager pm = Utils.getApp().getPackageManager();
    +            PackageInfo pi = pm.getPackageInfo(packageName, 0);
    +            if (null == pi) return -1;
    +            ApplicationInfo ai = pi.applicationInfo;
    +            return null == ai ? -1 : ai.targetSdkVersion;
    +        } catch (PackageManager.NameNotFoundException e) {
    +            e.printStackTrace();
    +            return -1;
    +        }
    +    }
    +
         /**
          * Return the application's signature.
          *
    @@ -721,6 +780,8 @@ private static List getAppSignaturesHash(final String packageName, final
          * 
  • path of package
  • *
  • version name
  • *
  • version code
  • + *
  • minimum sdk version code
  • + *
  • target sdk version code
  • *
  • is system
  • * * @@ -740,6 +801,8 @@ public static AppInfo getAppInfo() { *
  • path of package
  • *
  • version name
  • *
  • version code
  • + *
  • minimum sdk version code
  • + *
  • target sdk version code
  • *
  • is system
  • * * @@ -829,13 +892,18 @@ private static AppInfo getBean(final PackageManager pm, final PackageInfo pi) { String packageName = pi.packageName; ApplicationInfo ai = pi.applicationInfo; if (ai == null) { - return new AppInfo(packageName, "", null, "", versionName, versionCode, false); + return new AppInfo(packageName, "", null, "", versionName, versionCode, -1, -1, false); } String name = ai.loadLabel(pm).toString(); Drawable icon = ai.loadIcon(pm); String packagePath = ai.sourceDir; + int minSdkVersion = -1; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { + minSdkVersion = ai.minSdkVersion; + } + int targetSdkVersion = ai.targetSdkVersion; boolean isSystem = (ApplicationInfo.FLAG_SYSTEM & ai.flags) != 0; - return new AppInfo(packageName, name, icon, packagePath, versionName, versionCode, isSystem); + return new AppInfo(packageName, name, icon, packagePath, versionName, versionCode, minSdkVersion, targetSdkVersion, isSystem); } /** @@ -843,13 +911,15 @@ private static AppInfo getBean(final PackageManager pm, final PackageInfo pi) { */ public static class AppInfo { - private String packageName; - private String name; + private String packageName; + private String name; private Drawable icon; - private String packagePath; - private String versionName; - private int versionCode; - private boolean isSystem; + private String packagePath; + private String versionName; + private int versionCode; + private int minSdkVersion; + private int targetSdkVersion; + private boolean isSystem; public Drawable getIcon() { return icon; @@ -907,14 +977,31 @@ public void setVersionName(final String versionName) { this.versionName = versionName; } - public AppInfo(String packageName, String name, Drawable icon, String packagePath, - String versionName, int versionCode, boolean isSystem) { + public int getMinSdkVersion() { + return minSdkVersion; + } + + public void setMinSdkVersion(int minSdkVersion) { + this.minSdkVersion = minSdkVersion; + } + + public int getTargetSdkVersion() { + return targetSdkVersion; + } + + public void setTargetSdkVersion(int targetSdkVersion) { + this.targetSdkVersion = targetSdkVersion; + } + + public AppInfo(String packageName, String name, Drawable icon, String packagePath, String versionName, int versionCode, int minSdkVersion, int targetSdkVersion, boolean isSystem) { this.setName(name); this.setIcon(icon); this.setPackageName(packageName); this.setPackagePath(packagePath); this.setVersionName(versionName); this.setVersionCode(versionCode); + this.setMinSdkVersion(minSdkVersion); + this.setTargetSdkVersion(targetSdkVersion); this.setSystem(isSystem); } @@ -928,6 +1015,8 @@ public String toString() { "\n app path: " + getPackagePath() + "\n app v name: " + getVersionName() + "\n app v code: " + getVersionCode() + + "\n app v min: " + getMinSdkVersion() + + "\n app v target: " + getTargetSdkVersion() + "\n is system: " + isSystem() + "\n}"; } diff --git a/lib/utildebug/src/main/java/com/blankj/utildebug/debug/tool/appInfo/AppInfoItem.java b/lib/utildebug/src/main/java/com/blankj/utildebug/debug/tool/appInfo/AppInfoItem.java index 76351e4b10..54895ee71f 100644 --- a/lib/utildebug/src/main/java/com/blankj/utildebug/debug/tool/appInfo/AppInfoItem.java +++ b/lib/utildebug/src/main/java/com/blankj/utildebug/debug/tool/appInfo/AppInfoItem.java @@ -5,10 +5,12 @@ import android.view.View.OnClickListener; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.annotation.StringRes; + import com.blankj.utilcode.util.AppUtils; import com.blankj.utilcode.util.ClickUtils; import com.blankj.utilcode.util.StringUtils; -import com.blankj.utildebug.DebugUtils; import com.blankj.utildebug.R; import com.blankj.utildebug.base.rv.BaseItem; import com.blankj.utildebug.base.rv.ItemViewHolder; @@ -16,9 +18,6 @@ import java.util.ArrayList; import java.util.List; -import androidx.annotation.NonNull; -import androidx.annotation.StringRes; - /** *
      *     author: blankj
    @@ -29,8 +28,8 @@
      */
     public class AppInfoItem extends BaseItem {
     
    -    private String          mTitle;
    -    private String          mContent;
    +    private String mTitle;
    +    private String mContent;
         private OnClickListener mListener;
     
         private TextView titleTv;
    @@ -71,9 +70,9 @@ public static List getAppInfoItems() {
             appInfoItems.add(new AppInfoItem(R.string.du_app_info_version_name, AppUtils.getAppVersionName()));
             appInfoItems.add(new AppInfoItem(R.string.du_app_info_version_code, String.valueOf(AppUtils.getAppVersionCode())));
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    -            appInfoItems.add(new AppInfoItem(R.string.du_app_info_min_sdk_version, String.valueOf(DebugUtils.getApp().getApplicationInfo().minSdkVersion)));
    +            appInfoItems.add(new AppInfoItem(R.string.du_app_info_min_sdk_version, String.valueOf(AppUtils.getAppMinSdkVersion())));
             }
    -        appInfoItems.add(new AppInfoItem(R.string.du_app_info_target_sdk_version, String.valueOf(DebugUtils.getApp().getApplicationInfo().targetSdkVersion)));
    +        appInfoItems.add(new AppInfoItem(R.string.du_app_info_target_sdk_version, String.valueOf(AppUtils.getAppTargetSdkVersion())));
             appInfoItems.add(new AppInfoItem(R.string.du_app_info_open_app_info_page, "", new OnClickListener() {
                 @Override
                 public void onClick(View v) {
    
    From 5f739314d9eadeb5cad7f0e6876d2606480fc1f5 Mon Sep 17 00:00:00 2001
    From: Blankj 
    Date: Sat, 15 Oct 2022 00:45:11 +0800
    Subject: [PATCH 41/44] fix: some bugs
    
    ---
     CHANGELOG.md                                  |  1 +
     buildSrc/src/main/groovy/Config.groovy        |  6 +--
     lib/utilcode/README-CN.md                     | 11 +++--
     lib/utilcode/README.md                        |  3 +-
     .../blankj/utilcode/util/ActivityUtils.java   |  9 ++--
     .../com/blankj/utilcode/util/BarUtils.java    |  4 +-
     .../com/blankj/utilcode/util/DeviceUtils.java | 46 +++++++++++++++++--
     module_config.json                            |  2 +-
     8 files changed, 63 insertions(+), 19 deletions(-)
    
    diff --git a/CHANGELOG.md b/CHANGELOG.md
    index c4bcc19c85..73e8145bf1 100644
    --- a/CHANGELOG.md
    +++ b/CHANGELOG.md
    @@ -1,3 +1,4 @@
    +* `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.
    diff --git a/buildSrc/src/main/groovy/Config.groovy b/buildSrc/src/main/groovy/Config.groovy
    index 268ec666ce..9a8d69d659 100644
    --- a/buildSrc/src/main/groovy/Config.groovy
    +++ b/buildSrc/src/main/groovy/Config.groovy
    @@ -6,8 +6,8 @@ class Config {
         static compileSdkVersion = 29
         static minSdkVersion = 14
         static targetSdkVersion = 29
    -    static versionCode = 1_030_007
    -    static versionName = '1.31.0'// E.g. 1.9.72 => 1,009,072
    +    static versionCode = 1_031_001
    +    static versionName = '1.31.1'// E.g. 1.9.72 => 1,009,072
     
         // lib version
         static gradlePluginVersion = '4.1.0'
    @@ -34,7 +34,7 @@ class Config {
                 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: false, localPath: "./lib/utilcode", remotePath: "com.blankj:utilcodex:$Config.versionName"),
    +            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*/
    diff --git a/lib/utilcode/README-CN.md b/lib/utilcode/README-CN.md
    index d8b9591fe7..6610b3be99 100644
    --- a/lib/utilcode/README-CN.md
    +++ b/lib/utilcode/README-CN.md
    @@ -3,7 +3,7 @@
     Gradle:
     ```groovy
     // if u use AndroidX, use the following
    -implementation 'com.blankj:utilcodex:1.31.0'
    +implementation 'com.blankj:utilcodex:1.31.1'
     
     // Not in maintenance
     implementation 'com.blankj:utilcode:1.30.7'
    @@ -1210,10 +1210,11 @@ removeListener: 移除消息监听器
     
     * ### URI 相关 -> [UriUtils.java][uri.java]
     ```
    -res2Uri  : res 转 uri
    -file2Uri : file 转 uri
    -uri2File : uri 转 file
    -uri2Bytes: uri 转 bytes
    +res2Uri            : res 转 uri
    +file2Uri           : file 转 uri
    +uri2File           : uri 转 file
    +uri2FileNoCacheCopy: uri 转 file 不拷贝缓存
    +uri2Bytes          : uri 转 bytes
     ```
     
     * ### UtilsTransActivity -> [UtilsTransActivity.java][trans.java]
    diff --git a/lib/utilcode/README.md b/lib/utilcode/README.md
    index b88bcbcfbd..570f58fc46 100644
    --- a/lib/utilcode/README.md
    +++ b/lib/utilcode/README.md
    @@ -3,7 +3,7 @@
     Gradle:
     ```groovy
     // if u use AndroidX, use the following
    -implementation 'com.blankj:utilcodex:1.31.0'
    +implementation 'com.blankj:utilcodex:1.31.1'
     
     // Not in maintenance
     implementation 'com.blankj:utilcode:1.30.6'
    @@ -1212,6 +1212,7 @@ removeListener
     res2Uri
     file2Uri
     uri2File
    +uri2FileNoCacheCopy
     uri2Bytes
     ```
     
    diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/ActivityUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/ActivityUtils.java
    index 10858f75f4..056668652c 100644
    --- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/ActivityUtils.java
    +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/ActivityUtils.java
    @@ -2013,10 +2013,11 @@ private static boolean startActivity(final Intent intent,
         }
     
         private static boolean isIntentAvailable(final Intent intent) {
    -        return Utils.getApp()
    -                .getPackageManager()
    -                .queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY)
    -                .size() > 0;
    +//        return Utils.getApp()
    +//                .getPackageManager()
    +//                .queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY)
    +//                .size() > 0;
    +        return true;
         }
     
         private static boolean startActivityForResult(final Activity activity,
    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 ece4f7faba..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
    @@ -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);
         }
    @@ -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);
    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 e6feb5fdaa..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
    @@ -13,16 +13,19 @@
     import android.telephony.TelephonyManager;
     import android.text.TextUtils;
     
    -import androidx.annotation.RequiresApi;
    -import androidx.annotation.RequiresPermission;
    -
    +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;
    @@ -382,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;
    @@ -389,6 +393,42 @@ 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. * diff --git a/module_config.json b/module_config.json index 18f416382a..87233122b9 100644 --- a/module_config.json +++ b/module_config.json @@ -23,7 +23,7 @@ {"name": "lib_base", "isApply": true, "useLocal": true, "localPath": "./lib/base"}, {"name": "lib_common", "isApply": true, "useLocal": true, "localPath": "./lib/common"}, {"name": "lib_subutil", "isApply": true, "useLocal": true, "localPath": "./lib/subutil"}, - {"name": "lib_utilcode", "isApply": true, "useLocal": false, "localPath": "./lib/utilcode", "remotePath": "com.blankj:utilcodex:$Config.versionName"}, + {"name": "lib_utilcode", "isApply": true, "useLocal": true, "localPath": "./lib/utilcode", "remotePath": "com.blankj:utilcodex:$Config.versionName"}, {"name": "lib_utildebug", "isApply": true, "useLocal": true, "localPath": "./lib/utildebug"}, {"name": "lib_utildebug_no_op", "isApply": true, "useLocal": true, "localPath": "./lib/utildebug-no-op"} ] From 99be3102e1b5dce8bf051721008811eed3dae0a0 Mon Sep 17 00:00:00 2001 From: taochen <935612713@qq.com> Date: Fri, 21 Oct 2022 15:42:20 +0800 Subject: [PATCH 42/44] =?UTF-8?q?[F]=20=E9=83=A8=E5=88=86=E5=BA=94?= =?UTF-8?q?=E7=94=A8=E5=B8=82=E5=9C=BA=E4=BB=A5=E6=89=80=E8=B0=93ActivityU?= =?UTF-8?q?tils=E9=9A=90=E7=A7=81=E5=90=88=E8=A7=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E6=8B=92=E7=BB=9D=E5=BA=94=E7=94=A8=E4=B8=8A=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../blankj/utilcode/util/ActivityUtils.java | 57 +++++++++---------- 1 file changed, 26 insertions(+), 31 deletions(-) diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/ActivityUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/ActivityUtils.java index 056668652c..d49ce6ff06 100644 --- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/ActivityUtils.java +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/ActivityUtils.java @@ -1997,29 +1997,22 @@ private static void startActivity(final Context context, private static boolean startActivity(final Intent intent, final Context context, final Bundle options) { - if (!isIntentAvailable(intent)) { - Log.e("ActivityUtils", "intent is unavailable"); - return false; - } if (!(context instanceof Activity)) { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); } - if (options != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - context.startActivity(intent, options); - } else { - context.startActivity(intent); + try { + if (options != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + context.startActivity(intent, options); + } else { + context.startActivity(intent); + } + } catch (Exception e) { + Log.e("ActivityUtils", "An exception occurred in startActivity, error message: " + e.getLocalizedMessage()); + return false; } return true; } - private static boolean isIntentAvailable(final Intent intent) { -// return Utils.getApp() -// .getPackageManager() -// .queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY) -// .size() > 0; - return true; - } - private static boolean startActivityForResult(final Activity activity, final Bundle extras, final String pkg, @@ -2036,15 +2029,16 @@ private static boolean startActivityForResult(final Intent intent, final Activity activity, final int requestCode, @Nullable final Bundle options) { - if (!isIntentAvailable(intent)) { - Log.e("ActivityUtils", "intent is unavailable"); + try { + if (options != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + activity.startActivityForResult(intent, requestCode, options); + } else { + activity.startActivityForResult(intent, requestCode); + } + } catch (Exception e) { + Log.e("ActivityUtils", "An exception occurred in startActivityForResult, error message: " + e.getLocalizedMessage()); return false; } - if (options != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - activity.startActivityForResult(intent, requestCode, options); - } else { - activity.startActivityForResult(intent, requestCode); - } return true; } @@ -2079,18 +2073,19 @@ private static boolean startActivityForResult(final Intent intent, final Fragment fragment, final int requestCode, @Nullable final Bundle options) { - if (!isIntentAvailable(intent)) { - Log.e("ActivityUtils", "intent is unavailable"); - return false; - } if (fragment.getActivity() == null) { Log.e("ActivityUtils", "Fragment " + fragment + " not attached to Activity"); return false; } - if (options != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - fragment.startActivityForResult(intent, requestCode, options); - } else { - fragment.startActivityForResult(intent, requestCode); + try { + if (options != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + fragment.startActivityForResult(intent, requestCode, options); + } else { + fragment.startActivityForResult(intent, requestCode); + } + } catch (Exception e) { + Log.e("ActivityUtils", "An exception occurred in fragment.startActivityForResult, error message: " + e.getLocalizedMessage()); + return false; } return true; } From 19349b9998224f04385c37f643fc96e69faf33bd Mon Sep 17 00:00:00 2001 From: simple <383559698@qq.com> Date: Wed, 24 Apr 2024 19:22:35 +0800 Subject: [PATCH 43/44] update VibrateUtils --- buildSrc/src/main/groovy/Config.groovy | 2 +- .../pkg/feature/vibrate/VibrateActivity.kt | 22 +++++- .../pkg/src/main/res/values/strings.xml | 1 + .../blankj/utilcode/util/VibrateUtils.java | 79 +++++++++++++++++++ 4 files changed, 101 insertions(+), 3 deletions(-) diff --git a/buildSrc/src/main/groovy/Config.groovy b/buildSrc/src/main/groovy/Config.groovy index a69b8907c7..9a8d69d659 100644 --- a/buildSrc/src/main/groovy/Config.groovy +++ b/buildSrc/src/main/groovy/Config.groovy @@ -34,7 +34,7 @@ class Config { 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: false, localPath: "./lib/utilcode", remotePath: "com.blankj:utilcodex:$Config.versionName"), + 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*/ 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..ee88dab0fa 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,22 @@ 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.vibrateCompat(longArrayOf(0, 1000, 1000, 2000, 2000, 1000), 1) +// VibrateUtils.vibrateCompat(1000) + }, 1000) + }, + CommonItemClick(R.string.vibrate_cancel) { + VibrateUtils.cancel() + } ) } @@ -44,4 +55,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/res/values/strings.xml b/feature/utilcode/pkg/src/main/res/values/strings.xml index ccec698647..551f9adbaf 100644 --- a/feature/utilcode/pkg/src/main/res/values/strings.xml +++ b/feature/utilcode/pkg/src/main/res/values/strings.xml @@ -366,5 +366,6 @@ Vibrate 1000ms Vibrate Custom + Vibrate Background Cancel diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/VibrateUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/VibrateUtils.java index 622d657817..8d2ab055e4 100644 --- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/VibrateUtils.java +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/VibrateUtils.java @@ -1,7 +1,11 @@ package com.blankj.utilcode.util; import android.content.Context; +import android.media.AudioAttributes; +import android.os.Build; import android.os.Vibrator; + +import androidx.annotation.RequiresApi; import androidx.annotation.RequiresPermission; import static android.Manifest.permission.VIBRATE; @@ -35,6 +39,39 @@ public static void vibrate(final long milliseconds) { vibrator.vibrate(milliseconds); } + /** + * Vibrate. + *

    Must hold {@code }

    + * + * @param milliseconds The number of milliseconds to vibrate. + * @param attributes {@link AudioAttributes} corresponding to the vibration. For example, + * specify {@link AudioAttributes#USAGE_ALARM} for alarm vibrations or + * {@link AudioAttributes#USAGE_NOTIFICATION_RINGTONE} for + * vibrations associated with incoming calls. + */ + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + @RequiresPermission(VIBRATE) + public static void vibrate(final long milliseconds, AudioAttributes attributes) { + Vibrator vibrator = getVibrator(); + if (vibrator == null) return; + vibrator.vibrate(milliseconds, attributes); + } + + /** + * VibrateCompat + *

    Must hold {@code }

    + * + * @param milliseconds he number of milliseconds to vibrate. + */ + @RequiresPermission(VIBRATE) + public static void vibrateCompat(final long milliseconds) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + vibrate(milliseconds, getAudioAttributes()); + } else { + vibrate(milliseconds); + } + } + /** * Vibrate. *

    Must hold {@code }

    @@ -49,6 +86,41 @@ public static void vibrate(final long[] pattern, final int repeat) { vibrator.vibrate(pattern, repeat); } + /** + * Vibrate. + *

    Must hold {@code }

    + * + * @param pattern An array of longs of times for which to turn the vibrator on or off. + * @param repeat The index into pattern at which to repeat, or -1 if you don't want to repeat. + * @param attributes {@link AudioAttributes} corresponding to the vibration. For example, + * specify {@link AudioAttributes#USAGE_ALARM} for alarm vibrations or + * {@link AudioAttributes#USAGE_NOTIFICATION_RINGTONE} for + * vibrations associated with incoming calls. + */ + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + @RequiresPermission(VIBRATE) + public static void vibrate(final long[] pattern, final int repeat, AudioAttributes attributes) { + Vibrator vibrator = getVibrator(); + if (vibrator == null) return; + vibrator.vibrate(pattern, repeat, attributes); + } + + /** + * VibrateCompat + *

    Must hold {@code }

    + * + * @param pattern An array of longs of times for which to turn the vibrator on or off. + * @param repeat The index into pattern at which to repeat, or -1 if you don't want to repeat. + */ + @RequiresPermission(VIBRATE) + public static void vibrateCompat(final long[] pattern, final int repeat) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + vibrate(pattern, repeat, getAudioAttributes()); + } else { + vibrate(pattern, repeat); + } + } + /** * Cancel vibrate. *

    Must hold {@code }

    @@ -66,4 +138,11 @@ private static Vibrator getVibrator() { } return vibrator; } + + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + private static AudioAttributes getAudioAttributes() { + return new AudioAttributes.Builder() + .setUsage(AudioAttributes.USAGE_ALARM) + .build(); + } } From c7ebceb6675670080389472445d0bcb3c71f8bc9 Mon Sep 17 00:00:00 2001 From: simple <383559698@qq.com> Date: Thu, 25 Apr 2024 10:36:38 +0800 Subject: [PATCH 44/44] add VibrateUtils comment --- .../blankj/utilcode/pkg/feature/vibrate/VibrateActivity.kt | 1 + .../src/main/java/com/blankj/utilcode/util/VibrateUtils.java | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) 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 ee88dab0fa..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 @@ -41,6 +41,7 @@ class VibrateActivity : CommonActivity() { 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) diff --git a/lib/utilcode/src/main/java/com/blankj/utilcode/util/VibrateUtils.java b/lib/utilcode/src/main/java/com/blankj/utilcode/util/VibrateUtils.java index 8d2ab055e4..164810381a 100644 --- a/lib/utilcode/src/main/java/com/blankj/utilcode/util/VibrateUtils.java +++ b/lib/utilcode/src/main/java/com/blankj/utilcode/util/VibrateUtils.java @@ -58,7 +58,7 @@ public static void vibrate(final long milliseconds, AudioAttributes attributes) } /** - * VibrateCompat + * VibrateCompat - Can vibrate in background *

    Must hold {@code }

    * * @param milliseconds he number of milliseconds to vibrate. @@ -106,7 +106,7 @@ public static void vibrate(final long[] pattern, final int repeat, AudioAttribut } /** - * VibrateCompat + * VibrateCompat - Can vibrate in background *

    Must hold {@code }

    * * @param pattern An array of longs of times for which to turn the vibrator on or off.