From 270e035b3a5f1a26a215ab0311c565f103b097f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BD=AE=E5=AD=90=E5=93=A5?= Date: Sat, 8 Jan 2022 22:28:33 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A0=E5=85=A5=20Kotlin=20=E5=8D=8F?= =?UTF-8?q?=E7=A8=8B=20=E4=BC=98=E5=8C=96=E9=83=A8=E5=88=86=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E7=9A=84=E5=86=99=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 8 +++++ .../com/hjq/demo/manager/ActivityManager.kt | 12 ++----- .../com/hjq/demo/manager/ThreadPoolManager.kt | 34 ------------------- .../com/hjq/demo/ui/activity/CrashActivity.kt | 11 ++++-- .../demo/ui/activity/ImageSelectActivity.kt | 8 +++-- .../hjq/demo/ui/activity/SettingActivity.kt | 11 +++--- .../demo/ui/activity/VideoSelectActivity.kt | 8 +++-- .../com/hjq/demo/ui/fragment/HomeFragment.kt | 5 +-- common.gradle | 6 ++++ .../java/com/hjq/base/action/HandlerAction.kt | 6 +--- .../java/com/hjq/widget/view/ClearEditText.kt | 9 ++--- .../com/hjq/widget/view/PasswordEditText.kt | 16 ++++----- 12 files changed, 56 insertions(+), 78 deletions(-) delete mode 100644 app/src/main/java/com/hjq/demo/manager/ThreadPoolManager.kt diff --git a/README.md b/README.md index 8f5c438..996eb41 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,14 @@ * 博客地址:[但愿人长久,搬砖不再有](https://www.jianshu.com/p/77dd326f21dc) +* 另外你如果对 Kotlin 不熟悉,恰好想学习的话,推荐你通过下面这三篇文章来学习 + + * [全民 Kotlin:Java我们不一样](https://www.jianshu.com/p/a01e6b957269) + + * [全民 Kotlin:你没有玩过的全新玩法](https://www.jianshu.com/p/884ca0a49e5e) + + * [全民 Kotlin:协程特别篇](https://www.jianshu.com/p/2e0746c7d4f3) + * 当我们日复一日年复一年的搬砖的时候,你是否曾想过提升一下开发效率,如果一个通用的架构摆在你的面前,你还会选择自己搭架构么,但是搭建出一个好的架构并非易事,有多少人愿意选择去做,还有多少人选择努力去做好,可能寥寥无几,但是你今天看到的,正是你所想要的,一个真正能解决你开发新项目时最大痛点的架构工程,你不需要再麻木 Copy 原有旧项目的代码,只需改动少量代码就能得到想要的效果,你会发现开发新项目其实是一件很快乐的事。 * AndroidProject 已维护三年多的时间,几乎耗尽我所有的业余时间,里面的代码改了再改,改了又改,不断 Review、不断创新、不断改进、不断测试、不断优化,每天都在重复这些枯燥的步骤,但是只有这样才能把这件事做好,因为我相信把同样一件事重复做,迟早有一天可以做好。 diff --git a/app/src/main/java/com/hjq/demo/manager/ActivityManager.kt b/app/src/main/java/com/hjq/demo/manager/ActivityManager.kt index 2bd9f3f..087545f 100644 --- a/app/src/main/java/com/hjq/demo/manager/ActivityManager.kt +++ b/app/src/main/java/com/hjq/demo/manager/ActivityManager.kt @@ -19,18 +19,10 @@ class ActivityManager private constructor() : ActivityLifecycleCallbacks { companion object { @Suppress("StaticFieldLeak") - @Volatile - private var sInstance: ActivityManager? = null + private val activityManager: ActivityManager by lazy { ActivityManager() } fun getInstance(): ActivityManager { - if (sInstance == null) { - synchronized(ActivityManager::class.java) { - if (sInstance == null) { - sInstance = ActivityManager() - } - } - } - return sInstance!! + return activityManager } /** diff --git a/app/src/main/java/com/hjq/demo/manager/ThreadPoolManager.kt b/app/src/main/java/com/hjq/demo/manager/ThreadPoolManager.kt deleted file mode 100644 index 3b19a6d..0000000 --- a/app/src/main/java/com/hjq/demo/manager/ThreadPoolManager.kt +++ /dev/null @@ -1,34 +0,0 @@ -package com.hjq.demo.manager - -import java.util.concurrent.SynchronousQueue -import java.util.concurrent.ThreadPoolExecutor -import java.util.concurrent.TimeUnit - -/** - * author : Android 轮子哥 - * github : https://github.com/getActivity/AndroidProject-Kotlin - * time : 2020/01/11 - * desc : 线程池管理类 - */ -class ThreadPoolManager : ThreadPoolExecutor( - 0, 200, - 30L, TimeUnit.MILLISECONDS, - SynchronousQueue()) { - - companion object { - - @Volatile - private var instance: ThreadPoolManager? = null - - fun getInstance(): ThreadPoolManager { - if (instance == null) { - synchronized(ThreadPoolManager::class.java) { - if (instance == null) { - instance = ThreadPoolManager() - } - } - } - return instance!! - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/hjq/demo/ui/activity/CrashActivity.kt b/app/src/main/java/com/hjq/demo/ui/activity/CrashActivity.kt index 8568db9..9ab4536 100644 --- a/app/src/main/java/com/hjq/demo/ui/activity/CrashActivity.kt +++ b/app/src/main/java/com/hjq/demo/ui/activity/CrashActivity.kt @@ -18,15 +18,17 @@ import android.view.View import android.widget.TextView import androidx.core.view.GravityCompat import androidx.drawerlayout.widget.DrawerLayout +import androidx.lifecycle.lifecycleScope import com.gyf.immersionbar.ImmersionBar import com.hjq.demo.R import com.hjq.demo.aop.SingleClick import com.hjq.demo.app.AppActivity -import com.hjq.demo.manager.ThreadPoolManager import com.hjq.demo.other.AppConfig import com.hjq.permissions.Permission import com.hjq.permissions.XXPermissions import com.tencent.bugly.crashreport.CrashReport +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import java.io.PrintWriter import java.io.StringWriter import java.net.InetAddress @@ -227,14 +229,17 @@ class CrashActivity : AppActivity() { } if (permissions.contains(Manifest.permission.INTERNET)) { builder.append("\n当前网络访问:\t") - ThreadPoolManager.getInstance().execute { + + lifecycleScope.launch(Dispatchers.IO) { try { InetAddress.getByName("www.baidu.com") builder.append("正常") } catch (ignored: UnknownHostException) { builder.append("异常") } - post { infoView?.text = builder } + lifecycleScope.launch(Dispatchers.Main) { + infoView?.text = builder + } } } else { infoView?.text = builder diff --git a/app/src/main/java/com/hjq/demo/ui/activity/ImageSelectActivity.kt b/app/src/main/java/com/hjq/demo/ui/activity/ImageSelectActivity.kt index b1ed18a..2edda6f 100644 --- a/app/src/main/java/com/hjq/demo/ui/activity/ImageSelectActivity.kt +++ b/app/src/main/java/com/hjq/demo/ui/activity/ImageSelectActivity.kt @@ -8,6 +8,7 @@ import android.provider.MediaStore import android.text.TextUtils import android.view.* import android.view.animation.* +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.RecyclerView import com.hjq.base.BaseActivity import com.hjq.base.BaseAdapter @@ -18,7 +19,6 @@ import com.hjq.demo.aop.Log import com.hjq.demo.aop.Permissions import com.hjq.demo.aop.SingleClick import com.hjq.demo.app.AppActivity -import com.hjq.demo.manager.ThreadPoolManager import com.hjq.demo.other.GridSpaceDecoration import com.hjq.demo.ui.activity.CameraActivity.OnCameraListener import com.hjq.demo.ui.adapter.ImageSelectAdapter @@ -28,6 +28,8 @@ import com.hjq.demo.widget.StatusLayout import com.hjq.permissions.Permission import com.hjq.permissions.XXPermissions import com.hjq.widget.view.FloatActionButton +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import java.io.File import java.util.* @@ -150,7 +152,7 @@ class ImageSelectActivity : AppActivity(), StatusAction, Runnable, // 显示加载进度条 showLoading() // 加载图片列表 - ThreadPoolManager.getInstance().execute(this) + lifecycleScope.launch(Dispatchers.IO) { run() } } override fun getStatusLayout(): StatusLayout? { @@ -238,7 +240,7 @@ class ImageSelectActivity : AppActivity(), StatusAction, Runnable, // 这里需要延迟刷新,否则可能会找不到拍照的图片 postDelayed({ // 重新加载图片列表 - ThreadPoolManager.getInstance().execute(this@ImageSelectActivity) + lifecycleScope.launch { run() } }, 1000) } diff --git a/app/src/main/java/com/hjq/demo/ui/activity/SettingActivity.kt b/app/src/main/java/com/hjq/demo/ui/activity/SettingActivity.kt index f20e3b4..54fe2bc 100644 --- a/app/src/main/java/com/hjq/demo/ui/activity/SettingActivity.kt +++ b/app/src/main/java/com/hjq/demo/ui/activity/SettingActivity.kt @@ -2,6 +2,7 @@ package com.hjq.demo.ui.activity import android.view.Gravity import android.view.View +import androidx.lifecycle.lifecycleScope import com.hjq.base.BaseDialog import com.hjq.base.action.AnimAction import com.hjq.demo.R @@ -12,7 +13,6 @@ import com.hjq.demo.http.glide.GlideApp import com.hjq.demo.http.model.HttpData import com.hjq.demo.manager.ActivityManager import com.hjq.demo.manager.CacheDataManager -import com.hjq.demo.manager.ThreadPoolManager import com.hjq.demo.other.AppConfig import com.hjq.demo.ui.dialog.MenuDialog import com.hjq.demo.ui.dialog.SafeDialog @@ -21,6 +21,9 @@ import com.hjq.http.EasyHttp import com.hjq.http.listener.HttpCallback import com.hjq.widget.layout.SettingBar import com.hjq.widget.view.SwitchButton +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext /** * author : Android 轮子哥 @@ -132,11 +135,11 @@ class SettingActivity : AppActivity(), SwitchButton.OnCheckedChangeListener { // 清除内存缓存(必须在主线程) GlideApp.get(this@SettingActivity).clearMemory() - ThreadPoolManager.getInstance().execute { - CacheDataManager.clearAllCache(this) + lifecycleScope.launch(Dispatchers.IO) { + CacheDataManager.clearAllCache(this@SettingActivity) // 清除本地缓存(必须在子线程) GlideApp.get(this@SettingActivity).clearDiskCache() - post { + withContext(Dispatchers.Main) { // 重新获取应用缓存大小 cleanCacheView?.setRightText(CacheDataManager.getTotalCacheSize(this@SettingActivity)) } diff --git a/app/src/main/java/com/hjq/demo/ui/activity/VideoSelectActivity.kt b/app/src/main/java/com/hjq/demo/ui/activity/VideoSelectActivity.kt index 6d34043..06a551c 100644 --- a/app/src/main/java/com/hjq/demo/ui/activity/VideoSelectActivity.kt +++ b/app/src/main/java/com/hjq/demo/ui/activity/VideoSelectActivity.kt @@ -11,6 +11,7 @@ import android.os.Parcelable import android.provider.MediaStore import android.view.* import android.view.animation.* +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.RecyclerView import com.hjq.base.BaseActivity import com.hjq.base.BaseAdapter @@ -21,7 +22,6 @@ import com.hjq.demo.aop.Log import com.hjq.demo.aop.Permissions import com.hjq.demo.aop.SingleClick import com.hjq.demo.app.AppActivity -import com.hjq.demo.manager.ThreadPoolManager import com.hjq.demo.other.GridSpaceDecoration import com.hjq.demo.ui.activity.CameraActivity.OnCameraListener import com.hjq.demo.ui.adapter.VideoSelectAdapter @@ -32,6 +32,8 @@ import com.hjq.permissions.Permission import com.hjq.permissions.XXPermissions import com.hjq.widget.view.FloatActionButton import com.tencent.bugly.crashreport.CrashReport +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import java.io.File import java.util.* @@ -150,7 +152,7 @@ class VideoSelectActivity : AppActivity(), StatusAction, Runnable, BaseAdapter.O // 显示加载进度条 showLoading() // 加载视频列表 - ThreadPoolManager.getInstance().execute(this) + lifecycleScope.launch(Dispatchers.IO) { run() } } override fun getStatusLayout(): StatusLayout? { @@ -241,7 +243,7 @@ class VideoSelectActivity : AppActivity(), StatusAction, Runnable, BaseAdapter.O // 这里需要延迟刷新,否则可能会找不到拍照的视频 postDelayed({ // 重新加载视频列表 - ThreadPoolManager.getInstance().execute(this@VideoSelectActivity) + lifecycleScope.launch { run() } }, 1000) } diff --git a/app/src/main/java/com/hjq/demo/ui/fragment/HomeFragment.kt b/app/src/main/java/com/hjq/demo/ui/fragment/HomeFragment.kt index 85a3c34..9eaab86 100644 --- a/app/src/main/java/com/hjq/demo/ui/fragment/HomeFragment.kt +++ b/app/src/main/java/com/hjq/demo/ui/fragment/HomeFragment.kt @@ -2,7 +2,8 @@ package com.hjq.demo.ui.fragment import android.content.res.ColorStateList import android.widget.TextView -import androidx.appcompat.widget.* +import androidx.appcompat.widget.AppCompatImageView +import androidx.appcompat.widget.Toolbar import androidx.core.content.ContextCompat import androidx.recyclerview.widget.RecyclerView import androidx.viewpager.widget.ViewPager @@ -13,7 +14,7 @@ import com.hjq.demo.R import com.hjq.demo.app.AppFragment import com.hjq.demo.app.TitleBarFragment import com.hjq.demo.ui.activity.HomeActivity -import com.hjq.demo.ui.adapter.* +import com.hjq.demo.ui.adapter.TabAdapter import com.hjq.demo.ui.adapter.TabAdapter.OnTabListener import com.hjq.demo.widget.XCollapsingToolbarLayout import com.hjq.demo.widget.XCollapsingToolbarLayout.OnScrimsListener diff --git a/common.gradle b/common.gradle index 45377d5..eee9044 100644 --- a/common.gradle +++ b/common.gradle @@ -68,4 +68,10 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.3.1' // Material 库:https://github.com/material-components/material-components-android implementation 'com.google.android.material:material:1.4.0' + + // Kotlin 协程:https://github.com/Kotlin/kotlinx.coroutines + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0' + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0' + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1' } \ No newline at end of file diff --git a/library/base/src/main/java/com/hjq/base/action/HandlerAction.kt b/library/base/src/main/java/com/hjq/base/action/HandlerAction.kt index e90160c..d027f2f 100644 --- a/library/base/src/main/java/com/hjq/base/action/HandlerAction.kt +++ b/library/base/src/main/java/com/hjq/base/action/HandlerAction.kt @@ -34,11 +34,7 @@ interface HandlerAction { * 延迟一段时间执行 */ fun postDelayed(runnable: Runnable, delayMillis: Long): Boolean { - var delayMillis: Long = delayMillis - if (delayMillis < 0) { - delayMillis = 0 - } - return postAtTime(runnable, SystemClock.uptimeMillis() + delayMillis) + return postAtTime(runnable, SystemClock.uptimeMillis() + if (delayMillis < 0) 0 else delayMillis) } /** diff --git a/library/widget/src/main/java/com/hjq/widget/view/ClearEditText.kt b/library/widget/src/main/java/com/hjq/widget/view/ClearEditText.kt index 8846734..5f311ff 100644 --- a/library/widget/src/main/java/com/hjq/widget/view/ClearEditText.kt +++ b/library/widget/src/main/java/com/hjq/widget/view/ClearEditText.kt @@ -3,6 +3,7 @@ package com.hjq.widget.view import android.content.Context import android.graphics.drawable.Drawable import android.text.Editable +import android.text.TextUtils import android.text.TextWatcher import android.util.AttributeSet import android.view.MotionEvent @@ -60,11 +61,7 @@ class ClearEditText @JvmOverloads constructor( * [OnFocusChangeListener] */ override fun onFocusChange(view: View, hasFocus: Boolean) { - if (hasFocus && text != null) { - setDrawableVisible(text!!.isNotEmpty()) - } else { - setDrawableVisible(false) - } + setDrawableVisible(hasFocus && !TextUtils.isEmpty(text)) focusChangeListener?.onFocusChange(view, hasFocus) } @@ -91,7 +88,7 @@ class ClearEditText @JvmOverloads constructor( } return true } - return touchListener != null && touchListener!!.onTouch(view, event) + return touchListener?.onTouch(view, event) ?: false } /** diff --git a/library/widget/src/main/java/com/hjq/widget/view/PasswordEditText.kt b/library/widget/src/main/java/com/hjq/widget/view/PasswordEditText.kt index 6707773..d922bbb 100644 --- a/library/widget/src/main/java/com/hjq/widget/view/PasswordEditText.kt +++ b/library/widget/src/main/java/com/hjq/widget/view/PasswordEditText.kt @@ -1,12 +1,16 @@ package com.hjq.widget.view -import android.content.* +import android.content.Context import android.graphics.drawable.Drawable -import android.text.* +import android.text.Editable +import android.text.InputType +import android.text.TextUtils +import android.text.TextWatcher import android.text.method.HideReturnsTransformationMethod import android.text.method.PasswordTransformationMethod import android.util.AttributeSet -import android.view.* +import android.view.MotionEvent +import android.view.View import android.view.View.OnFocusChangeListener import android.view.View.OnTouchListener import androidx.core.content.ContextCompat @@ -76,11 +80,7 @@ class PasswordEditText @JvmOverloads constructor( * [OnFocusChangeListener] */ override fun onFocusChange(view: View?, hasFocus: Boolean) { - if (hasFocus && text != null) { - setDrawableVisible(text!!.isNotEmpty()) - } else { - setDrawableVisible(false) - } + setDrawableVisible(hasFocus && !TextUtils.isEmpty(text)) focusChangeListener?.onFocusChange(view, hasFocus) }