Kotlin学习笔记

1.Kotlin文档

2.kotlin使用Dagger2

3.java中调用Kotion写的控件失败

原因:没有引入kotlin相关插件
解决:首先在Projectbuild.gradle中的dependencies加入 classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.21",然后在Modulebuild.gradle中引入插件plugins { id 'com.android.application' id 'kotlin-android' }

4.不要再使用Kotlin Extensions Gradle插件,推荐使用ViewDatabind

优雅地封装和使用 ViewBinding

5.插件

名称 描述
JsonToKotlinClass Json数据格式化Kotlin的插件
BugKotlinDocument-Github 输入/**就出来注释

Android Studio离线安装插件plugins

6.创建一个Handler

    private  var mHandler = Handler(Looper.getMainLooper()) {
        false
    }

注意1:要在内部使用mHandler.sendEmptyMessage(0),可以通过msg.target得到mHandler对象后发送
注意2:mainLooper可能为空,你要确定你是在主线程调用此mHandler,否则推荐使用Looper.getMainLooper()

7.适用于Kotlin的依赖注入框架Koin,用于替代Dragger2

koin-Github
适用于Kotlin的超好用依赖注入框架

8.库

说明 引入路径
生命周期-数据绑定ViewModel 官网ViewModelimplementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
协程 官网协程简介 implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9"
依赖注入框架 koin,适用于Kotlin中替代Dragger,简书博客介绍Koin
数据存储 MMKV参考:SharedPreferences替换:MMKV集成与原理一文读懂 SharedPreferences 的缺陷及一点点思考
图片加载 coilkotlin写的图片加载库,可替代Glide

9.DSL篇

Kotlin之美——DSL篇

10.网络

使用协程,让网络世界更加美好
Retrofit + Kotlin请求接口时,遇到问题:Parameter type must not include a type variable or wildcard
使用Moshi更好地兼容Kotlin空安全

11.协程

kotlin coroutines guide-官方文档
Kotlin 协程-掘金博客
Kotlin Coroutines(协程)讲解
Kotlin Jetpack 实战:图解协程原理

12.如何使用kapt

apply plugin: 'kotlin-kapt'
kapt {
generateStubs = true
}
kapt 'androidx.room:room-compiler:2.2.3'

注意:annotationProcessorkapt不能共存,如果你是javaKotlin混用的项目,那么使用了kapt后,其他的使用annotationProcessor也要改为kapt,不然构建项目就会报报错(我就是因为这个原因,搞了一天)

13.KTX扩展项

官方KTX介绍

14.泛型

我的Kotlin 学习之路(七)Kotlin之泛型、泛型约束、协变(Variance)

15.扩展函数

inline、noinline、crossinline傻傻分不清楚

16.序列化parcelize

首先引入插件

apply plugin: 'kotlin-parcelize'

然后,需要序列化的类:

import android.os.Parcelable
import kotlinx.parcelize.Parcelize
@Parcelize
class UserBean(val name:String,val id:Int):Parcelable

17.单例模式

Kotlin中带参的单例模式

18.Java 中的写法在Kotlin 中是怎么写的?

Java 中的写法在Kotlin 中是怎么写的?

19.Kotlin for循环的几种使用方法

Kotlin for循环的几种使用方法

20.Jetpack Compose

Jetpack Compose Beta 版现已发布!-掘金翻译的官方文档
Jetpack Compose 环境基础,编写示例

21.数据存储

当前最好用的用于替代SharedPreferences的存储是MMKV,由于MMKV存储对象必须是实现了Parcelable的对象,而如果你还保留了大量java代码写的只实现了Serializable接口的对象。可用用如下方式读写:

/**
         * desc:保存对象
         * @param key
         * @param obj
         * @remind 要保存的对象,只能保存实现了serializable的对象
         */
        @JvmStatic
        fun saveObject(key: String?, obj: Serializable?) {
            try {
                //先将序列化结果写到byte缓存中,其实就分配一个内存空间
                val bos = ByteArrayOutputStream()
                val os = ObjectOutputStream(bos)
                //将对象序列化写入byte缓存
                os.writeObject(obj)
                //将序列化的数据转为16进制保存
                val bytesToHexString = bytesToHexString(bos.toByteArray())
                //保存该16进制数组
                mmkv.putString(key, bytesToHexString)
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
        @JvmStatic
        fun <T : Any?> readObject(key: String?): T? {
            val string = mmkv.getString(key, "")
            string?.let {
                //将16进制的数据转为数组,准备反序列化
                return try {
                    val stringToBytes = StringToBytes(string)
                    val bis = ByteArrayInputStream(stringToBytes)
                    val ois = ObjectInputStream(bis)
                    //返回反序列化得到的对象
                    ois.readObject() as T
                } catch (e: Exception) {
                    null
                }
            }
            return null
        }

        /**
         * desc:将数组转为16进制
         * @param bArray
         * @return modified:
         */
        private fun bytesToHexString(bArray: ByteArray?): String? {
            if (bArray == null) return null
            if (bArray.isEmpty()) return ""

            val sb = StringBuffer(bArray.size)
            var sTemp: String
            for (i in bArray.indices) {
                sTemp = Integer.toHexString(0xFF and bArray[i].toInt())
                if (sTemp.length < 2) sb.append(0)
                sb.append(sTemp.toUpperCase(Locale.getDefault()))
            }
            return sb.toString()
        }

        /**
         * 把16进制字符串转换成字节数组 @param hex @return
         */
        private fun StringToBytes(hex: String): ByteArray {
            val len = hex.length / 2
            val result = ByteArray(len)
            val achar = hex.toCharArray()
            for (i in 0 until len) {
                val pos = i * 2
                val toBe1 = toByte(achar[pos])
                val a = toBe1 shl 4
                val b = toByte(achar[pos + 1])
                result[i] = ((a or b).toByte())
            }
            return result
        }

        private fun toByte(c: Char): Int {
            return "0123456789ABCDEF".indexOf(c)
        }

但建议还是把对象改为实现Parcelable,因为Parcelable的效率是Serializable的10多倍。
而且用kotlin实现也很方便,参考上面16

22.坑

1.如果要使用@BindingAdapter对数据进行绑定,那么需要添加@JvmStatic注释,否则报错

    //普通网络图片
    @JvmStatic
    @BindingAdapter("url")
    fun bindUrl(view: ImageView, imageUrl: String?) {
        Glide.with(view).load(imageUrl).into(view)
    }

2.java一键转kotlin后会出现很多!!标记的内容,使用了!!的字段要非常确定不为空null
解决方案:让你的 Kotlin 代码远离 !!

3.友盟统计SDK不支持kotlin,以前是java的时候有数据,改为kotlin的一周,发现没有统计数据了
解决:MyApplication改用java代码编写,然后在里面做友盟的初始化操作
4.高德地图黑屏:神奇的bug
最开始以为是kotlin的问题,用了java写页面,问题依旧,最后发现三个条件导致页面黑屏,a.文本数据设置中包含了特殊字符:()或· b.使用了高德地图mapView.onCreate(savedInstanceState),c.红米k30手机(目前测试其他手机正常)

  • 单独使用地图,没有问题(说明高德没有)
  • 单独对文本设置包含了特殊字符的文本没有问题(说明可以设置特殊字符的文本:重庆市渝中区菜袁路渝中区旭庆·江湾国际花都(菜袁路西))
  • 不使用红米手机K30,设置了地图也设置了包含了特殊字符的文本也没问题
    最终结论:手机有问题

解决方案一:去掉特殊文本中的特殊字符:重庆市渝中区菜袁路渝中区旭庆江湾国际花都菜袁路西(不合理,显示的内容缺少)
解决方案二:不使用红米手机(测试不干)
解决方案三:猜想黑屏是渲染导致,那么可以延迟处理其中一方,地图因为要跟随onCreate的创建而绑定,没法弄,于是考虑延迟300豪秒来设置特殊文本到文本控件中

23.关键字

Kotlin系列之let、with、run、apply、also函数的使用

字段 用法 说明
also object.also{//todo} also函数返回的则是传入对象的本身,和let函数使用类似

24.MVVM记录关键点

1.要绑定每次数据的更新,需要如下代码

binding.setLifecycleOwner(this)//关键代码:绑定每次LiveData数据的更新

2.如果想多个页面使用观察同一个数据,可以设置此数据为静态变量

companion object{
        private var userData = MutableLiveData<User>()
    }

25.代码混淆

Android 代码混淆,到底做了什么?

26.zxing二维码扫描

zxing-android-embedded

27.RecyclerView 配合 DiffUtil,好用到飞起

https://www.cnblogs.com/plokmju/p/7385136.html

28.Fragment的添加,删除,替换,https://cloud.tencent.com/developer/article/1036708

29.在Kotlin中对空字段的处理

val submitTime:String=""
get() = if(TextUtils.isEmpty(field))"--" else TimeUtils.ymdhmsToYmdhm(field)

30.kotlin 字符串_10个有用的Kotlin字符串扩展

https://blog.csdn.net/weixin_26727575/article/details/108497391

31.AS编译报错:More than one file was found with OS independent path META-INF/library_release.kotlin_module

https://blog.csdn.net/jabony/article/details/112930562

32.kotlin - 实现静态单例的方式

https://www.jianshu.com/p/fe44743d0f01

33.hook:无所不能的 hook,让应用不再崩溃

https://mp.weixin.qq.com/s/6IgiJQEWUvfzxfP1gJFVLQ
https://github.com/eleme/lancet

34.构建异常:

引入最新ExoPlayer:The minCompileSdk (31) specified in adependency's AAR metadata (META-INF/com/android/build/gradle/aar-metadata.properties)is greater than this module's compileSdkVersion (android-30).Dependency: androidx.core:core:1.7.0.
解决一:https://www.cjavapy.com/article/2241/【无效】
解决二:我是因为引入了implementation 'com.google.android.exoplayer:exoplayer:2.16.1'去掉后即可

修改buildToolsVersion '31.0.0'后报错,Installed Build Tools revision 31.0.0 is corrupted. Remove and install again
解决:https://blog.n0ts.cn/1435.html

修改compileSdkVersion 31和 targetSdkVersion 31报错:> Manifest merger failed : Apps targeting Android 12 and higher are required to specify an explicit value forandroid:exportedwhen the corresponding component has an intent filter defined. See https://developer.android.com/guide/topics/manifest/activity-element#exported for details.
解决: 给有过滤器的页面添加android:exported属性

添加:android:exported="true"后依然报错
解决:

异常:The minCompileSdk (31) specified in adependency's AAR metadata (META-INF/com/android/build/gradle/aar-metadata.properties)
配置冲突:https://www.cjavapy.com/article/2241/

35.自定义View-第十四步:setShadowLayer阴影与SetMaskFilter发光效果

https://www.jianshu.com/p/2f1024f9c554

36.过时的OnActivityResult替代品registerForActivityResult

https://www.jianshu.com/p/b6798dcf090a
ActivityResultContract抽象类
ActivityResultCallback接口回调
ActivityResultRegistry抽象类

    @NonNull
    @Override
    public final <I, O> ActivityResultLauncher<I> registerForActivityResult(
            @NonNull ActivityResultContract<I, O> contract,
            @NonNull ActivityResultCallback<O> callback) {
        return registerForActivityResult(contract, mActivityResultRegistry, callback);
    }
    @NonNull
    @Override
    public final <I, O> ActivityResultLauncher<I> registerForActivityResult(
            @NonNull final ActivityResultContract<I, O> contract,
            @NonNull final ActivityResultRegistry registry,
            @NonNull final ActivityResultCallback<O> callback) {
        return registry.register(
                "activity_rq#" + mNextLocalRequestCode.getAndIncrement(), this, contract, callback);
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,585评论 4 365
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,923评论 1 301
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,314评论 0 248
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,346评论 0 214
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,718评论 3 291
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,828评论 1 223
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,020评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,758评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,486评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,722评论 2 251
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,196评论 1 262
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,546评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,211评论 3 240
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,132评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,916评论 0 200
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,904评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,758评论 2 274

推荐阅读更多精彩内容

  • 前言 整理了协程的基本使用,不深入,适合入门。刚接触协程,不必过于关注定义。协程的生命周期是需要留意的点。 学习资...
    大荒里种菜阅读 408评论 0 1
  • 本文介绍了Kotlin入门应该知道一些基本语法概念。包括变量、常量、函数、空安全、类定义、类继承、数据类、接口定义...
    于卫国阅读 6,372评论 6 10
  • 在前面说几句 Google I/O 正式宣布将 Kotlin 作为 Android 的官方开发语言,大家学习 Ko...
    HowieTian阅读 363评论 0 0
  • 每天学习一小时,所以每天记录一点点,月末争取把文档看完😭 为什么学习Kotlin呢? Kotlin中文官方文档文档...
    刘喵喵嗷呜阅读 283评论 0 0
  • 推荐指数: 6.0 书籍主旨关键词:特权、焦点、注意力、语言联想、情景联想 观点: 1.统计学现在叫数据分析,社会...
    Jenaral阅读 5,661评论 0 5