Kotlin初体验

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 距离kotlin成为Android一级开发语言已经一年了,这节将从零开始,实现kotlin的几个小知识点。以下操作是在AndroidStudio3.0.

距离kotlin成为Android一级开发语言已经一年了,这节将从零开始,实现kotlin的几个小知识点。

以下操作是在AndroidStudio3.0.1下完成的,如果是3.0以下版本的AndroidStudio,需要安装好kotlin插件才能使用Kotlin进行开发

Kotlin教程推荐

官网文档黑马教程《Kotlin for android developers》中文版翻译

相关代码已经上传到Github的KotlinPractice文件夹下了

创建项目:

在创建项目中勾选kolin支持后直接下一步即可

img_8df73b8300c793f926bb5834b6a0661e.png
勾选kotlin支持

创建完项目后我们发现主类已经是使用了kotlin代码了,我们去project的build.gradle目录下可以看到

ext.kotlin_version = '1.1.51' kotlin  //版本号 
dependencies {
    classpath 'com.android.tools.build:gradle:3.0.1'
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"//依赖
}

以及module下build.gradle的:

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'  

实际上这就是我们刚才勾选kotlin后给我们自动生成的,如果我们想要在现有Java代码项目中使用kotlin,那么我们就需要手动的去添加这些依赖,或者使用方便的java代码转kotlin来进行配置,我们看到MainActivity默认已经是kotlin类了


/**
 *  : AppCompatActivity() 
 *  :类名,表示继承于AppCompatActivity类
 */
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}

为TextView控件赋值:

我们在布局从添加一个TextView,id命名为text_01

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="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"
    tools:context="com.example.administrator.kotlin.MainActivity">

    <TextView
        android:id="@+id/txt_01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="测试文本" />

</LinearLayout>

回到Activity,在activity的导包中添加这一行

import kotlinx.android.synthetic.main.activity_main.*

它的作用现在只要知道添加了这一行后我们就不需要再findViewById就可以了,activity_main的意思是Activity布局的包名。

import kotlinx.android.synthetic.main.activity_main.*
/**
 *  : AppCompatActivity() :类名,表示继承与什么类
 */
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
//      为TextView设置值,koltin的语句后面是不需要;的,但是如果你加上也不会报错的
        txt_01.setText("你好,世界")
    }
}

运行程序,确实和我们想要的是一样的

设置按钮点击事件

我们再为布局添加3个button按钮

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="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.administrator.kotlin.MainActivity">

    <TextView
        android:id="@+id/txt_01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="测试文本" />

    
    <Button
        android:id="@+id/btn_01"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" 
        android:text="按钮1"
        />

    <Button
        android:id="@+id/btn_02"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="按钮2"
        />

    <Button
        android:id="@+id/btn_03"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="按钮3"
        />
</LinearLayout>

回到Activity,让MainActivity类继承于View.OnClickListener接口,我们可以看到koltin继承接口是使用,号进行的,如果我们想要继承多个接口,只需要使用多个,分隔开来就行了

/**
 *  : AppCompatActivity() :类名,表示继承于什么类
 *  ,View.OnClickListener, View.OnLongClickListener 表示继承于 View.OnClickListener 点击事件接口, View.OnLongClickListener 长按事件接口
 */
class MainActivity : AppCompatActivity(), View.OnClickListener, View.OnLongClickListener {


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
//      为TextView设置值,koltin的语句后面是不需要;的,但是如果你加上也不会报错的
        txt_01.setText("你好,世界")
    }

    /**
     * 重写OnClickListener接口的onClick方法
     */
    override fun onClick(p0: View?) {
        
    }

    /**
     * 重写OnLongClickListener接口的onLongClick方法
     */
    override fun onLongClick(p0: View?): Boolean {
        return false
    }

}

然后就是我们熟悉的在点击事件里面使用switch找到对应控件的id了,只是在kotlin里面是使用when

/**
 * 重写OnClickListener接口的onClick方法
 */
override fun onClick(p0: View?) {
    when (p0!!.id) {
        R.id.btn_01 -> {
            Toast.makeText(this, "按钮1", Toast.LENGTH_LONG).show()
        }

        R.id.btn_02 -> {
            Toast.makeText(this, "按钮2", Toast.LENGTH_LONG).show()
        }

        R.id.btn_03 -> {
            Toast.makeText(this, "按钮3", Toast.LENGTH_LONG).show()
        }
    }
}

最后要注意,虽然我们通过import kotlinx.android.synthetic.main.activity_main.*使得不需要写控件的fndId,但是我们仍然是要写setOnClickListener(this)控件点击回调监听的

