Kotlin学习笔记
1.Kotlin文档,
2.kotlin使用Dagger2
-
Kotlin
中使用Dagger2
可能导致错误"Dagger does not support injection into private fields"
https://blog.csdn.net/xuhanbing/article/details/76212338 - 如果是新项目,建议使用koin进行注入
3.java中调用Kotion写的控件失败
原因:没有引入kotlin相关插件
解决:首先在Project
的build.gradle
中的dependencies
加入 classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.21"
,然后在Module
的build.gradle
中引入插件plugins { id 'com.android.application' id 'kotlin-android' }
4.不要再使用Kotlin Extensions Gradle
插件,推荐使用ViewDatabind
5.插件
名称 | 描述 |
---|---|
JsonToKotlinClass | Json数据格式化Kotlin的插件 |
BugKotlinDocument-Github | 输入/**就出来注释 |
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 的缺陷及一点点思考 |
图片加载 |
coil用kotlin 写的图片加载库,可替代Glide
|
9.DSL篇
10.网络
使用协程,让网络世界更加美好
Retrofit + Kotlin请求接口时,遇到问题:Parameter type must not include a type variable or wildcard
11.协程
kotlin coroutines guide-官方文档
Kotlin 协程-掘金博客
Kotlin Jetpack 实战:图解协程原理
深入学习Kotlin之Flow(一),什么是Flow?Flow的基本使用
Kotlin协程官方文档
官方推荐 Flow 取代 LiveData,有必要吗?
12.如何使用kapt
apply plugin: 'kotlin-kapt'
kapt {
generateStubs = true
}
kapt 'androidx.room:room-compiler:2.2.3'
注意:annotationProcessor
和kapt
不能共存,如果你是java
和Kotlin
混用的项目,那么使用了kapt
后,其他的使用annotationProcessor
也要改为kapt
,不然构建项目就会报报错(我就是因为这个原因,搞了一天)
13.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.单例模式
18.Java 中的写法在Kotlin 中是怎么写的?
19.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.ViewModel
24.关键字
Kotlin系列之let、with、run、apply、also函数的使用
字段 | 用法 | 说明 |
---|---|---|
also |
object.also{//todo} |
also 函数返回的则是传入对象的本身,和let 函数使用类似 |
25.MVVM记录关键点
- ViewModel
ViewModel-Google官网
ViewModel简书
【背上Jetpack之ViewModel】即使您不使用MVVM也要了解ViewModel ——ViewModel 的职能边界 - LivewData
LiveData数据改变时通知相应的界面代码进行更新
1.要绑定每次数据的更新,需要如下代码
binding.setLifecycleOwner(this)//关键代码:绑定每次LiveData数据的更新
2.如果想多个页面使用观察同一个数据,可以设置此数据为静态变量
companion object{
private var userData = MutableLiveData<User>()
}
26.代码混淆
27.zxing二维码扫描
28.事件分发
https://www.jianshu.com/p/3581fcf302fd?utm_campaign=haruki
29.RecyclerView 配合 DiffUtil,好用到飞起
30.Fragment的添加,删除,替换,https://cloud.tencent.com/developer/article/1036708
31.在Kotlin中对空字段的处理
val submitTime:String=""
get() = if(TextUtils.isEmpty(field))"--" else TimeUtils.ymdhmsToYmdhm(field)
32.kotlin 字符串_10个有用的Kotlin字符串扩展
https://blog.csdn.net/weixin_26727575/article/details/108497391