Kotlin lightweight Android development

What is Kotlin

KotlinIt is a language that runs on JVMtop of .

It Jetbrainswas created by , the company behind Jetbrainsmany powerful tools such as the well-known . is a very simple language, one of its main goals is to provide a powerful language while maintaining a simple and streamlined syntax.Java IDE IntelliJ IDEAKotlin
Insert image description here

kotlin features

Its main features are as follows:

  1. Lightweight: This is Androidvery important for. The libraries required by the project should be as small as possible. AndroidThere is a strict limit on the number of methods, and Kotlinonly about 6000 additional methods have been added.
  2. Interoperability: Communicates seamlessly Kotlinwith Javalanguages. This means that we can Kotlinuse any existing Javalibrary in our code; therefore, even though the language is still young, there are already hundreds of libraries available. In addition to this, Kotlincode can be Javaused by code, which means we can use both languages ​​to build software. You can use it Kotlinto develop new features while implementing Javaother parts of the code base.
  3. Strong typing: We rarely need to specify types in our code because the compiler can infer the type of a variable or function return value in most cases. This way you get two benefits: simplicity and security. Using vardeclaring a variadic argument, valdeclaring an immutable argument var: varis a mutable variable, which is a variable that can be changed to another value by reassignment. This way of declaring variables Javais the same as declaring variables in . val: valis a read-only variable. This way of declaring a variable is equivalent to the variable javain final. One valmust be initialized when it is created because it cannot be changed later. The above code: var name = "ztz" println(name) name = "yif" println(name) val finalValue = "i v"; println(finalValue); The result is as follows: ztz yif iv
  4. Air security: Javathe biggest problem is null. If there is no nulljudgment on variables or parameters, a large number of them may be thrown in the program NullPointerException, but these are difficult to detect during coding. KotlinExplicit is used null, which forces us to check if necessary null.
  5. Syntactic sugar
    • Simplification of classes, implicit getter(), setter()
    • The default implementation of the interface
    • lambdas and higher-order functions
    • Null pointer safety, compile time null pointer checking
    • Streaming collection operations map(), forEach()
  6. new features
    • Function expansion, attribute expansion
    • attribute proxy

Kotlin lightweight development

Null safe

Kotlinis nullsafe. If a type may be null, then we need to add one after the type ?. This way, we need to check every time a variable of this type is used null. For example, the following code will not compile:

var artist: Artist? = null?
artist.print()

Line 2 will show an error because the variable is not nullchecked. We can do this:

if (artist != null) {
    
    
? artist.print()?
}

This demonstrates Kotlinanother great feature: smart type conversion. If the variable's type is checked, there is no need to cast it in the checking scope. With this, we can now use variables as types ifin . This is true for other inspections as well. There is an easier way to check , which is to use it before calling the object's function . You can even provide an alternative approach via operators :artistArtistnull?Elvis?

val name = artist?.name ?: ""

data class data

In Java, if we want to create a data class or POJOa class (a class that just saves some state), we need to create a class with a lot of fields, gettersand setters, and maybe provide toStringand equalsmethods:

public class Artist {
    
    
    private long id;
    private String name;
    private String url;
    private String mbid;
 
    public long getId() {
    
    
        return id;
    }
 
    public void setId(long id) {
    
    
        this.id = id;
    }
 
    public String getName() {
    
    
        return name;
    }
 
    public void setName(String name) {
    
    
        this.name = name;
    }
 
    public String getUrl() {
    
    
        return url;
    }
 
    public void setUrl(String url) {
    
    
        this.url = url;
    }
 
    public String getMbid() {
    
    
        return mbid;
    }
 
    public void setMbid(String mbid) {
    
    
        this.mbid = mbid;
    }
 
    @Override public String toString() {
    
    
        return "Artist{
    
    " +
                "id=" + id +
                ", name='" + name + '\'' +
                ", url='" + url + '\'' +
                ", mbid='" + mbid + '\'' +
                '}';
    }
}

In Kotlin, the above code can be written as follows:

data class Artist (?
    var id: Long,
    var name: String,
    var url: String,
    var mbid: String)

KotlinUse properties instead of fields. Basically, a property is a field plus its getterAND setter.

Interoperability

KotlinProvides some great interoperability features, which are Androidvery helpful for development. lambdaOne of them is the mapping between an interface with a single method and an expression. Thus, the following click listener:

view.setOnClickListener(object : View.OnClickListener {
    
    
    override fun onClick(v: View) {
    
    
        toast("Click")?
    }
?})

It can be written like this:

view.setOnClickListener {
    
     toast("Click") }

Additionally, gettersand settersare automatically mapped to properties. There is no performance penalty because the bytecode actually just calls the original gettersAND setters. As shown in the following code:

supportActionBar.title = title
textView.text = title
contactsList.adapter = ContactsYifAdapter()

lambda expression

LambdaExpressions will simplify the code to a great extent, but the important thing is that with the help of Lambdaexpressions, we can do things that were previously impossible or very troublesome to implement. Expressions allow Lambdaus to think about problems in a more functional way. LambdaAn expression is actually a specified type, and the type defines a function. For example, we can define a variable like this:

val listener: (View) -> Boolean

This variable can declare a function that takes a viewand returns this function. We need to define the behavior of the function through closure:

val listener = {
    
     view: View -> view is TextView }

The above function will receive an instance of View, and if it viewis TextView, it will return it true. Since the compiler can infer the type, we don't need to specify it. It can also be more explicit:

val listener: (View) -> Boolean = {
    
     view -> view is TextView }

With the help of Lambdaexpressions, we can abandon the use of callback interfaces. Just set the function you want to be called later:

fun asyncOperation(value: Int, callback: (Boolean) -> Unit) {
    
    
    ...
    callback(true)?
}
asyncOperation(5) {
    
     result -> println("result: $result") }

There is a more concise way. If the function only receives one parameter, you can use reserved words it:

asyncOperation(5) {
    
     println("result: $it") }

higher order function

lambda`本身作为一等公民,它是有类型的。比如下面这个加法表达式sum的类型为`(Int, Int) -> Int。
val sum: (Int, Int) -> Int = { x, y -> x+y }

It is natural for a variable to have a type. Since the input and return value of a high-order function is lambda, it is normal for its type to be a bit strange.

fun main(args: Array<String>) {
    
    
    // 自定义高阶函数, lambda 表达式 作为入参
    listOf("1", "2", "3", "4").myForEach {
    
     println(it) }

    // 自定义高阶函数, lambda 表达式 作为返回值
//    getLogger()("I'm a Closure")
    var logger = getLogger()
    logger("I'm a Closure")
}

/**
 * 接受一个 lambda 表达式, 作为遍历任务
 */
fun <T> List<T>.myForEach(doTask: (T) -> Unit){
    
    
    for(item in this)
        doTask(item)
}

/**
 * 返回一个 lambda 表达式(闭包), 如: 日志输出工具 logger
 */
fun getLogger(): (String) -> Unit{
    
    
//    return { println(it) }
    return fun (it: String){
    
    
        println(it)
    }
}

PS: Seeing getLogger()this usage, you probably realize that you can jswrite closures like that.

The default implementation of the interface

As the name suggests, it means that the interface can have a default implementation of the method body like an abstract class. I attribute it to syntactic sugar, because there java8is already exactly the same thing in China, and the corresponding keyword is called default.

interface A {
    
    
    fun foo() {
    
     println("A") }    // 默认实现, 打印"A"
    fun bar()
}
 
interface B {
    
    
    fun foo() {
    
     println("B") }
    fun bar() {
    
     println("bar") }
}
 
// 多继承时,显式指定 super<A>.foo() 以去冲突
class D : A, B {
    
    
    override fun foo() {
    
    
        super<A>.foo()
        super<B>.foo()
    }
 
    override fun bar() {
    
    
        super.bar()
    }
}

Streaming collection operations map(), forEach()

Streaming set operators are very common and can be found in any language. However, if they do not support functional expressions, they will be cumbersome to write. In the following example, the connection of some operators makes the operation logic very clear. If the demand changes later, such as changing descending order to ascending order, only one sortedDescending()line needs to be changed, which is very flexible.

fun main(args: Array<String>){
    
    
    val list = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    list.filter {
    
     it%2==0 }             // 取偶数
            .map{
    
     it*it }               // 平方
            .sortedDescending()         // 降序排序
            .take(3)                    // 取前 3 个
            .forEach {
    
     println(it) }    // 遍历, 打印
}
 
// 输出:
100
64
36

expand

Expanding this thing seems to be done in the decorator mode. Its effect is to add functions without changing the source code. For example, if we want to Activityadd one toast(), we don't need to uninstall the base class at all. This simplifies a lot of work, especially for some packaged jarclasses.

fun Activity.toast(msg: String) {
    
    
    Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
}
/**
 * @author yif
 *
 * 函数拓展, 属性拓展
 */
fun main(args: Array<String>) {
    
    
    val list = listOf("1", "2", "3", "4")
 
    // 函数拓展
    list.myForEach {
    
     println(it) }
 
    // 属性拓展
    println("last: ${
    
    list.lastItem}")
}
 
/**
 * 拓展 List 类, 加一个自定义的遍历方法
 */
fun <T> List<T>.myForEach(doTask: (T) -> Unit){
    
    
    for(item in this)
        doTask(item)
}
 
/**
 * 拓展 List 类, 加一个自定义的长度属性
 */
val <T> List<T>.lastItem: T
        get() = get(size - 1)
 
// 输出:
1
2
3
4
last: 4

attribute proxy

It delegates the properties of get()the set()property to a class so that it can do some additional operations during get()and . set()like:

  • Lazy loading
  • Observer (automatically notifies when properties change)
  • Taking lazy loading as an example for attribute non-empty judgment, lazySumit may require complex operations, so we delegate it to lazy. As you can see, only the first load is calculated, and subsequent values ​​are taken directly, which improves efficiency. val lazySum: Int by lazy { println("begin compute lazySum ...") var sum = 0 for (i in 0…100) sum += i println("lazySum computed!n") sum // Return the calculation result} fun main (args: Array<String>) { println(lazySum) println(lazySum) } // Output: begin compute lazySum … lazySum computed! 5050 5050 Anko Ankois Kotlina library developed by the team to simplify Androiddevelopment. Its main goal is to provide a view DSLthat can be declared using Kotlincode: verticalLayout { val name = editText() button("Say Hello") { onClick { toast("Hello, ${name.text}!") } } } It also Provides some other useful features. For example, navigate to otherActivityAnd pass values ​​to other interfaces: startActivity("id" to res.id, "name" to res.name) startActivity<ContentActivity>( Pair(Constants.CONTENT_TITLE_KEY, useWebsiteBean.name), Pair(Constants.CONTENT_URL_KEY, useWebsiteBean.link ), Pair(Constants.CONTENT_ID_KEY, useWebsiteBean.id) ) Summary Kotlin really simplifies Android development work in many aspects. It will increase your productivity and solve some common problems in a very different and simpler way. Let’s use Kotlin for rapid and agile development .

Guess you like

Origin blog.csdn.net/hdbdhdbh/article/details/131286043