完整代码:

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.*

/**
 *  : AppCompatActivity() :类名,表示继承与什么类
 */
class MainActivity : AppCompatActivity(), View.OnClickListener, View.OnLongClickListener {


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
//      为TextView设置值,koltin的语句后面是不需要;的,但是如果你加上也不会报错的
        txt_01.setText("你好,世界")
//       设置控件的回调监听
        init()
    }

    /**
     *  设置控件的回调监听
     */
    private fun init() {
        btn_01.setOnClickListener(this)
        btn_02.setOnClickListener(this)
        btn_03.setOnClickListener(this)
    }

    /**
     * 重写OnClickListener接口的onClick方法
     */
    override fun onClick(p0: View?) {
        when (p0!!.id) {
            R.id.btn_01 -> {
                Toast.makeText(this, "按钮1", Toast.LENGTH_LONG).show()
            }

            R.id.btn_02 -> {
                Toast.makeText(this, "按钮2", Toast.LENGTH_LONG).show()
            }

            R.id.btn_03 -> {
                Toast.makeText(this, "按钮3", Toast.LENGTH_LONG).show()
            }
        }
    }

    /**
     * 重写OnLongClickListener接口的onLongClick方法
     */
    override fun onLongClick(p0: View?): Boolean {
        return false
    }

}

运行程序点击按钮后,出现了我们想要的吐司

实现网络请求

开始之前我们先在module下配置anko依赖,这是为了等下线程调度用的

module:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'

//    kotlin插件anko
    implementation "org.jetbrains.anko:anko-common:0.10.4"
 

}

然后实现我们的network()请求网络方法,最后不要忘了在AndroidManifest.xml下添加网络权限

<uses-permission android:name="android.permission.INTERNET" />
   /**
     * 重写OnClickListener接口的onClick方法
     */
    override fun onClick(p0: View?) {
        when (p0!!.id) {
            R.id.btn_01 -> {
//              只进行网络请求
                network();
            }

            R.id.btn_02 -> {
//              进行网路请求,并且进行json数据解析
                Toast.makeText(this, "按钮2", Toast.LENGTH_LONG).show()
            }

            R.id.btn_03 -> {
                Toast.makeText(this, "按钮3", Toast.LENGTH_LONG).show()
            }
        }
    }
    /**
     * 网络请求
     */
    private fun network() {
//       声明要请求的网址,在kotlin中,var能声明一切类型,而后面的:String其实是可以不加的
        var string: String = "http://www.wanandroid.com/tools/mockapi/2872/k1"
//        作用类似java在子线程中进行网络请求,但是async在kotlin中叫做协程
        async() {
            val fore = URL(string).readText()
            Log.d("tonjies", fore)
        }

    }

观察日志,我们可以看到确实已经获取了Json数据

img_cebac371fc82cf5eed1d358934a75093.png
这里写图片描述

Json数据解析

接下来我们进行json数据的解析,首先添加gson解析依赖

//    goso解析
    compile "com.google.code.gson:gson:2.4"

我们创建bean实体类包,在包下创建解析实体类Student,我们不需要像Java那样去生成get和set对象,因为这kotlin已经帮我们生成好啦!

/**
 * Created by 舍长 on 2018/4/28.
 * 描述: 数据请求实体类
 */
class Student {
    var name:String?=null
    var age:String?=null
}

在按钮2的点击事件里面写一个gson方法,在gson方法里将网络请求到的数据转换成实体类,并且回到UI线程,显示在文字控件上

   /**
     * 重写OnClickListener接口的onClick方法
     */
    override fun onClick(p0: View?) {
        when (p0!!.id) {
            R.id.btn_01 -> {
//              只进行网络请求
                network();
            }

            R.id.btn_02 -> {
//              进行网路请求,并且进行json数据解析
                Toast.makeText(this, "按钮2", Toast.LENGTH_LONG).show()
                gson();
            }

            R.id.btn_03 -> {
                Toast.makeText(this, "按钮3", Toast.LENGTH_LONG).show()
            }
        }
    }

    /**
     * 网络请求并使用gson解析数据
     */
    private fun gson() {
//       声明要请求的网址,在kotlin中,var能声明一切类型,而后面的:String其实是可以不加的
        var string: String = "http://www.wanandroid.com/tools/mockapi/2872/student"
//        作用类似java在子线程中进行网络请求,但是async在kotlin中叫做协程
        async() {
            val fore = URL(string).readText()
            var fromJson: Student = Gson().fromJson(fore, Student::class.java)
//           回到UI线程中去更新数据,这里的${属性名}是字符串模板,作用于Java的+属性名+相同
            uiThread {
                txt_01.setText("学生的名字是${fromJson.name},年龄是${fromJson.age}")
            }
        }
    }

