AndroidUtilCodeKTX !是时候提升你的开发效率了 !(持续更新中...)

简介: AndroidUtilCodeKTX !是时候提升你的开发效率了 !(持续更新中...)

前言


第一次接触 Kotlin 还是 2017 年,当时 Kotlin 还没扶正,也不是 Android 的官方开发语言。至于我是怎么被安利的,没记错的话,应该是 开源实验室 的 Kotlin 教程。当时身边几乎没有人在学 Kotlin,网上相关的资料也很少,我还翻译了一部分官网文档,写了一本 GitBook 。 当然现在有更好的 Kotlin 语言中文站 了,对于英文基础不是很好的同学,这是一个不错的入门资料。


两年半时间过来了,Kotlin 摇身一变,稳坐 Android 官方开发语言。尽管可能是为了避免与 Oracle 的诉讼,但我相信这绝对不是主要原因。被定义为 Better Java 的 Kotlin,的确做到了更好,也逐渐为更多人所使用。


《全新 LeakCanary 2 ! 完全基于 Kotlin 重构升级 !》

Retrofit 2.6.0 ! 更快捷的协程体验 !


越来越多的知名三方库都已经开始提供对 Kotlin 的支持。Android 官方的新特性也将优先支持 Kotlin。除了 Android 领域,Spring 5 正式发布时,也将 Kotlin 作为其主打的新特性之一。肉眼可见的,在 JVM 语言领域,Kotlin 必将有一番作为。


我在之前的一篇文章 真香!Kotlin+MVVM+LiveData+协程 打造 Wanandroid! 中开源了 Kotlin MVVM 版本的 Wanandroid 应用,到现在一共有 138 个 star 和 20 个 fork。数据并不是多亮眼,但算是我开源生涯中的一大步。这个项目我也一直在更新,欢迎大家持续关注。


目前的工作中,除非一些不可抗拒因素,我已经将 Kotlin 作为第一选择。在进行多个项目的开发工作之后,我发现我经常在各个项目之间拷贝代码,base 类,扩展函数,工具类等等。甚至有的时候会翻回以前的 Java 代码,或者 Blankj 的 AndroidUtilCode,拿过来直接使用。但是很多时候直接生搬硬套 Java 工具类,并不是那么的优雅,也没有很好的运用 Kotlin 语言特性。我迫切需要一个通用的 Kotlin 工具类库。


基于此,AndroidUtilCodeKTX 诞生了。如果你用过 Blankj 的 AndroidUtilCode,它们的性质是一样的,但绝不是其简单的 Kotlin 翻译版本,而是更多的糅合了 Kotlin 特性,一切从 “简” ,代码越少越好。Talk is easy,show me the code ! 话不多说,下面就代码展示 AndroidUtilCodeKTX 中一些工具类的使用。


AndroidUtilCodeKTX


权限请求

request(Manifest.permission.READ_CALENDAR, Manifest.permission.RECORD_AUDIO) {
    onGranted { toast("onGranted") }
    onDenied { toast("onDenied") }
    onShowRationale { showRationale(it) }
    onNeverAskAgain { goToAppInfoPage() }
}
复制代码


借助扩展函数和 DSL ,可以轻松的在 Activity 中优雅的请求权限以及处理回调。这不是一个全新的轮子,主要代码来自 PermissionsKt 。但是它有一个致命的缺点,需要开发者手动覆写 onRequestPermissionsResult() 来处理权限请求结果,这显得并不是那么简洁和优雅。我这里借鉴了 RxPermissions 的处理方式,通过在当前 Activity 依附一个 Fragment 进行权限请求以及回调处理,这样对用户来说是无感的,且避免了额外的代码。后续会单独写一篇文章,分析其中 Kotlin DSL 的应用。


SharedPreferences

putSpValue("int", 1)
putSpValue("float", 1f)
putSpValue("boolean", true)
putSpValue("string", "ktx")
putSpValue("serialize", Person("Man", 3))
getSpValue("int", 0)
getSpValue("float", 0f)
getSpValue(key = "boolean", default = false)
getSpValue("string", "null")
getSpValue("serialize", Person("default", 0))
复制代码


