Android kotlin高级特性

不错

https://www.jianshu.com/p/5f77209abb9b

 

https://www.jianshu.com/p/cf9d068d4b6c

 

 

Kotlin+RxJava+Android Architecture Components

 

1.Kotlin优缺点

2.Kotlin基本变量,方法,类

https://www.jianshu.com/p/cf9d068d4b6c

https://blog.csdn.net/carson_ho/article/details/96965702

 

 

1.Kotlin跟Java比,kotlin具有哪些优势?

 

  Kotlin语言简练,而且Kotlin里面可以没有空指针问题,在Android中使用Java就会存在很多令人头大的空指针问题。

 

2.当你项目中同时使用Kotlin和Java,你是如何保证空指针问题的?

 

  首先,Kotlin本身就不存在空指针问题,而如果你在Kotlin中去调用Java某个类的方法的时候,这个方法最好使用注解的方式来避免返回空指针。

 

1.Kotlin是什么?

1.Kotlin是一种基于JVM的编程语言。

2.实际上它是对Java的一种扩展。

3.Kotlin支持函数式编程。

4.Kotlin类和Java类的互相调用。

 

理解Android Architecture Components系列(一)

使用的Kotlin特性:

Kotlin允许开发者在不改变已有类的情况下,为某个类添加新的函数。这个特性叫做扩展函数。

举一个简单的例子。如果要关闭一个I/O流,使用Java可能是写一个工具方法。

/**
 * 安全关闭io流
 * @param closeable
 */
public static void closeQuietly(Closeable closeable) {
    if (closeable != null) {
        try {
            closeable.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

对Kotlin而言,可以对Closeable扩展一个函数closeQuietly()。

fun Closeable?.closeQuietly() {
    try {
        this?.close()
    } catch (e: Throwable) {
    }
}

之后,任何实现了Closeable接口的类,都可以使用它本身的closeQuietly()方法来关闭流。我们不再需要那个工具方法了。

 

使用扩展函数

 

fun loge(tag: String, content: String?) {
    Log.e(tag, content ?: tag)
}

调用的时候直接使用loge(TAG, "content")

 

在项目中,我们使用扩展函数对Glide做了封装,大大简化了Glide的使用。

/**
     * 占位符矩形
     */
    fun ImageView.load(url: String) {
        get(url).placeholder(R.drawable.shape_default_rec_bg)
                .error(R.drawable.shape_default_rec_bg)
                .into(this)
    }

    /**
     * 占位符圆角矩形
     */
    fun ImageView.loadRound(url: String) {
        get(url).placeholder(R.drawable.shape_default_round_bg)
                .error(R.drawable.shape_default_round_bg)
//            .apply(RequestOptions.bitmapTransform(RoundedCornersTransformation(DisplayUtil.dp2px(context, 6f), 0)))
                .transform(RoundedCornersTransformation(DisplayUtil.dp2px(context, 6f), 0))
                .into(this)
    }

    /**
     * 占位符圆形
     */
    fun ImageView.loadCircle(url:Drawable) {
        get(url).placeholder(R.drawable.shape_default_circle_bg)
                .error(R.drawable.shape_default_circle_bg)
                .into(this)
    }

    fun ImageView.loadCircle(url: String) {
        get(url).placeholder(R.drawable.shape_default_circle_bg)
                .error(R.drawable.shape_default_circle_bg)
                .into(this)
    }

    fun ImageView.get(url: String): GlideRequest = GlideApp.with(context).load(url)
    fun ImageView.get(url: Drawable): GlideRequest = GlideApp.with(context).load(url)
fun Context.toast(str: String) = Toast.makeText(this, str, Toast.LENGTH_LONG).show()

// 当我们需要toast的时候,我们可以这样调用

context.toast("test")

说到扩展函数,就不得不提的几个基础库的扩展函数,也叫做作用域函数,它们是:

T.run、T.let、T.also、T.apply 以及run、width两个函数。对于这几个函数的使用刚开始的时候我还是很懵逼的,只是大概了解用法,以及带来的链式调用的便捷

二.尾随闭包

一开始我并不了解这个概念。偶然间我看到我们的小伙伴在使用RxBus时,写下了这样的代码:

 

RxBus.get().register(LogoutEvent::class.java) { refresh() }

当时我感觉很疑惑,因为RxBus是我写的,记得没有提供这样的方法啊。点击register()方法进去看之后,发现register是这样的:

 

    public  Disposable register(Class eventType, Consumer onNext) {
        return toObservable(eventType).observeOn(AndroidSchedulers.mainThread()).subscribe(onNext);
    }

由于register()最后一个参数是一个方法或者说是一个闭包,可以把方法或者闭包提到最外面。变成项目中看到的样子

RxBus.get().register(LogoutEvent::class.java) { refresh() }

这就是尾随闭包,可以让代码看起来更加简洁。

三.with的用法

with是将某个对象作为函数的参数,在函数块内可以通过 this 指代该对象。在函数块内可以直接调用对象的方法或者属性。

 

/**
 * Calls the specified function [block] with the given [receiver] as its receiver and returns its result.
 */
@kotlin.internal.InlineOnly
public inline fun  with(receiver: T, block: T.() -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return receiver.block()
}
class AppPublisherAdapter : BaseAdapter() {

    override fun getLayoutId(viewType: Int): Int = R.layout.cell_app_publisher

    override fun onBindViewHolderImpl(holder: BaseViewHolder, position: Int,content: BoundAppInfoResponse.AppInfo) {
        holder.itemView.tv_game_name.text = content.name

        if (content.is_bound) {
            holder.itemView.tv_bound_user_name.text = content.bound_user_name
            holder.itemView.tv_bound_user_name.setTextColor(context.resources.getColor(R.color.color_bound_user_name))
        } else {
            holder.itemView.tv_bound_user_name.text = context.getString(R.string.bind_on_account)
            holder.itemView.tv_bound_user_name.setTextColor(context.resources.getColor(R.color.color_bind_on_account))
        }
        holder.itemView.iv_game_icon.load(content.logo_url)
    }
}

使用with之后,该函数块可以省略"content."

 

 

class AppPublisherAdapter : BaseAdapter() {

    override fun getLayoutId(viewType: Int): Int = R.layout.cell_app_publisher

    override fun onBindViewHolderImpl(holder: BaseViewHolder, position: Int, content: BoundAppInfoResponse.AppInfo) {

        with(content) {
            holder.itemView.tv_game_name.text = name

            if (is_bound) {
                holder.itemView.tv_bound_user_name.text = bound_user_name
                holder.itemView.tv_bound_user_name.setTextColor(context.color(R.color.color_bound_user_name))
            } else {
                holder.itemView.tv_bound_user_name.text = context.string(R.string.bind_on_account)
                holder.itemView.tv_bound_user_name.setTextColor(context.color(R.color.color_bind_on_account))
            }
            holder.itemView.iv_game_icon.load(logo_url)
        }
    }
}

告别findViewById

kotlin-android-extensions相当于DataBinding,同样的目的为了偷懒不用写findViewByIdAndroid 开发必备。

如果使用了kotlin-android-extensions,不使用findviewfindid操作一定要在对应的kotlin文件里导入:

inline(内联)、infix(中缀)、高阶函数

 

DSL-Anko布局

 

 

 

你可能感兴趣的:(kotlin,android,性能优化)