Desarrollo ligero de Android con Kotlin

¿Qué es Kotlin?

KotlinEs un lenguaje que se ejecuta encima JVMde .

Fue Jetbrainscreado por , la empresa detrás de Jetbrainsmuchas herramientas poderosas como la conocida . es un lenguaje muy simple, uno de sus principales objetivos es proporcionar un lenguaje potente manteniendo una sintaxis simple y optimizada.Java IDE IntelliJ IDEAKotlin
Insertar descripción de la imagen aquí

características de kotlin

Sus principales características son las siguientes:

  1. Ligero: Esto es Androidmuy importante para. Las bibliotecas requeridas por el proyecto deben ser lo más pequeñas posible. AndroidExiste un límite estricto en la cantidad de métodos y Kotlinsolo se han agregado alrededor de 6000 métodos adicionales.
  2. Interoperabilidad: se comunica perfectamente Kotlincon Javaidiomas. Esto significa que podemos Kotlinusar cualquier Javabiblioteca existente en nuestro código, por lo tanto, aunque el lenguaje aún es joven, ya hay cientos de bibliotecas disponibles. Además de esto, Kotlinel código se puede Javausar por código, lo que significa que podemos usar ambos lenguajes para crear software. Puede usarlo Kotlinpara desarrollar nuevas funciones mientras implementa Javaotras partes del código base.
  3. Escritura fuerte: rara vez necesitamos especificar tipos en nuestro código porque el compilador puede inferir el tipo de una variable o el valor de retorno de una función en la mayoría de los casos. De esta forma obtienes dos beneficios: simplicidad y seguridad. Al vardeclarar un argumento variado, valdeclarar un argumento inmutable var: vares una variable mutable, que es una variable que se puede cambiar a otro valor mediante reasignación. Esta forma de declarar variables Javaes la misma que declarar variables en . val: vales una variable de solo lectura. Esta forma de declarar una variable es equivalente a la variable javaen final. Uno valdebe inicializarse cuando se crea porque no se puede cambiar más adelante. El código anterior: var nombre = "ztz" println(nombre) nombre = "yif" println(nombre) val finalValue = "i v"; println(finalValue); El resultado es el siguiente: ztz yif iv
  4. Seguridad aérea: Javael mayor problema es null. Si no se nulljuzgan las variables o parámetros, es posible que se incluyan una gran cantidad de ellos en el programa NullPointerException, pero son difíciles de detectar durante la codificación. KotlinSe utiliza explícito null, lo que nos obliga a comprobarlo si es necesario null.
  5. Azúcar sintáctica
    • Simplificación de clases, getter() implícito, setter()
    • La implementación predeterminada de la interfaz.
    • lambdas y funciones de orden superior
    • Seguridad de puntero nulo, comprobación de puntero nulo en tiempo de compilación
    • Mapa de operaciones de recopilación de streaming (), forEach ()
  6. nuevas características
    • Expansión de funciones, expansión de atributos.
    • proxy de atributo

Desarrollo ligero de Kotlin

Nulo seguro

Kotlines nullseguro. Si un tipo puede ser null, entonces debemos agregar uno después del tipo ?. De esta forma, debemos comprobar cada vez que se utiliza una variable de este tipo null. Por ejemplo, el siguiente código no se compilará:

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

La línea 2 mostrará un error porque la variable no está nullmarcada. Podemos hacer esto:

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

Esto demuestra Kotlinotra gran característica: la conversión de tipos inteligente. Si se marca el tipo de variable, no es necesario incluirla en el alcance de verificación. Con esto, ahora podemos usar variables como tipos ifen . Esto también se aplica a otras inspecciones. Hay una forma más sencilla de comprobarlo , que es utilizarlo antes de llamar a la función del objeto . Incluso puedes proporcionar un enfoque alternativo a través de operadores :artistArtistnull?Elvis?

val name = artist?.name ?: ""

datos de clase de datos

En Java, si queremos crear una clase de datos o POJOuna clase (una clase que simplemente guarda algún estado), necesitamos crear una clase con muchos campos gettersy setters, y tal vez proporcionar métodos toStringy :equals

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 + '\'' +
                '}';
    }
}

En Kotlin, el código anterior se puede escribir de la siguiente manera:

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

KotlinUtilice propiedades en lugar de campos. Básicamente, una propiedad es un campo más su getterAND setter.

Interoperabilidad

KotlinProporciona excelentes funciones de interoperabilidad, que son Androidmuy útiles para el desarrollo. lambdaUno de ellos es el mapeo entre una interfaz con un único método y una expresión. Por lo tanto, el siguiente oyente de clics:

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

