Kotlin
1 Kotlin介绍
1.1 Kotlin简介
- Kotlin 是一个基于 JVM 的新的编程语言,由 JetBrains 开发
- Kotlin可以编译成Java字节码,也可以编译成JavaScript,方便在没有JVM的设备上运行。
- Kotlin已正式成为Android官方支持开发语言。
1.2 为什么要使用Kotlin?
- 谷歌官宣Kotlin语言正式成功安卓开发的一级编程语言
- 语法简单,不啰嗦
- 空指针安全
- Lambda, 高阶函数,Streams API, 函数式编程支持
- 与Java交互性好,可以无缝连接
- 编译速度比java快,具体参考https://juejin.im/post/583d3879128fe1006bf2013b
1.3 Kotlin学习
- 官网文档 http://kotlinlang.org/docs/reference/
- Kotlin中文社区 http://kotlin.cn/
2 Kotlin的使用
2.1Kotlin的安装
2.1.1 Kotlin 是需要通过插件进行安装的,打开AndoridStudio的 Settings 中的 Plugin 搜索 Kotlin,点击安装,等待安装(过程会比较久),假如安装失败的话,建议到https://plugins.jetbrains.com/plugin/6954-kotlin 官网上找到最新的插件,右键复制地址使用迅雷进行下载,然后使用下图导入按钮将插件导入后重启AS即可(推荐使用该方法)
2.1.2 创建一个AS工程Project,可以看到还是一个java项目,然后选择 Code 下的 Convert Java File to Kotlin File 选项,点击后可以看到MainActivity已经转换成Kotlin写法了
g)
运行到机器上,你会发现程序崩溃了并且报了一个ClassNotFoundException异常,这时候系统会提示你进行Kotlin配置,点击 Configure,直接点击Ok
2.1.3 并且在你app的build.gradle文件中添加如下代码,添加完后你可以使用Kotlin语言进行开发了!
2.2 Kotlin的语法(列举部分)
1) 定义
在Kotlin中常量使用val声明,变量使用var声明,关键字在前面,类型以冒号:隔开在后面,也可以省略直接赋值,类型后带问号?表示可为空类型(默认空安全),带!!表示该类型一定不为空。
//空安全变量
var str : String = "hello"
val list : ArrayList<String>
val list = arrayListOf(1,2,3,4)
var str2 : String = null //编译不通过
var str3 : String? = null //允许为空
2) 条件
if…else 在kotlin正常使用,不过移除了switch用更强大的when替代,when子式可以是常量、变量、返回数值的表达式、返回Boolean值的表达式,比if else更加灵活
for (x in 0..10){
when(x){
2-> Log.d("xx","等于2")
in 1..5 -> Log.d("xx1",x.toString())
if (x > 6) 7 else 2 ->Log.d("xx3","大于6并等于7,或小于6并等于2")
}
}
打印结果print:
D/xx1: 1
D/xx: 等于2
D/xx1: 3
D/xx1: 4
D/xx1: 5
D/xx3: 大于0并等于1,或小于0并等于-1
//数组过滤
val list = arrayListOf(1, 2, 3, 4, 5)
//doubleList = [2,4,6,8,10]
val doubleList = list.map {
it * 2
}
//oddList = [1,3,5]
val oddList = list.filter{
it % 2 == 1
}
//将list挨个打印出来
list.forEach {
println(it)
}
3)循环
主要讲for循环
//for(int i=0; i<20; i++){ print(i) }
for(x in 0..20){
print(x)
}
//for(int i=0; i<list.size()-2; i++){ print(list.get(i)) }
for(i in list.size() - 2){
print(list[i])
}
val list: ArrayList<String> = ArrayList()
list.add("ss")
list.add("ss1")
list.add("ss2")
for((index,value) in list.withIndex()){
Log.d("cxx","index:$index+value+$value")
}
list.forEach {
Log.d("cxx",it)
}
4) 定义方法
//普通方法,默认返回值为void
fun test(num : String,context: Context){
Toast.makeText(context,num, Toast.LENGTH_SHORT).show()
}
//有返回值的方法 ArrayList类型
private fun initDate() : ArrayList<String>{
val list = ArrayList<String>()
for(i in 0..20){
list.add(i.toString())
}
return list
}
5) 冒号
在Kotlin中冒号:用万能来称呼绝不为过。常量变量的类型声明,函数的返回值,类的继承都需要它
//声明int类型常量
val index : Int = 1
//省略类型说明
var age = "23"
//定义有返回值的函数
fun getName() : String{
return "shownXeu"
}
//类继承
class UserList<E>() : ArrayList<E>(){
//...
}
2.3 Kotlin在Android中的一些写法
2.3.1 省去findViewById写法
在import kotlinx.android.synthetic.main.[layoutId].* 后,例如布局文件XML有一个TextView
<TextView
android:id="@+id/tv_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
在Activity中可以访问到控件
tv_message.text = "Hello World"
这样就完成了TextView的赋值
2.3.2 空安全
Kotlin的空安全设计,主要是在类型后面加?表示可空,否则就不能为null。
val anInt: Int = null // 错误
val anotherInt: Int? = null // 正确
使用时,则:
val nullable: Int? = 0
val nonNullable: Int = 2
nullable.toFloat() // 编译错误
nullable?.toFloat() // 如果null,什么都不做,否则调用toFloat
nullable!!.toFloat() // 强制转换为非空对象,并调用toFloat;如果nullable为null,抛空指针异常
nonNullable.toFloat() // 正确
2.3.3 扩展函数
- Kotlin的扩展函数功能使得我们可以为现有的类添加新的函数,实现某一具体功能
- 扩展函数是静态解析的,并未对原类添加函数或属性,对类本身没有任何影响
举个例子,拿Toast来说,安卓到处都可以用到,我们新建个kt文件,叫做ext,里面写
//length是默认参数
fun Context.toast(message : String, length : Int = Toas.LENGTH_SHORT){
Toast.makeText(this,message,length).show()
}
具体的写法是fun + 类型.函数(参数),接下来就可以直接在Activity里面直接使用toast了
2.3.4 javaBean
在java里面,我们定义一个实体,是这样的
public class User {
private String name;
private String id;
public User(String name, String id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
可以看到,两个属性而已,要写一堆代码,接下来看看kotlin的
data class User(var name:String, var id:String)
就一行代码,括号里跟着参数,也是构造器,并且不用getter setter
val user = User("shownxeu","23")
user.id = "300"
2.3.5 伴生对象
在java中,我们总把公用的方法,声明为静态方法,以便在任何地方都可以调用。但是在Kotlin中是不支持静态方法和对象的,这时候就要使用伴生对象了,伴生对象是伴随这个类声明周期的对象。
java
//创建一个伴生对象
companion object{
val USER = "USER"
fun startActivity(context: Context,user:User ){
val intent = Intent(context,SecondActivity::class.java)
intent.putExtra(USER,user)
context.startActivity(intent)
}
}
这样的话就可以在Activity.startActivity(…)进行跳转了
2.3.6 lambda表达式与监听器
kotlin中Button的点击事件可以这样简写
“`java
//kotlin
btn.setOnClickListener{
//do something
}
//其他上面的语句原本是这样,但是由于view不需要用到所以就可以直接省略
btn.setOnClickListener{
view -> view.(xxx) //do something
}
//在java中
button.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View view){
//do something
}
})
“`
Unit(kotlin的null,不过是个具体的对象)在kotlin代表无类型,在kotlin中设置监听回调
//定义无类型的监听器
var mListener : ((pos : Int) -> Unit)? = null
fun setOnItemClickListener(listener : ((pos : Int) -> Unit)){
this.mListener = listener
}
//在需要监听回调的地方执行
mListener?.invoke(position)
2.3.7 没有外部指针的内部类
刚开始学习Android的时候,很多同学都或多或少的遇到过因为内部类而引起的内存泄漏的情况吧,比如Handler就是如此,其内部持有了Activity的引用,而可能在一定情况下会引起内存泄漏。
Kotlin在这点上对于初学者是非常友好的,其内部类在默认情况下并没有持有外部类的引用,类似于Java中的静态内部类。
“`java
class Outer(){
var outer = “outer”
class Inner{
// 这里无法引用到outer,
// 因为Inner并没有持有Outer的引用
// var inner = outer
}
}
//如果内部类需要使用外部类的属性或者方法,一种是传参,还有一中就是使用inner关键字。
class Outer(){
var outer = “outer”
inner class Inner{
// 这里可以使用外部类的outer属性
var inner = outer
}
}
“`
3 踩坑
在kotlin代码中使用dataBinding,开启dataBinding的 enabled 为true,并且代码都能够生成Binding没问题,跑了一下程序,发现一直报这个错
检查了大半天才发现需要配置kapt管理插件,在项目的build.grale中加入对应的代码
编译成功后,最后才能正常运行…