美文网首页kotlin小白日记
kotlin小白日记2「工具类的封装,Anko简化吐司,空值处理

kotlin小白日记2「工具类的封装,Anko简化吐司,空值处理

作者: 唐_夏影 | 来源:发表于2018-09-16 18:48 被阅读54次

    Kotlin初体验二「kotlin框架Anko的使用,工具类的封装,空值处理」

    本篇上篇为kotlin初体验,源代码已上传至Github仓库的KotlinPractice2文件夹内

    AndroidStudio是可以直接运行Main主函数类的,创建test包,在包下创建dmeo1.kt文件,输入以下代码

    /**
     * 输入main提示输出主函数
     * 输入sout输出println
     */
    fun main(args: Array<String>) {
        println("你好,世界")
    }
    

    右键Run就可以运行主函数中的代码了

    AndroidStudio运行单个类.gif

    页面布局

    创建项目,在activity_main.xml下添加4个按钮

    <?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=".MainActivity">
    
        <Button
            android:id="@+id/btnLog"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="封装Log" />
    
        <Button
            android:id="@+id/btnToasts"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="短吐司"
            />
    
        <Button
            android:id="@+id/btnToastL"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="长吐司"
            />
    
        <Button
            android:id="@+id/btnNet"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="获取网络数据"
            />
    
    </LinearLayout>
    

    添加按钮的点击事件

    package com.example.tonjies.kotlinpractice2
    
    import android.support.v7.app.AppCompatActivity
    import android.os.Bundle
    import android.view.View
    //有了这一行后就不需要再写findById了
    import kotlinx.android.synthetic.main.activity_main.*
    //实现OnClickListener点击事件接口
    class MainActivity : AppCompatActivity(), View.OnClickListener {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            //初始化按钮
            init()
        }
    
        //初始化按钮
        private fun init() {
            btnLog.setOnClickListener(this)
            btnToasts.setOnClickListener(this)
            btnToastL.setOnClickListener(this)
            btnNet.setOnClickListener(this)
        }
    
        //实现按钮的点击事件
        override fun onClick(v: View?) {
            when (v?.id) {
                //使用封装的工具类打印Log
                R.id.btnLog -> {
                    
                }
                //使用Anko框架输出短吐司
                R.id.btnToasts -> {
    
                }
                //使用Anko框架数据长吐司
                R.id.btnToastL -> {
    
                }
                //获取网络数据
                R.id.btnNet -> {
    
                }
            }
        }
    
    }
    

    工具类的封装

    为什么要封装Log,这是因为我们每次输入Log的时候,每次都要重复的输入TAG,我们可以把Log封装成一个工具类,把固定的TAG变量抽取出来

    在Kotlin中可以将类的关键字class替换成object,这样该类就会变成了一个单例模式的类,之后我们就可以接用使用类名.方法()的形式调用该类中的方法了

    /**
     * 在kotlin中,加了object后,L类就成为了一个单例模式的类,相当于帮我们省略掉了以前Java实现单例的代码
     * 最后我们可以直接L.d调用类中的方法
     */
    object L {
        //过滤词
        val TAG:String="tonjies"
        //5个等级 DIWE
    
        fun d(text: String) {
            Log.d(TAG, text + "")
        }
    }
    

    在Log按钮的点击事件里面使用

    override fun onClick(v: View?) {
        when (v?.id) {
            R.id.btnLog -> {
                //加了object关键字后成为了单例模式的类,直接类名.方法调用即可
                L.d("你好,世界")
            }
            R.id.btnToasts -> {
    
            }
            R.id.btnToastL -> {
    
            }
            R.id.btnNet -> {
    
            }
        }
    }
    

    点击按钮之后日志成功打印

    打印Log.png

    AnKo的吐司封装

    这里介绍AnKo封装的吐司函数,在build.gradle加入依赖,点击同步

     compile "org.jetbrains.anko:anko-commons:0.10.5"
    

    在按钮点击事件里面写入Anko框架里的toast短吐司,longToast长吐司函数

    override fun onClick(v: View?) {
        when (v?.id) {
            R.id.btnLog -> {
                //加了object关键字后成为了单例模式的类,直接类名.方法调用即可
                L.d("你好,世界")
            }
            R.id.btnToasts -> {
                toast("短吐司")
            }
            R.id.btnToastL -> {
                longToast("长吐司")
            }
            R.id.btnNet -> {
    
            }
        }
    }
    

    点击运行程序,查看短吐司和长吐司时候打印成功

    空值处理

    上一小节频繁出现了!和 ?两个符号,这两个符号在kotlin中代表的是空值处理。

    什么意思呢,我们知道,在我们之前使用java的过程中,很容易就出现了NullPointerException异常。

    举个例子,我们创建一个java学生类

    //举个例子
    public class Student {
        public void study() {
            System.out.println("学生在学习");
        }
    }
    

    测试Main函数

    public class Demo {
        private static Student student;
        public static void main(String[] args) {
            student.study();
        }
    }
    

    我们声明了Student对象,但是却忘记new实例化它,之后就直接调用了学生的study方法,运行结果就是空指针异常了。

    kotlin对这种现象进行了一些处理,现在我们创建test1.kt,创建主函数,同样声明我们的student(kotlin和java的类可以互调),不实现它。

    fun main(args: Array<String>) {
        //报错
        var student: Student= null
    }
    

    我们发现程序直接报错了,这是因为我们的Kotlin默认时不允许你声明不实现的。但是有些情况,我们是没法提前实现的,比如要用后面的参数传递赋值

    这个时候我们可以给该变量的类型加个?,表示允许该变量为空。

    var student: Student?= null
    

    我们再输出学生的学习方法,发现系统再次提示错误

    空值处理.png

    这是因为编译器检测到上面我们已经允许student值为空了,如果我们这时候不做任何处理,它仍然可能跑出空指针异常,所以编译器不允许我们做这么危险的事情。

    移动到错误处,提示我们有两个操作符?.与!!可以操作,我们先使用?.。

    //加入以后,即使是空值调用study方法也不会抛出空指针异常
    student?.study()
    

    我们发现报错消失,运行程序,虽然我们没有实例化Student类就调用了study方法,却没有任何错误,kotlin已经帮我们处理了这个问题,空指针问题解决(因为没有实例化student变量,当然也没有任何输出)。

    那!!又是什么意思,它其实是一个比较作死的符号,如果我们使用它,就表示告诉编译器,我们不需要kotlin来帮我处理空指针异常了,你跟我像java一样运行就可以了。

    //加入以后,编译器就不会再帮我们处理空指针异常了
    student!!.study()
    

    运行程序,结果果然崩溃了,出现了KotlinNullPointerException异常。所以该符号应该尽量少的使用。

    除了上面的两个操作符外,kotlin还有一个叫做Elvis的 操作符供我们使用。

    //加入之后,如果变量不为空,则执行变量的方法,如果变量为空,则执行右边的操作
    student?.study() ?: pritln()
    //声明在主函数之外
    fun pritln() {
        println("变量为空")
    }
    

    这其实有点类似我们用if去做判断。

    if(student==null){
        print("变量为空啦")
    }else{
        student.study()
    }
    

    没错,正是我们java中对空值进行处理的方式。

    完整代码。

    fun main(args: Array<String>) {
        //报错
        var student: Student? = null
        //加入以后,即使是空值调用方法也不会抛出空指针异常
    //    student?.study()
        //加入以后,编译器就不会再帮我们处理空指针异常了
    //    student!!.study()
        //加入之后,如果变量不为空,则执行变量的方法,如果变量为空,则执行右边的操作
        student?.study() ?: pritln()
        if(student==null){
            print("变量为空啦")
        }else{
            student.study()
        }
    }
    //声明在主函数之外
    fun pritln() {
        println("变量为空")
    }
    

    本小节就先到这里啦,如果文章对你有帮助,麻烦点个喜欢 or 关注,谢谢(っ╹◡╹)ノ。

    相关文章

      网友评论

        本文标题:kotlin小白日记2「工具类的封装,Anko简化吐司,空值处理

        本文链接:https://www.haomeiwen.com/subject/kiyfnftx.html