Android Util Code KTX! It's time to improve your development efficiency! (Continuous updates...)

Posted by gford on Fri, 19 Jul 2019 10:35:43 +0200

Preface

The first contact with Kotlin was in 2017, when Kotlin was not upgraded, nor was it the official Android development language. As for how Amway got me, if I remember correctly, it should be Open Source Lab Kotlin tutorial. At that time, almost no one was studying Kotlin, and there were few related materials on the Internet. I also translated some official documents and wrote a book. GitBook This is the case. Of course, there are better ones now. Kotlin Language Chinese Station Well, it's a good introduction for students who don't have a good foundation in English.

Over the past two and a half years, Kotlin has been transformed into the official Android development language. Although it may be to avoid litigation with Oracle, I believe this is definitely not the main reason. Kotlin, defined as Better Java, did a better job and was gradually being used by more people.

New Leak Canary 2! Fully based on Kotlin refactoring upgrade! >

Retrofit 2.6.0! Faster process experience!

More and more well-known tripartite libraries have begun to provide Kotlin support. Android's official new features will also give priority to Kotlin. In addition to Android, Spring 5 officially launched Kotlin as one of its new features. As can be seen from the naked eye, Kotlin is bound to make some progress in the field of JVM language.

My previous article What a fragrance! Kotlin+MVVM+LiveData + Co-op Create Wanandroid! Open source version of Kotlin MVVM Wanandroid Up to now, there are 138 star s and 20 fork s. The data is not very eye-catching, but it's a big step in my open source career. I have been updating this project, and welcome your continuous attention.

In my current job, unless there are some irresistible factors, I have made Kotlin my first choice. After working on several projects, I found that I often copy code, base classes, extension functions, tool classes and so on between projects. Sometimes it even flips back to previous Java code, or Blankj's. AndroidUtilCode Take it and use it directly. But most of the time, it is not so elegant to copy Java tool classes directly, and it does not make good use of Kotlin language features. I urgently need a common Kotlin tool class library.

Based on this, AndroidUtilCodeKTX It was born. If you've ever used Blankj's Android Util Code, they're the same in nature, but it's not a simple Kotlin translation, it's more a blend of Kotlin features. Everything from "simplicity", the less code the better. Talk is easy, show me the code! Let's not say much. Here's the code. AndroidUtilCodeKTX Use of some tool classes.

AndroidUtilCodeKTX

Privilege Request

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

With the help of extension functions and DSL, it is easy to gracefully request permissions and handle callbacks in Activity. This is not a brand new wheel. The main code comes from PermissionsKt This is the case. But it has a fatal disadvantage, requiring developers to manually override onRequestPermissionsResult() to handle the results of permission requests, which seems less concise and elegant. I learned from it here. RxPermissions By attaching a Fragment to the current Activity for privilege requests and callbacks, it is insensitive to the user and avoids additional code. A separate article will be written to analyze the application of 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))

Basic storage and reading operations can be accomplished with only one function, relying on generics without proactively declaring the type of value. The default storage file name is 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")

Activity related

The main purpose is to optimize the use of startActivity and strive to make it possible to start the Activity in one sentence under any circumstances.

Ordinary jump:

startKtxActivity<AnotherActivity>()

With flag jump:

startKtxActivity<AnotherActivity>(Intent.FLAG_ACTIVITY_NEW_TASK)

startActivityForResult :

startKtxActivityForResult<AnotherActivity>(requestCode = 1024)

Band value jump:

startKtxActivity<AnotherActivity>(value = "string" to "single value")

Jump with multiple values:

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

With Bundle jump:

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

It 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?

It encapsulates Aes encryption operation and provides fast data and file encryption and decryption methods without paying attention to internal details. By default, using AES/CFB/NoPadding mode, you can modify the mode through the cipher Algotirhm 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"

Hash correlation

It provides extension methods for String and ByteArray, which can quickly hash.

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

Support MD5, sha1, sha224, sha256, sha384, 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)

In addition to string hashing, it also provides hashing operations for files.

val file = File("xxx")
val md5 = file.hash(Hash.MD5)
val sha1 = file.hash(Hash.SHA1)

Intent correlation

Jump to the application information interface:

Context.goToAppInfoPage(packageName: String = this.packageName)

Jump to the date and time page:

Context.goToDateAndTimePage()

Jump to the Language Settings page:

Context.goToLanguagePage()

Jump to the accessibility service settings page:

Context.goToAccessibilitySetting()

Browser opens the specified page:

Context.openBrowser(url: String)

Install apk:

// need android.permission.REQUEST_INSTALL_PACKAGES after N
Context.installApk(apkFile: File)

Open applications in the App Store:

Context.openInAppStore(packageName: String = this.packageName)

Start App:

Context.openApp(packageName: String)

Uninstall App: (Seems to be useless)

Context.uninstallApp(packageName: String)

Log correlation

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 defaults to ktx, and you can specify it in your parameters.

"abc".logv()
"def".loge(tag = "xxx")

System Service correlation

It turned out that this was how we got system services:

val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager

Actually, it's quite concise, but we forgot about Context.WINDOW_SERVICE. It can be made more elegant by extending attributes.

val Context.powerManager get() = getSystemService<PowerManager>()

inline fun <reified T> Context.getSystemService(): T? =
    ContextCompat.getSystemService(this, T::class.java)

For users, power manager can be used directly without any extra work.

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

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?

This piece of content is still relatively small for the time being, mainly sorting out some common requirements I met in the project. Get version number, version name, application information according to apk file, application signature and so on. App-related tools will actually have a lot of classes, which will be slowly added 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

They are also some of the more commonly used 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)

Other

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

Use

implementation 'luyao.util.ktx:AndroidUtilKTX:0.0.5'

summary

These are all extracted from my project, and that's why, now. AndroidUtilCodeKTX Just a child, not so perfect, all-round. I will continue to update and improve the library, and I hope you can mention more about it. issue and pr Provide your valuable advice!

Thank you very much here. Jie Smart Yesterday's email feedback provided some suggestions for revision, which also gave me more motivation to continue maintenance. In addition, the latest version of Android Util Code KTX will be used in my open source projects for the first time. wanandroid ) On, welcome to star, fork!

Writing the first Wechat Public Number: Dedicated to Java, Android original knowledge sharing, LeetCode problem solving.

More relevant knowledge, sweep code to pay attention to me!

Topics: Android SHA1 Java less