在不久前Google io开发者大会上面,Google突然发出大招–Kotlin成为Android开发的官方语言。一夜间,大多数全球的Android开发者们一脸懵逼,绝大多数人之前压根不知道Kotlin是个什么东西。而这就意味着,在之后的Android项目开发中将逐步从Java语言转变为Kotlin语言,而在以后新增的代码文件将不再以Java代码的形式出现,而是以 Kotlin 代码格式出现,与此同时,之前老的 Java 代码也将会陆陆续续被翻译成 Kotlin 代码。使用Kotlin语言开发Android项目的时代已经到来,本文就将从以下几个方面浅析一下这异军突起的Android官方新语言:
Kotlin是由一家位于捷克布拉格的软件开发公司JetBrains开发的基于JVM的一种语言。众所周知,该公司研发了IntelliJ IDEA这款相对于Eclipse有较大改善的大名鼎鼎IDE产品而闻名,之前有使用Java语言开发的程序猿对此应该是比较了解的。Kotlin最开始是使用Java开发者的思维被创建的,而Intellij则是作为它最主要的开发IDE。
而对于当前所有的Android开发者而言,有两个福音:
在Kotlin被列为Android官方语言后,很多之前一直使用Java语言开发项目的程序猿开始担心自己没有办法迅速的学习新的一门语言,并且快速的投入到实战中去。事实上,并不需要有这样的担心。尽管是已经习惯了使用Java来开发Android应用程序的开发者也不用担心,因为Java和Kotlin之间代码是可以共存的,而且更为便利的是他们之间可以相互调用,除此以外Google官方还提供了如何将Java代码转换为Kotlin代码的功能,是不是很贴心呢。
Kotlin是一种兼容Java的语言,相比于Java语言,Kotlin主要在一下几个方面具有优势:
总而言之,相比于Java有的功能,Kotlin基本上都有,而且两者之间的性能理论上是一样的,而Kotlin在一些方面则要优于Java。
易表现(简洁性)
使用Kotlin对我们来说可以更轻易地避免模版式代码,因为大部分的典型情况都在语言中默认覆盖实现了。
举个最简单的例子,在Java中,get/set方法自动转换成属性,对应到Kotlin属性的调用。
在Java中,我们输入下段代码:
public class User {
private int id;
private String name;
public void setId(int id) {
this. id = id;
}
public void setName(String name) {
this. name=name;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
}
说白了,上述代码就只有两个字段,一个是id,一个是name,如果我们用Kotlin来写如下:
data class User(var name: String, var id: String)
十来行变一行,有木有!!!
不仅如此,Kotlin还会自动生成所有属性和它们的访问器,以及一些方法,例如toString方法及equals方法。
var user = User("lcjingsi","0823")
空安全性
如果我们不需要参数或者只需要一个参数时
class User {
var name: String? = null
var id: String? = null
constructor(name: String) {
this.name = name
}
constructor(name: String, id: String) {
this.name = name
this.id = id
}
}
看到这里,有人会问了。String?=null 是什么意思
其实这就是我们上面所提到的Kotlin所具有的空安全性。当我们用Java写代码时,我们如果不想出现NullPointerException,那就需要我们每次在使用它之前去判断是否为空。而这个问题在 Kotlin语言中得到了很好的解决。
// 这里不能通过编译,因为User不能是null
var notNullUser: User = null
// User可以是 null
var User: User? = null
// 无法编译,因为User可能是null,我们需要进行处理
artist.print()
// 只有在User != null时才会打印
User?.print()
// 如果我们在之前进行了空检查,则不需要使用安全调用操作符调用
if (User != null) {
User.print()
}
// 只有在确保User不是null的情况下才能这么调用,否则它会抛出异常
User!!.print()
// 使用Elvis操作符来给定一个在是null的情况下的替代值
val name = User?.name ?: "empty"
就比如这段代码,如果user是可能为空的,而user没对空情况做处理,则无法编译。
我们再举个实际的例子:
Java
public void test(String string)
{
if (string != null){
char[]chars = string.toCharArray();
if (chars.length>10){
System.out.println(((Character)chars[10]).hashCode());
}
}
}
Kotlin
fun testNullSafeOperator(string:String?){
System.out.println(string?.toCharArray()?.getOrNull(10)?.hashCode());
}
testNullSafeOperator(null)
testNullSafeOperator("15659766728")
testNullSafeOperator("158")
//result
null
49
null
一眼可以看出,相对于Java繁琐的判断而言,Kotlin几乎是一行代码解决问题的。
易拓展性
易拓展性就是说在Kotlin中,我们可以给任何类添加函数和方法,包括系统类以及自定义的类,这样会使得我们比项目中原本拥有的典型的工具类来的更加具有可读性。比如,我们想要在User类中添加一个toast方法:
Java
public static void toast(User user,String message){
Toast.makeText(user,message,Toast.LENGTH_LONG).show();
}
Kotlin
fun User.toast(message: CharSequence, duration: Int = Toast.LENGTH_SHORT) {
Toast.makeText(this, message, duration).show()
}
User.toast("Hello world!")
当我们加上这段代码之后,就可以在所有用得到User的地方调用User.toast()方法。即我们只需要重写扩展方法就可以了,不过需要注意的是,如果拓展方法写到类中,只能在该类生效。
函数式
Kotlin是一种基于面向对象的语言,但是就如其他很多现代的语言一样,它使用了很多函数式编程的概念,比如使用lambda表达式来更方便地解决问题。
我们来举个简单的例子:
大家对于Android开发中经常会使用到的点击事件应该并不陌生,之前我们是这样来写的
view.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
Toast.makeText(v.getContext(), "Click", Toast.LENGTH_SHORT).show();
}
})
利用刚才我们所学习到的Kotlin语言的拓展性,我们可以改写成如下形式
view.setOnClickListener(object : OnClickListener {
override fun onClick(v: View) {
toast("Click")
}
}
而利用lambdas表达式我们就可以把上述代码再次优化
view.setOnClickListener({view -> toast("Click")})
考虑到很多情况下我们并不需要用到参数View,所以左值参数也可以省略,考虑到只有一个参数,可以将大括号去除,于是就有了
view.setOnClickListener{toast("Click")}
比起最初的Java代码简化了差不多五倍以上,是不是很简洁,而且也特别容易理解。
Kotlin Android Extention
这个对于每一个Android应用程序开发者来说算得上是最大的福利了。也是强势推荐使用Kotlin语言来开发Android项目的重要原因。为什么这么说呢?在以往的Android开发中,大家应该都能够明显发现findViewById()是一个比较让人抓狂的函数,尽管开源界已经有几个库提供了解决办法,比如:ButterKnife,DataBinding等,但我们还是被困在这个findViewById这个让人又爱又恨的函数中。而Kotlin则是提供了一个解决该问题最简单的方法——Kotlin Android Extensions。
Kotlin Android Extensions是Kotlin的一个插件,它包含在普通的那个插件中,允许以惊人的无缝方式从Activitie,Fragment和View中恢复View,不用增加额外的代码,直接使用xml中定义的android:id就可以引用view,就像它们是在布局中定义的属性一样,你可以使用 id 的名称。除此以外它还构建本地视图缓存,因此当我们首次使用一个属性时,它会做一个普通的findViewById,而接下来,View则是从缓存中恢复,使得访问速度更快。
举个例子:
这是一个布局文件
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
android.support.constraint.ConstraintLayout>
下面我们用两种方式写MainActivity。
class MainActivity : AppCompatActivity() {
private var mTextMessage: TextView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mTextMessage = findViewById(R.id.message) as TextView
mTextMessage!!.setText("Hello jingsi")
}
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
private var mTextMessage: TextView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
message.setText("Hello jingsi");
}
具体配置方法可参考:Kotlin编程之Kotlin Android Extensions(扩展插件)
了解到一些基础的Kotlin语言的语法和特性后,那么我们该如何在Android Studio中使用Kotlin呢?
首先我们需要下载Kotlin插件(以Android Studio 3.1.2版本为例)
点击File->Settings->Plugins 可以在已支持的插件中找到Kotlin(貌似Android Studio 3.1.2版本 是自带Kotlin插件的)
如果使用的是老版本的Android Studio没有该插件 那么点击Install JetBrains plugins 然后在搜索栏中输入Kotlin进行搜索找到Kotlin 点击右边的Install按钮 下载完成后 Restart Android Studio即可
重新打开Android Studio后点击File->New 可以看到新出现的Kotlin File/Class按钮,然后点击(本来应该还有个Kotlin Activity,奈何找了很多办法也没有显示出来 好在影响不大)
点击OK,然后你会发现Android Studio自动打开了build.gradle文件,并且在头部多出了一行Kotlin的配置代码,build.gradle文件有变动,我们重新编译下项目,这时因为需要下载kotlin的相关文件,所以可能需要些时间.然后会发现project的build.gradle有了一些变化:
buildscript {
ext.kotlin_version = '1.2.50'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
然后是Module下的build.gradle:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 27
defaultConfig {
applicationId "com.example.lcjingsi.kotlindemo"
minSdkVersion 15
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
repositories {
mavenCentral()
}
下面我们用个简单的Demo来演示一下:
在开始写之前,我们在利用Kotlin的Kotlin-android-extensions插件的实用性,使得我们不用再写findViewById()代码配置很简单,首先在moudle的build.gradle文件头部加上这行代码:apply plugin: 'kotlin-android-extensions
这个时候我们需要重新编译下项目,然后打开MainActivity,在导包配置中,添加如下代码import kotlinx.android.synthetic.main.activity_main.*
然后就可以编写代码了。
下面是activity_main.xml文件
"http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.lcjingsi.myapplication.MainActivity">
然后是MainActivity
package com.example.lcjingsi.myapplication
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Toast
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity(), View.OnClickListener{
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btn1.setOnClickListener(this)
btn2.setOnClickListener(this)
btn3.setOnClickListener(this)
}
override fun onClick(v:View){
when(v?.id){
R.id.btn1 -> showToast("${btn1.text}")
R.id.btn2 -> showToast("${btn2.text}")
R.id.btn3 -> showToast("${btn3.text}")
}
}
fun showToast(str:String){
Toast.makeText(this,str,Toast.LENGTH_LONG).show();
}
}
我们在这里实现了一个点击Button弹出Toast的效果,如下
以上就是对Google官方新推出的Android应用开发新语言Kotlin的简单介绍,当然以上只是对Kotlin进行的一个最基本的阐述和一些特性,目的是方便之前使用Java开发Android应用的程序猿们快速熟悉Kotlin,如果想要深入学习请继续阅读相关资料。
Kotlin官方中文文档
Kotlin官网
Kotlin中文官网
Kotlin的gitbook网址
作者:胡静思
原文地址:https://blog.csdn.net/zuolvji1168/article/details/80721267