Yesterday, the gods quietly gave a thumbs-up to their new work. Then there were ripples in the circle. Today I’m going to dip into the hot spot and tell you a little bit about the library.
At the time of writing, that’s what the numbers look like. God is god ah, basically engaged in Android development, will flow to him, like gangsters, always worship Guan Er Ye. Maybe some kids just click on the star and don’t read the content carefully.
What is this library for?
A set of Kotlin extensions for Android app development. The goal of Android KTX is to make Android development with Kotlin more concise, pleasant, and idiomatic. It is an explicit goal of this project to not add any new feature to the existing Android APIs.
This is super clear, this is a set of Kotlin extensions for Android application development. The goal is to use Kotlin for simple, enjoyable, idiomatic Android development, with the explicit goal of not adding new functionality to existing apis.
To put it simply, this library is a wrapper written by Kotlin that allows you to have fun and finish your project quickly. It’s just a wrapper and doesn’t add new functionality.
So, our code can get shorter and shorter and simpler. The dismissive might say, well, that’s just a bunch of grammar candy, that’s all. There was a universal skill he could do, but he didn’t bother to write.
To get into the body of the work, take a look at what wrappers the library currently provides.
Quite a lot, actually. I learned that it really doesn’t matter how much, the key is to be practical and really solve the pain points that exist in the development process.
In practical Java development, there is always some code that is a pain to look at. For example, the most basic setup is the click event. ViewTreeObserver listener, Bundle creation and storage, SharedPreferences storage, database Cursor operation, Hander message handling Intent jump, Runnable, etc. But in order to implement this method, you have to write a bunch of template methods or create objects to which you belong, and it feels like you’re sacrificing heaven every time, and the process has to be highly consistent.
So let’s compare and contrast.
//before val observer = textView.viewTreeObserver observer.addOnPreDrawListener(object : ViewTreeObserver.OnPreDrawListener { override fun onPreDraw(): Boolean { val maxLines = textView.height / textView.lineHeight textView.maxLines = maxLines textView.viewTreeObserver.removeOnPreDrawListener( this) return false } }) //after textView.doOnPreDraw { val maxLines = textView.height / textView.lineHeight textView.maxLines = maxLines } //before val sp = getEditor(context) sp.putFloat(key, value) sp.apply() //after getSharedPreferences(context).edit { putFloat(key, value) }Copy the code
Remember when you were just getting started using SharedPreferences and forgot to call the Apply () or commit() methods, resulting in invalid results. So with this library, you don’t have to worry about these details.
After reading the simple example, do you feel that the code is missing a lot after wrapping it up? And then let’s see what’s going on inside.
/**
* Performs the given action when the view tree is about to be drawn.
*/
inline fun View.doOnPreDraw(crossinline action: (view: View) -> Unit) {
val vto = viewTreeObserver
vto.addOnPreDrawListener(object : ViewTreeObserver.OnPreDrawListener {
override fun onPreDraw(): Boolean {
action(this@doOnPreDraw)
when {
vto.isAlive -> vto.removeOnPreDrawListener(this)
else -> viewTreeObserver.removeOnPreDrawListener(this)
}
return true
}
})
}
Copy the code
As you can see from above, the code is still the tedious code before, fixed code has become a template, and you need to do the specific action method callback to you to achieve.
Here we focus on three keywords, inline and crossinline noinline
Inline: As we all know, in Java, methods that cannot be directly assigned must be object oriented. For example, the ClickListener for the click event, we end up needing the onClick() method, but each time we have to wrap it as a ClickListener object. Instead of creating a function object for the parameter and then generating a call, the compiler can issue the following code after using the inline keyword on the method, which is not so cool.
Crossinline: After inline, if our function as a parameter to the method is not called directly inside the method, but in a lambda expression or an inner class, we declare the method using Crossinline as needed to tell the compiler that it can pass. Kind of like in Java, when an inner class calls an external temporary variable that must be declared final.
Noinline: Having said crossinline, we can of course also know that we sometimes want to limit the scope of this function parameter, so we need to use noinline to declare it. It’s kind of like @nullale @nonNULL, where the IDE automatically checks for you and warns you.
Now that you’re done with the keyword, let’s take a look at Closure. Kotlin uses a lot of closures, and the intuition is that you can have a lot fewer parentheses.
Look at the following method call, which is supposed to call the doOnPreDraw() method, but its parentheses are missing.
textView.doOnPreDraw {
val maxLines = textView.height / textView.lineHeight
textView.maxLines = maxLines
}
Copy the code
To complete it, it would look like this:
textView.doOnPreDraw({
view ->
})
Copy the code
The reason for this is that if your method has only one argument and it is a function expression, you can omit the parentheses and keep them concise and readable. Don’t you think curly braces look a little weird with curly braces?
This kind of closure is quite common. If you look at the build.gradle configuration file, for example, is it all the same?
signingConfigs { release { storeFile file(".. /release.jks") keyPassword gradle.password } debug { storeFile file(".. /debug.keystore") storePassword "android "}}Copy the code
As I said at the beginning, I hate the method of writing jump activities. It’s really annoying. It’s like this:
val intent = Intent(context, TopicDetailActivity::class.java) intent.putExtra(Constants.ID, id) context!! .startActivity(intent)Copy the code
Then do a similar trick yourself:
inline fun <T> startActivityIntent(context: Context? , clazz: Class<T>, action: (intent: Intent) -> Unit) { if (context == null) { return } val intent = Intent(context, clazz) action(intent) context.startActivity(intent) }Copy the code
Then you can call happily:
startActivityIntent(context, TopicDetailActivity::class.java, {
it.putExtra(Constants.ID, id)
})
Copy the code
At this point, this article should end. In addition to the Kotlin extension library just released by Google, The Kotlin official has long provided related extensions for us to develop, but also for fear that we will not adapt to it at first. https://github.com/Kotlin/anko
Back to the title, if you haven’t really used Kotlin by this point, you should really consider trying it out and playing around with it, because it supports lambda, supports closures, and has cleaner code. And it’s backed by Google, just like Android Studio was when it started.
By the way, this library is not the final version at present, and there may be normative changes or removal of THE API. If you use it directly for projects, you should be prepared for the risks.
The resources
Kotlin Functions should read the official documentation. @parcelize is also super fun to use.