基本的存储和读取操作都只需要一个函数即可完成,依赖泛型无需主动声明值的类型。默认存储文件名称为包名,如果你想自定义文件名称,声明 name 参数即可:

putSpValue("another","from another sp file",name = "another")
getSpValue("another","null",name = "another")
复制代码


Activity 相关

主要是优化了 startActivity 的使用,争取做到任何情况下都可以一句代码启动 Activity。


普通跳转:

startKtxActivity<AnotherActivity>()
复制代码


带 flag 跳转:

startKtxActivity<AnotherActivity>(Intent.FLAG_ACTIVITY_NEW_TASK)
复制代码


startActivityForResult :

startKtxActivityForResult<AnotherActivity>(requestCode = 1024)
复制代码


带值跳转:

startKtxActivity<AnotherActivity>(value = "string" to "single value")
复制代码


带多个值跳转:

startKtxActivity<AnotherActivity>(
                values = arrayListOf(
                    "int" to 1,
                    "boolean" to true,
                    "string" to "multi value"
                )
            )
复制代码


带 Bundle 跳转:

startKtxActivity<AnotherActivity>(
                extra = Bundle().apply {
                    putInt("int", 2)
                    putBoolean("boolean", true)
                    putString("string", "from bundle")
                }
            )
复制代码


基本涵盖了所有的 Activity 跳转情况。


Aes 加密相关

ByteArray.aesEncrypt(key: ByteArray, iv: ByteArray, cipherAlgotirhm: String = AES_CFB_NOPADDING): ByteArray
ByteArray.aesDecrypt(key: ByteArray, iv: ByteArray, cipherAlgotirhm: String = AES_CFB_NOPADDING): ByteArray 
File.aesEncrypt(key: ByteArray, iv: ByteArray, destFilePath: String): File?
File.aesDecrypt(key: ByteArray, iv: ByteArray, destFilePath: String): File?
复制代码


封装了 Aes 加密操作,提供了快捷的数据和文件加解密方法,无需关注内部细节。默认使用 AES/CFB/NoPadding 模式,你可以通过 cipherAlgotirhm 参数修改模式。