运行程序,点击按钮二,可以看到文字确实变成了我们想要的json数据:学习的名字是tonjies,年龄是18

这一小节的完整代码:

布局文件activity_main:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="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.administrator.kotlin.MainActivity">

    <TextView
        android:id="@+id/txt_01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="测试文本" />


    <Button
        android:id="@+id/btn_01"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="按钮1"
        />

    <Button
        android:id="@+id/btn_02"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="按钮2"
        />

    <Button
        android:id="@+id/btn_03"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="按钮3"
        />
</LinearLayout>

MainActivity

package com.example.administrator.kotlin

import android.icu.lang.UCharacter.GraphemeClusterBreak.L
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Toast
import com.example.administrator.kotlin.R.id.async
import com.example.administrator.kotlin.bean.Student
import com.google.gson.Gson

import kotlinx.android.synthetic.main.activity_main.*
import java.net.URL
import org.jetbrains.anko.custom.async
import org.jetbrains.anko.uiThread

/**
 *  : AppCompatActivity() :类名,表示继承与什么类
 */
class MainActivity : AppCompatActivity(), View.OnClickListener, View.OnLongClickListener {


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
//      为TextView设置值,koltin的语句后面是不需要;的,但是如果你加上也不会报错的
        txt_01.setText("你好,世界")
//       设置控件的回调监听
        init()
    }

    /**
     *  设置控件的回调监听
     */
    private fun init() {
        btn_01.setOnClickListener(this)
        btn_02.setOnClickListener(this)
        btn_03.setOnClickListener(this)
    }

    /**
     * 重写OnClickListener接口的onClick方法
     */
    override fun onClick(p0: View?) {
        when (p0!!.id) {
            R.id.btn_01 -> {
//              只进行网络请求
                network();
            }

            R.id.btn_02 -> {
//              进行网路请求,并且进行json数据解析
                Toast.makeText(this, "按钮2", Toast.LENGTH_LONG).show()
                gson();
            }

            R.id.btn_03 -> {
                Toast.makeText(this, "按钮3", Toast.LENGTH_LONG).show()
            }
        }
    }

    /**
     * 网络请求并使用gson解析数据
     */
    private fun gson() {
//       声明要请求的网址,在kotlin中,var能声明一切类型,而后面的:String其实是可以不加的
        var string: String = "http://www.wanandroid.com/tools/mockapi/2872/student"
//        作用类似java在子线程中进行网络请求,但是async在kotlin中叫做协程
        async() {
            val fore = URL(string).readText()
            var fromJson: Student = Gson().fromJson(fore, Student::class.java)
//           回到UI线程中去更新数据,这里的${属性名}是字符串模板,作用于Java的+属性名+相同
            uiThread {
                txt_01.setText("学生的名字是${fromJson.name},年龄是${fromJson.age}")
            }
        }
    }

    /**
     * 网络请求
     */
    private fun network() {
//       声明要请求的网址,在kotlin中,var能声明一切类型,而后面的:String其实是可以不加的
        var string: String = "http://www.wanandroid.com/tools/mockapi/2872/student"
//        作用类似java在子线程中进行网络请求,但是async在kotlin中叫做协程
        async() {
            val fore = URL(string).readText()
            Log.d("tonjies", fore)
        }

    }

    /**
     * 重写OnLongClickListener接口的onLongClick方法
     */
    override fun onLongClick(p0: View?): Boolean {
        return false
    }

}

好了,这一小节就到这里啦!在学习的过程中,参考开源项目和巧妙使用Java代码转kotlin的快捷键是挺有用的