Se puede escribir así:

view.setOnClickListener {
    
     toast("Click") }

Además, gettersy settersse asignan automáticamente a propiedades. No hay ninguna penalización en el rendimiento porque el código de bytes en realidad simplemente llama al gettersAND original setters. Como se muestra en el siguiente código:

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

expresión lambda

LambdaLas expresiones simplificarán el código en gran medida, pero lo importante es que con la ayuda de Lambdaexpresiones podemos hacer cosas que antes eran imposibles o muy problemáticas de implementar. Las expresiones nos permiten Lambdapensar en los problemas de una manera más funcional. LambdaUna expresión es en realidad un tipo específico y el tipo define una función. Por ejemplo, podemos definir una variable como esta:

val listener: (View) -> Boolean

Esta variable puede declarar una función que toma viewy devuelve esta función. Necesitamos definir el comportamiento de la función mediante cierre:

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

La función anterior recibirá una instancia de Viewy, si viewes así TextView, la devolverá true. Dado que el compilador puede inferir el tipo, no es necesario especificarlo. También puede ser más explícito:

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

Con la ayuda de Lambdaexpresiones, podemos abandonar el uso de interfaces de devolución de llamada. Simplemente configura la función a la que quieres que te llamen más tarde:

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

Hay una forma más concisa: si la función solo recibe un parámetro, puedes usar palabras reservadas it:

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

función de orden superior

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

Es natural que una variable tenga un tipo. Dado que el valor de entrada y retorno de una función de orden superior es lambda, es normal que su tipo sea un poco extraño.

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)
    }
}

PD: Al ver getLogger()este uso, probablemente te des cuenta de que puedes jsescribir cierres como ese.

La implementación predeterminada de la interfaz.

Como sugiere el nombre, significa que la interfaz puede tener una implementación predeterminada del cuerpo del método como una clase abstracta. Lo atribuyo al azúcar sintáctico, porque java8ya existe exactamente lo mismo en China, y la palabra clave correspondiente se llama 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()
    }
}

Mapa de operaciones de recopilación de streaming (), forEach ()

Los operadores de conjuntos de transmisión son muy comunes y se pueden encontrar en cualquier idioma, sin embargo, si no admiten expresiones funcionales, será complicado escribirlos. En el siguiente ejemplo, la conexión de algunos operadores deja muy clara la lógica de operación: si la demanda cambia más tarde, como cambiar el orden descendente a ascendente, solo es necesario sortedDescending()cambiar una línea, lo cual es muy 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

expandir

La expansión de esto parece hacerse en el modo decorador. Su efecto es agregar funciones sin cambiar el código fuente. Por ejemplo, si queremos Activityagregar uno toast(), no necesitamos desinstalar la clase base en absoluto. Esto simplifica mucho el trabajo, especialmente para algunas jarclases empaquetadas.

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

proxy de atributo

Delega las propiedades de get()la set()propiedad a una clase para que pueda realizar algunas operaciones adicionales durante get()y . set()como:

  • Carga lenta
  • Observador (notifica automáticamente cuando cambian las propiedades)
  • Tomando la carga diferida como ejemplo para el juicio de atributos no vacíos, lazySumpuede requerir operaciones complejas, por lo que la delegamos a lazy. Como puede ver, solo se calcula la primera carga y los valores posteriores se toman directamente, lo que mejora la eficiencia. val lazySum: Int by lazy { println("comenzar a calcular lazySum ...") var sum = 0 for (i in 0…100) sum += i println("lazySum calculada!n") sum // Devuelve el resultado del cálculo } fun main (args: Array<String>) { println(lazySum) println(lazySum) } // Salida: comienza a calcular lazySum... ¡lazySum calculada! 5050 5050 Anko es Ankouna Kotlinbiblioteca desarrollada por el equipo para simplificar Androidel desarrollo. Su objetivo principal es proporcionar una vista DSLque se pueda declarar usando Kotlincódigo: verticalLayout { val nombre = editText() botón("Di Hola") { onClick { brindis("Hola, ${name.text}!") } } } También proporciona algunas otras funciones útiles. Por ejemplo, navegue a otrosActivityY pase valores a otras interfaces: startActivity("id" a res.id, "name" a 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) ) Resumen Kotlin realmente simplifica el trabajo de desarrollo de Android en muchos aspectos. Aumentará tu productividad y solucionará algunos problemas habituales de una forma muy diferente y sencilla. Utilicemos Kotlin para un desarrollo rápido y ágil .

Supongo que te gusta

Origin blog.csdn.net/hdbdhdbh/article/details/131286043
Recomendado
Clasificación