Kotlin有效地开发了 Android 应用程序 (5)
1。 Singleton
如果使用 Java 编写单例模式,则可以编写多种类型。同样,可以使用 Kotlin 编写几个简单的模式。这是一种使用委托属性来实现单例类型的方法。
首先,Kotlin在语法层面支持授权模式。
委托模式是软件设计模式中的一项基本技术。在委托模式中,两个对象参与处理同一个请求,接收请求的对象将请求委托给另一个对象处理。委托模式是一种基本技术,许多其他模式如状态模式、策略模式、访问者模式在特殊场合本质上都会使用委托模式。委托模式允许我们使用聚合而不是继承。
对于一些非常常见的属性,虽然我们可以在需要时手动实现它们,但更好的方法是一次性实现它们并将它们放入库中。也就是说,它的属性值操作不再依赖于自己的getter()/setter()方法,而是委托给代理类,这样就可以通过代理类的管理来统一各个使用类中的属性。这样,就是
的委托属性。
Kotlin的标准库中有几个默认委托,非空属性就是其中之一。它将包含一个具有空值的变量,并且在设置此属性时将被分配一个真值。如果加载前未赋值,则会抛出异常。
当然,即使是懒人也可以实现单例。下面我们使用非空委托来实现单个应用程序。
class App : Application() {
companion object {
var instance: App by Delegates.notNull()
}
override fun onCreate() {
super.onCreate()
instance = this
}
}
复制代码
2。封装Extras
使用ExtrasDelegate封装Extras
import android.support.v4.app.Fragment
import android.support.v7.app.AppCompatActivity
import kotlin.reflect.KProperty
/**
*
* @FileName:
* com.safframework.delegate.extras.Extras.kt
* @author: Tony Shen
* @date: 2018-06-11 23:56
* @version V1.0 <描述当前版本功能>
*/
class ExtrasDelegate<out T>(private val extraName: String, private val defaultValue: T) {
private var extra: T? = null
operator fun getValue(thisRef: AppCompatActivity, property: KProperty<*>): T {
extra = getExtra(extra, extraName, thisRef)
return extra ?: defaultValue
}
operator fun getValue(thisRef: Fragment, property: KProperty<*>): T {
extra = getExtra(extra, extraName, thisRef)
return extra ?: defaultValue
}
}
fun <T> extraDelegate(extra: String, default: T) = ExtrasDelegate(extra, default)
fun extraDelegate(extra: String) = extraDelegate(extra, null)
@Suppress("UNCHECKED_CAST")
private fun <T> getExtra(oldExtra: T?, extraName: String, thisRef: AppCompatActivity): T? =
oldExtra ?: thisRef.intent?.extras?.get(extraName) as T?
@Suppress("UNCHECKED_CAST")
private fun <T> getExtra(oldExtra: T?, extraName: String, thisRef: Fragment): T? =
oldExtra ?: thisRef.arguments?.get(extraName) as T?
复制代码
封装后在MainActivity中传递参数,传递给其他Activity。
import android.content.Intent
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import com.safframework.delegate.R
import com.safframework.delegate.domain.User
import com.safframework.ext.click
import kotlinx.android.synthetic.main.activity_main.*
/**
*
* @FileName:
* com.safframework.delegate.activity.MainActivity.java
* @author: Tony Shen
* @date: 2018-06-13 12:03
* @version V1.0 <描述当前版本功能>
*/
class MainActivity:AppCompatActivity() {
public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initViews()
}
private fun initViews() {
text1.click{
val intent = Intent(this@MainActivity, Demo4ExtrasDelegateActivity::class.java)
val u = User("Tony","123456")
intent.putExtra("user",u)
intent.putExtra("string","just a test")
startActivity(intent)
}
text2.click {
val intent = Intent(this@MainActivity, Demo4PrefsDelegateActivity::class.java)
startActivity(intent)
}
}
}
复制代码
点击功能在《使用Kotlin高效开发Android应用(二)》中已经介绍过,这里不再赘述。
Demo4ExtrasDelegateActivity 接受从 MainActivity 传递的参数。对于每种通过
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import com.safframework.delegate.domain.User
import com.safframework.delegate.extras.extraDelegate
import com.safframework.log.L
/**
*
* @FileName:
* com.safframework.delegate.activity.Demo4ExtrasDelegateActivity.java
* @author: Tony Shen
* @date: 2018-06-13 17:42
* @version V1.0 <描述当前版本功能>
*/
class Demo4ExtrasDelegateActivity: AppCompatActivity() {
private val user: User? by extraDelegate("user")
private val s:String? by extraDelegate("string")
public override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
L.json(user)
L.i(s)
}
}
复制代码
的物体,您都可以使用以下方法获得额外的奖励。只需确保额外的密钥正确即可。
private val user: User? by extraDelegate("user")
private val s:String? by extraDelegate("string")
复制代码
与 Extra 一样,SharedPreferences 也可以使用属性委托进行封装。
3。中缀
中缀表达式是表达算术或逻辑公式的通用方法。运算符以中缀的形式位于操作数的中间。中缀表达式允许我们使用单词或字母作为运算符(其本质仍然是函数调用),而忽略调用句点和括号。
Kotlin 的中缀表达式必须满足以下条件:
- 使用中缀修饰
- 只有一个参数
- 其参数不能接受可变数量的参数,并且不能有默认值。
例如:
infix fun Int.add(i:Int):Int = this + i
infix fun Int.加(i:Int):Int = this + i
fun main(args: Array<String>) {
println(5 add 10)
println(5 加 10)
}
复制代码
执行结果:
15
15
复制代码
在Kotlin中,使用中缀表达式最经典的例子就是使用kxdate来控制日期。 kxdate github地址:https://github.com/yole/kxdate
val twoMonthsLater = 2.months.fromNow
val yesterday = 1.days.ago
复制代码
相当于:
val twoMonthsLater = 2 months fromNow
val yesterday = 1 days ago
复制代码
可见,中缀表达式可以让代码更接近自然语言。
4。 inline
Kotlin 天然支持函数式编程,其主要特性之一就是高阶函数和 lambda。
使用高阶函数会带来一些运行效率的损失:每个函数都是一个对象,捕获一个闭包。也就是说,那些将在函数体内访问的变量。内存分配(对于函数对象和类)和虚拟调用代表运行时开销。
使用内联修饰函数,可以从编译器的角度将函数体复制到调用页面中,从而实现内联。 ***
在许多情况下,可以通过在使用的地方插入 Lambda 表达式来消除运行时开销。
当你查看Kotlin的standard.kt时,你会发现所有函数with、use、run、let等。他们使用内联。
另一个例子,扩展 Closeable 以支持 Java 函数try-with-resources
。
inline fun <T : Closeable?, R> T.use(block: (T) -> R): R {
var closed = false
try {
return block(this)
} catch (e: Exception) {
closed = true
try {
this?.close()
} catch (closeException: Exception) {
}
throw e
} finally {
if (!closed) {
this?.close()
}
}
}
复制代码
这个方法已经在https://github.com/fengzhizi715/SAF-Kotlin-Utils
总结
本文是该系列的最后一篇文章。未来,碎片化的开发细节将不会得到解决。它将被系统地组织起来。
作者:Tony沈哲
链接:https://juejin.im/post/5b30de416fb9a00e9c47de55
来源:掘金。商业转载请联系作者获取授权。非商业转载请注明出处。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。