plainText.toByteArray().aesEncrypt(key, iv, "AES/CBC/PKCS5Padding"
plainText.toByteArray().aesEncrypt(key, iv, "AES/ECB/PKCS5Padding"
plainText.toByteArray().aesEncrypt(key, iv, "AES/CTR/PKCS5Padding"
复制代码


Hash 相关

StringByteArray 提供了扩展方法,可以快捷的进行哈希。

ByteArray.hash(algorithm: Hash): String
String.hash(algorithm: Hash, charset: Charset = Charset.forName("utf-8")): String
ByteArray.md5Bytes(): ByteArray
ByteArray.md5(): String
String.md5(charset: Charset = Charset.forName("utf-8")): String
ByteArray.sha1Bytes(): ByteArray
ByteArray.sha1(): String
String.sha1(charset: Charset = Charset.forName("utf-8")): String
ByteArray.sha224Bytes(): ByteArray
ByteArray.sha224(): String
String.sha224(charset: Charset = Charset.forName("utf-8")): String
ByteArray.sha256Bytes(): ByteArray
ByteArray.sha256(): String
String.sha256(charset: Charset = Charset.forName("utf-8")): String
ByteArray.sha384Bytes(): ByteArray
ByteArray.sha384(): String
String.sha384(charset: Charset = Charset.forName("utf-8")): String
ByteArray.sha512Bytes(): ByteArray
ByteArray.sha512(): String
String.sha512(charset: Charset = Charset.forName("utf-8")): String
File.hash(algorithm: Hash = Hash.SHA1): String
复制代码


支持 MD5, sha1, sha224, sha256, sha384, sha512MD5 已经不再安全,密码学上来说已经不再推荐使用。

val origin = "hello"
val md5 = origin.hash(Hash.MD5)
val sha1 = origin.hash(Hash.SHA1)
复制代码


除了字符串取哈希,还提供了对文件取哈希值操作。

val file = File("xxx")
val md5 = file.hash(Hash.MD5)
val sha1 = file.hash(Hash.SHA1)
复制代码


Intent 相关

跳转到应用信息界面:

Context.goToAppInfoPage(packageName: String = this.packageName)
复制代码


跳转到日期和时间页面:

Context.goToDateAndTimePage()
复制代码


跳转到语言设置页面:

Context.goToLanguagePage()
复制代码


跳转到无障碍服务设置页面:

Context.goToAccessibilitySetting()
复制代码


浏览器打开指定网页:

Context.openBrowser(url: String)
复制代码


安装 apk :

// need android.permission.REQUEST_INSTALL_PACKAGES after N
Context.installApk(apkFile: File)
复制代码


在应用商店中打开应用:

Context.openInAppStore(packageName: String = this.packageName)
复制代码


启动 App :

Context.openApp(packageName: String)
复制代码


卸载 App :(好像并没有什么用)

Context.uninstallApp(packageName: String)
复制代码


Log 相关

fun String.logv(tag: String = TAG) = log(LEVEL.V, tag, this)
fun String.logd(tag: String = TAG) = log(LEVEL.D, tag, this)
fun String.logi(tag: String = TAG) = log(LEVEL.I, tag, this)
fun String.logw(tag: String = TAG) = log(LEVEL.W, tag, this)
fun String.loge(tag: String = TAG) = log(LEVEL.E, tag, this)
private fun log(level: LEVEL, tag: String, message: String) {
    when (level) {
        LEVEL.V -> Log.v(tag, message)
        LEVEL.D -> Log.d(tag, message)
        LEVEL.I -> Log.i(tag, message)
        LEVEL.W -> Log.w(tag, message)
        LEVEL.E -> Log.e(tag, message)
    }
}
复制代码


tag 默认为 ktx,你也可以在参数中自己指定。

"abc".logv()
"def".loge(tag = "xxx")
复制代码


SystemService 相关

原来我们是这样获取系统服务的:

val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
复制代码


其实也挺简洁的,但是我们忘记了 Context.WINDOW_SERVICE 咋办?通过扩展属性可以让它更优雅。

val Context.powerManager get() = getSystemService<PowerManager>()
inline fun <reified T> Context.getSystemService(): T? =
    ContextCompat.getSystemService(this, T::class.java)
复制代码


对于用户来说,直接使用 powerManager 即可,无需任何额外工作。

已作为扩展属性的系统服务如下:

val Context.windowManager
val Context.clipboardManager
val Context.layoutInflater
val Context.activityManager
val Context.powerManager
val Context.alarmManager
val Context.notificationManager
val Context.keyguardManager
val Context.locationManager
val Context.searchManager
val Context.storageManager
val Context.vibrator
val Context.connectivityManager
val Context.wifiManager
val Context.audioManager
val Context.mediaRouter
val Context.telephonyManager
val Context.sensorManager
val Context.subscriptionManager
val Context.carrierConfigManager
val Context.inputMethodManager
val Context.uiModeManager
val Context.downloadManager
val Context.batteryManager
val Context.jobScheduler
复制代码


App 相关

Context.versionName: String
Context.versionCode: Long
Context.getAppInfo(apkPath: String): AppInfo
Context.getAppInfos(apkFolderPath: String): List<AppInfo>
Context.getAppSignature(packageName: String = this.packageName): ByteArray?
复制代码


这一块内容暂时还比较少,主要是整理了我在项目中遇到的一些常见需求。获取版本号,版本名称,根据 apk 文件获取应用信息,获取应用签名等等。App 相关的其实会有很多工具类,后续会慢慢补充。


View 相关

View.visible()
View.invisible()
View.gone()
var View.isVisible: Boolean
var View.isInvisible: Boolean
var View.isGone: Boolean
View.setPadding(@Px size: Int)
View.postDelayed(delayInMillis: Long, crossinline action: () -> Unit): Runnable
View.toBitmap(config: Bitmap.Config = Bitmap.Config.ARGB_8888): Bitmap
复制代码

也都是一些比较常用的函数。


Common

Context.dp2px(dp: Float): Int
Context.px2dp(px: Float): Int
View.dp2px(dp: Float): Int
View.px2dp(px: Float): Int
Context.screenWidth
Context.screenHeight
Context.copyToClipboard(label: String, text: String)
复制代码


其他

RecyclerView.itemPadding(top: Int, bottom: Int, left: Int = 0, right: Int = 0)
ByteArray.toHexString(): String
...... 
复制代码


使用


implementation 'luyao.util.ktx:AndroidUtilKTX:0.0.5'
复制代码


总结


以上都是我在项目中提炼出来的,也正因如此,现在的 AndroidUtilCodeKTX 还只是个孩子,做不到那么的尽善尽美,面面俱到。我会持续更新完善这个库,也希望大家可以多多提 issuepr,提供您宝贵的意见!


在这里也十分感谢 Jie Smart 昨天的邮件反馈,提供了一些修改意见,也让我更有动力去继续维护。另外,最新版本的 AndroidUtilCodeKTX 我都会第一时间用在我的开源项目 wanandroid 上,欢迎大家 star ,fork !



相关文章
|
21天前
|
敏捷开发 测试技术 持续交付
自动化测试之美:从零开始搭建你的Python测试框架
在软件开发的马拉松赛道上,自动化测试是那个能让你保持节奏、避免跌宕起伏的神奇小助手。本文将带你走进自动化测试的世界,用Python这把钥匙,解锁高效、可靠的测试框架之门。你将学会如何步步为营,构建属于自己的测试庇护所,让代码质量成为晨跑时清新的空气,而不是雾霾中的忧虑。让我们一起摆脱手动测试的繁琐枷锁,拥抱自动化带来的自由吧!
|
2月前
|
API 开发工具 开发者
开发者必备:10个提升工作效率的网站🚀
作为一名开发者,利用合适的工具可以显著提高工作效率。以下是我个人推荐的10个网站,能够帮助你节省时间并提升开发质量。
62 2
开发者必备:10个提升工作效率的网站🚀
|
7月前
|
数据处理 开发者
【Uniapp 专栏】提升 Uniapp 开发效率的进阶方法
【5月更文挑战第17天】提升Uniapp开发效率的关键包括组件化、模板语法、数据处理和代码组织。通过封装组件如通用按钮,利用列表渲染生成多个元素,使用计算属性和方法处理复杂逻辑,以及采用预处理器如Sass编写样式。此外,良好的代码结构和使用开发者工具进行调试也是重要环节。掌握这些进阶技巧能帮助开发者更高效地构建高质量应用。
132 2
【Uniapp 专栏】提升 Uniapp 开发效率的进阶方法
|
5月前
|
前端开发 JavaScript 开发工具
前端开发最佳实践与工具推荐
【7月更文挑战第22天】前端开发是一个充满挑战和机遇的领域,掌握最佳实践和高效工具是提升开发效率、保证项目质量的关键。通过遵循版本控制、构建和部署、编写高质量代码、性能优化和安全性等最佳实践,并结合代码编辑工具、版本控制工具、包管理工具、构建工具、调试工具等实用工具,我们可以更好地完成前端开发任务,提升个人和团队的竞争力。
|
7月前
|
小程序 测试技术 持续交付
小程序全栈开发:如何提高开发效率
【4月更文挑战第12天】本文探讨了提高小程序全栈开发效率的策略:选择合适开发工具和框架,如微信开发者工具和Taro;实践模块化和组件化开发,增强代码复用性;采用前后端分离模式,提升灵活性;利用微信云开发平台简化工作流程;关注代码优化与性能调优;实施自动化测试和持续集成;强调团队协作与沟通;并强调持续学习与总结,以提升开发效率和构建高质量小程序。
80 2
|
7月前
|
XML JSON 开发者
Star 19.7k!提高开发效率的利器:DevToys开发人员的瑞士军刀!
Star 19.7k!提高开发效率的利器:DevToys开发人员的瑞士军刀!
|
API 开发工具
【平台开发】技术整合思考(六)开发规范(持续更新)
【平台开发】技术整合思考(六)开发规范(持续更新)
76 0
自动化测试技术笔记(三):如何编写技术方案
首先这个要求我觉得挺正常,一方面评审可以查漏补缺完善细节,另一方面也可以考察具体的落地经验和能力。其次,我认为技术方案其实有个通用的模版,或者说抽象的经验参考,这也是本篇文章我想聊的话题。
|
程序员 开发者 Windows
|
存储 弹性计算 分布式计算
关于开发者的心得
在这次在家时间过程中学到了很多,实现了远程访问,学会了如何管理后台,控制服务器。