目录
相关文章
|
开发者 Kotlin
抽丝剥茧聊Kotlin协程之Job初体验
抽丝剥茧聊Kotlin协程之Job初体验
抽丝剥茧聊Kotlin协程之Job初体验
|
Java Android开发 Kotlin
使用Kotlin开发Android应用初体验
使用Kotlin开发Android应用初体验 昨晚,最近一届的谷歌IO大会正式将Kotlin确定为了官方开发语言,作为一名Android开发鸟,怎么能不及时尝尝鲜呢? Kotlin的简要介绍 在开发之前,很多同学一定有很多疑问,Kotlin到底有啥好处,怎么和现有的项目共存呢?Java那么些特性Kotlin都有吗?嗯,让我们一一来看。
1550 0
|
2月前
|
JSON 调度 数据库
Android面试之5个Kotlin深度面试题:协程、密封类和高阶函数
本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点。文章详细解析了Kotlin中的协程、扩展函数、高阶函数、密封类及`inline`和`reified`关键字在Android开发中的应用,帮助读者更好地理解和使用这些特性。
30 1
|
3月前
|
Android开发 开发者 Kotlin
告别AsyncTask:一招教你用Kotlin协程重构Android应用,流畅度飙升的秘密武器
【9月更文挑战第13天】随着Android应用复杂度的增加,有效管理异步任务成为关键。Kotlin协程提供了一种优雅的并发操作处理方式,使异步编程更简单直观。本文通过具体示例介绍如何使用Kotlin协程优化Android应用性能,包括网络数据加载和UI更新。首先需在`build.gradle`中添加coroutines依赖。接着,通过定义挂起函数执行网络请求,并在`ViewModel`中使用`viewModelScope`启动协程,结合`Dispatchers.Main`更新UI,避免内存泄漏。使用协程不仅简化代码,还提升了程序健壮性。
92 1
|
4月前
|
调度 Android开发 开发者
【颠覆传统!】Kotlin协程魔法:解锁Android应用极速体验,带你领略多线程优化的无限魅力!
【8月更文挑战第12天】多线程对现代Android应用至关重要,能显著提升性能与体验。本文探讨Kotlin中的高效多线程实践。首先,理解主线程(UI线程)的角色,避免阻塞它。Kotlin协程作为轻量级线程,简化异步编程。示例展示了如何使用`kotlinx.coroutines`库创建协程,执行后台任务而不影响UI。此外,通过协程与Retrofit结合,实现了网络数据的异步加载,并安全地更新UI。协程不仅提高代码可读性,还能确保程序高效运行,不阻塞主线程,是构建高性能Android应用的关键。
63 4
|
5月前
|
安全 Android开发 Kotlin
Android经典面试题之Kotlin延迟初始化的by lazy和lateinit有什么区别?
**Kotlin中的`by lazy`和`lateinit`都是延迟初始化技术。`by lazy`用于只读属性,线程安全,首次访问时初始化;`lateinit`用于可变属性,需手动初始化,非线程安全。`by lazy`支持线程安全模式选择,而`lateinit`适用于构造函数后初始化。选择依赖于属性特性和使用场景。**
168 5
Android经典面试题之Kotlin延迟初始化的by lazy和lateinit有什么区别?
|
5月前
|
安全 Android开发 Kotlin
Android经典面试题之Kotlin中常见作用域函数
**Kotlin作用域函数概览**: `let`, `run`, `with`, `apply`, `also`. `let`安全调用并返回结果; `run`在上下文中执行代码并返回结果; `with`执行代码块,返回结果; `apply`配置对象后返回自身; `also`附加操作后返回自身
62 8
|
5月前
|
安全 Java Android开发
探索Android应用开发中的Kotlin语言
【7月更文挑战第19天】在移动应用开发的浩瀚宇宙中,Kotlin这颗新星以其简洁、安全与现代化的特性,正迅速在Android开发者之间获得青睐。从基本的语法结构到高级的编程技巧,本文将引导读者穿梭于Kotlin的世界,揭示其如何优化Android应用的开发流程并提升代码的可读性与维护性。我们将一起探究Kotlin的核心概念,包括它的数据类型、类和接口、可见性修饰符以及高阶函数等特性,并了解这些特性是如何在实际项目中得以应用的。无论你是刚入门的新手还是寻求进阶的开发者,这篇文章都将为你提供有价值的见解和实践指导。
|
5月前
|
SQL 安全 Java
Android经典面试题之Kotlin中object关键字实现的是什么类型的单例模式?原理是什么?怎么实现双重检验锁单例模式?
Kotlin 单例模式概览 在 Kotlin 中,`object` 关键字轻松实现单例,提供线程安全的“饿汉式”单例。例如: 要延迟初始化,可使用 `companion object` 和 `lazy` 委托: 对于参数化的线程安全单例,结合 `@Volatile` 和 `synchronized`
65 6
|
5月前
|
存储 前端开发 测试技术
Android Kotlin中使用 LiveData、ViewModel快速实现MVVM模式
使用Kotlin实现MVVM模式是Android开发的现代实践。该模式分离UI和业务逻辑,借助LiveData、ViewModel和DataBinding增强代码可维护性。步骤包括创建Model层处理数据,ViewModel层作为数据桥梁,以及View层展示UI。添加相关依赖后,Model类存储数据,ViewModel类通过LiveData管理变化,而View层使用DataBinding实时更新UI。这种架构提升代码可测试性和模块化。
195 2