preface
I first encountered Kotlin in 2017, before it was fully fledged and not an official Android development language. As for how I got into Amway, if I remember correctly, it was Kotlin’s tutorial in open Source Lab. At that time, few people around me were learning Kotlin, and there was very little information on the Internet. I also translated some of the official website documents and wrote a GitBook. Of course, now there is a better Kotlin Language Chinese site, for those who are not very good at English foundation, this is a good entry material.
Two and a half years later, Kotlin has become the official Android development language. Although it may have been to avoid a lawsuit with Oracle, I’m sure it wasn’t the main reason. Kotlin, defined as Better Java, did Better and became more widely used.
New LeakCanary 2! Completely Based on Kotlin Refactoring upgrade!
Retrofit server! Faster coroutine experience!
A growing number of well-known tripartite libraries are already offering support for Kotlin. Kotlin will also be a priority in Android’s official new features. In addition to Android, Spring 5 officially announced Kotlin as one of its key new features. As far as you can see, Kotlin has a future in the JVM language.
My previous article really smells good! Kotlin+MVVM+LiveData+ Coroutine build Wanandroid! The Kotlin MVVM version of the Wanandroid app has been opened source in China, with a total of 138 stars and 20 forks. Data isn’t stellar, but it’s a big step in my open source career. I am also updating this project all the time. Welcome to continue to pay attention to it.
In my current job, I’ve made Kotlin my first choice, barring some irresistible factors. After working on multiple projects, I found myself copying code from project to project, base classes, extension functions, utility classes, etc. Sometimes it even goes back to old Java code, or Blankj’s AndroidUtilCode, and uses it directly. But a lot of the time, it’s not very elegant and doesn’t make good use of the Kotlin language. I desperately need a generic Kotlin utility class library.
From this, AndroidUtilCodeKTX was born. If you’ve ever used Blankj’s AndroidUtilCode, it’s the same, but it’s not a simple Kotlin translation, it’s more of a Kotlin hybrid, everything from “simple” to less code. Talk is easy, show me the code! Without further ado, the following code shows the use of some utility classes in AndroidUtilCodeKTX.
AndroidUtilCodeKTX
Permission to request
request(Manifest.permission.READ_CALENDAR, Manifest.permission.RECORD_AUDIO) {
onGranted { toast("onGranted") }
onDenied { toast("onDenied") }
onShowRationale { showRationale(it) }
onNeverAskAgain { goToAppInfoPage() }
}
Copy the code
With extension functions and DSLS, it’s easy to gracefully request permissions and handle callbacks in an Activity. This is not an entirely new wheel, the main code comes from PermissionsKt. But it has a fatal flaw, need a developer manual override a onRequestPermissionsResult () to process the authorization request as a result, it is not so simple and elegant. I’ve borrowed the RxPermissions approach here by attaching the Activity to a Fragment for permission requests and callback processing, which is insensitive to the user and avoids extra code. A separate article will be written to examine the Kotlin DSL in action.
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))
Copy the code
Basic store and read operations can be done by a single function, relying on generics without actively declaring the type of the value. The default storage file name is called the package name. If you want to customize the file name, declare the name parameter:
putSpValue("another"."from another sp file",name = "another")
getSpValue("another"."null",name = "another")
Copy the code
The Activity related to the
The main thing is to optimize the use of startActivity so that you can start the Activity with a single line of code in any case.
Normal jump:
startKtxActivity<AnotherActivity>()
Copy the code
Jump with flag:
startKtxActivity<AnotherActivity>(Intent.FLAG_ACTIVITY_NEW_TASK)
Copy the code
StartActivityForResult:
startKtxActivityForResult<AnotherActivity>(requestCode = 1024)
Copy the code
Valued jump:
startKtxActivity<AnotherActivity>(value = "string" to "single value")
Copy the code
Jump with multiple values:
startKtxActivity<AnotherActivity>(
values = arrayListOf(
"int" to 1."boolean" to true."string" to "multi value"))Copy the code
Jump with Bundle:
startKtxActivity<AnotherActivity>(
extra = Bundle().apply {
putInt("int".2)
putBoolean("boolean".true)
putString("string"."from bundle")})Copy the code
Basically covers all Activity jumps.
Aes encryption correlation
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?
Copy the code
Encapsulates Aes encryption operation, provides fast data and file encryption and decryption method, without paying attention to internal details. AES/CFB/NoPadding is used by default. You can modify the mode with the cipherAlgotirhm parameter.
plainText.toByteArray().aesEncrypt(key, iv, "AES/CBC/PKCS5Padding"
plainText.toByteArray().aesEncrypt(key, iv, "AES/ECB/PKCS5Padding"
plainText.toByteArray().aesEncrypt(key, iv, "AES/CTR/PKCS5Padding"
Copy the code
Hash related
String and ByteArray extension methods for fast hashing.
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
Copy the code
Supports MD5, SHA1, SHA224, SHA256, SHA384, and SHA512. MD5 is no longer secure and cryptographically no longer recommended.
val origin = "hello"
val md5 = origin.hash(Hash.MD5)
val sha1 = origin.hash(Hash.SHA1)
Copy the code
In addition to string hash, file hash operations are also provided.
val file = File("xxx")
val md5 = file.hash(Hash.MD5)
val sha1 = file.hash(Hash.SHA1)
Copy the code
Intent related
Switch to the application information page:
Context.goToAppInfoPage(packageName: String = this.packageName)
Copy the code
Jump to the Date and Time page:
Context.goToDateAndTimePage()
Copy the code
Jump to the language setting page:
Context.goToLanguagePage()
Copy the code
Jump to the barrier-free service setting page:
Context.goToAccessibilitySetting()
Copy the code
Browser to open the specified page:
Context.openBrowser(url: String)
Copy the code
Install the apk:
// need android.permission.REQUEST_INSTALL_PACKAGES after N
Context.installApk(apkFile: File)
Copy the code
Opening an app in the App Store:
Context.openInAppStore(packageName: String = this.packageName)
Copy the code
Start the App:
Context.openApp(packageName: String)
Copy the code
Uninstall the App :(doesn’t seem to work)
Context.uninstallApp(packageName: String)
Copy the code
The Log related
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)
}
}
Copy the code
Tag is KTX by default, or you can specify it yourself.
"abc".logv()
"def".loge(tag = "xxx")
Copy the code
SystemService related
This is how we get system services:
val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
Copy the code
It’s actually pretty neat, but we forgot context.window_service. You can make it more elegant by extending the properties.
val Context.powerManager get() = getSystemService<PowerManager>()
inline fun <reified T> Context.getSystemService(a): T? =
ContextCompat.getSystemService(this, T::class.java)
Copy the code
For the user, you can just use powerManager without any extra work.
The system services that have been extended as attributes are as follows:
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
Copy the code
App related
Context.versionName: String
Context.versionCode: Long
Context.getAppInfo(apkPath: String): AppInfo
Context.getAppInfos(apkFolderPath: String): List<AppInfo>
Context.getAppSignature(packageName: String = this.packageName): ByteArray?
Copy the code
This section is still relatively small for the time being, but mainly summarizes some common requirements that I have encountered in projects. Get the version number, version name, get the application information from the APK file, get the application signature, etc. In fact, there will be many tool classes related to App, which will be added gradually in the future.
View related
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
Copy the code
These are some of the more common functions.
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)
Copy the code
other
RecyclerView.itemPadding(top: Int, bottom: Int, left: Int = 0, right: Int = 0)
ByteArray.toHexString(): String
......
Copy the code
use
implementation 'luyao. Util. KTX: AndroidUtilKTX: 0.0.5'
Copy the code
conclusion
That’s what I distilled from the project, and AndroidUtilCodeKTX is just a kid, and it can’t be that perfect. I will continue to update and improve this library. I also hope that you can make more issues and PR and provide your valuable opinions!
I would also like to thank Jie Smart for his email feedback yesterday, which provided me with some suggestions for revision and made me more motivated to continue maintenance. In addition, I will be using the latest version of AndroidUtilCodeKTX on my open source project WanAndroid for the first time. Welcome star, fork!
Article first published wechat public account: Bingxin said, focus on Java, Android original knowledge sharing, LeetCode problem solving.
More relevant knowledge, scan code to pay attention to me!