【Android笔记】Kotlin语法糖 & 知识(反射,hook,协程)

390 阅读8分钟

一、Kotlin常用语法糖

1、列表

1、列表区域,理论上用if可以用于防止越界

for (i in textViewList.indices) {
    Log.d("yeTestZ", "initView: " + i)
    textViewList[i].setOnClickListener { toggleSelection(i) }
}
  • textViewList.indices列表区域

2、字符串

1、补充视觉,不足2位自动补0

//补充视觉差异,前提宽度要够,在有放大的reyclevie中
val itemValue=item.padStart(2, '0')

二、常见知识

一、协程

1、作用域

MainScope().launch {
    withContext(Dispatchers.IO) {
       
    }
}

lifecycleScope.launch {}

2、作用域上锁情况

1、例一:启动一个测试协程,内部开启1000个子协程进行count++

  • 每个子协程有的运行在同一线程,有的在不同线程,这样会有多线程并发问题;
  • 挂起的协程并不会阻塞它所在的线程,此时这个线程就可以腾出身去执行其他的任务
  • java 中需要线程暂停时(如 Thread.sleep(1000)),通常就是直接阻塞这个线程,此时这个线程就会被限制,直到阻塞结束。
  • 轻量级的同步锁:Mutex只能锁外层同一个协程域的,如果是一个方法,其他地方调这个方法,第一次的锁是锁不住第二的调用的(两个协程域已经不一样了);

3、生命周期

1、封方法的话先执行job.cancel()

  • 这种写法如果封在方法里调用,如果你没有取消之前的协程,就算复制给同一个job,每次执行你都会启动一个新的协程,并且每个协程都会减少 countDown,这些协程并行工作,从而导致倒计时加速。因为多个协程同时在操作。
job = CoroutineScope(Dispatchers.Main).launch {
    while (countDown > 0) {
        // ...
        delay(1000)
        countDown-- // 每秒减去1
    }
}

二、 Lambda

1、[Kotlin基础] Java 调用

  1. 里面lambda和Java使用匿名内部类写的挺好的。

2、实战!聊聊工作中常用的Lambda

  • filter过滤
  • sorted+Comparator 排序
  • distinct去重
  • findFirst 返回第一个

3、map()和forEach()的区别和理解_map和foreach的区别

  • Map会返回一个数组
  • 他俩都不会修改数据源

2、【Android-Kotlin】匿名内部类与Lambda 表达式(附RecycleView监听)_kotlin lambda 匿名内部类

  • Kotlin与Java接口的写法
  • lambda说明
  • DialogFragment不支持构造方法传东西,callback改写 var callBack: ((allow: Boolean) -> Unit)? = null
  • 外头直接用赋值法:callback={allow->}
  • 写法优化
listener?.let { it(stage, currentCount) }
listener?.invoke(stage, currentCount)

三、let、also、with、run、apply函数的小结

1、场景函数

1、let

  • 在函数体内使用it替代object对象去访问其公有的属性和方法
  • ?.let{//表示object目标对象null的条件下才执行函数
  • 会返回最后一行
  • 优势:使用it指代即可,不用activity!!,新编译器activity!!会报波浪线,推荐用requireActivity()取代
 activity?.let {
                RateDialogFragment().show(it.supportFragmentManager, "")
            }

2、 Also

  • 用法和let差不多,区别在于最后一行不会返回

3、With

  • 适用于调用同一个类的多个方法时,可以省去类名重复,直接调用类的方法即可;
  • 写法和also差不多

image.png

4、Run

  • 写法相当于let和with结合,可以判空
  • 返回最后一行的值

image.png

5、Apply

  • 整体作用功能和run函数很像,唯一不同点就是它返回的值是对象本身

image.png

2、拓展函数

四、惰性加载

1. lateinit一般用于var
2. by lazy一般用于val

五、委托/代理

1、 5分钟速通Kotlin委托

  1. 委托;顾名思义,在代码的表现形式是就是一个方法接口,让一个类实现
  2. kotlin的by关键内部生成了一个对象

六、Kotlin/Java混合使用问题

1、Kotlin 与 Java 互操作_kotlin 转java

  • Java调kotlin伴生对象 内部要用JvmStatic

2、通配符

1、未知类型

  • kotlin:*
  • java:?
  • 样例
val clazz: Class<*>
Class<?> clazz = // 根据需要设置特定的 Class 对象

七、FLOW

三、数据结构

一、常见数据结构

  • 当涉及到存储空间大小时,整数类型(int)通常比字符串类型(String)占用较小的空间。

1、List

1、 kotlin使用SparseArray代替HashMap

  • SparseArray俩用法差不多,但其key/value只支持int类型;put一样都是替换,原本没有就是add,对应的get方法没有就是null。
val testSparse= SparseArray<Int>()
for (i in 0 until 5000) {
    testSparse.put(i,i)
}

Log.d("yeTest", "processLogic: "+testSparse.size())
//不会crash 取到null
Log.d("yeTest", "processLogic: "+testSparse.get(6000))

2、 ArrayList、LinkedList、TreeSet、HashSet、LinkedHashSet区别_linkedlist和hashset区别

  • List是可重复的序列集合
  • Set与Map是不可重复的散列集合

3、kotlin中的List集合类_kotlin list 组合及相关方法

4、getOrNull 很好用的方法

5、排序

6、赋值相关

  • 直接用=赋值的地址指向同一个
  • list1.addAll(list2)的各自的对象,地址都不变,此时修改list1不会影响list2;所以recycleViw其adapter持有的list和初始传进来的list逻辑独立;
  • System.identityHashCode(obj) 获取对象地址;

2、HashMap

  1. value存list:val list: MutableMap<String, List<Any>> = HashMap()

  2. 调用方式

ArrayList<Phone> list = new ArrayList<Phone>();

HashMap actionParams = new HashMap();
actionParams.put(key, value);

val actionParams: MutableMap<String, Any> = HashMap()
actionParams[key] = valie

3、Pair

1、细节说明 Android 表示一对“组元素”的Pair类

  • List+Pair=Map

4、树型相关:

1、一对多树形结构;适合文件及view树。

5、浮点数相关方法:Java Math floor、ceil、rint 及 round 用法

  • 四舍五入,取整相关方法;

二、Json

  • 常见格式
{
    "data":{
        "A1":{
            "A1":[
                "A1-1",
                "A1-2"
            ],
            "current":""//string类型
            "totalCount":1 //int类型 
        }
    }
}

三、各种类

1、判断方法

1、java==和=_Java 中==与===的区别?

  • 两等于会自动转类型,三等于会严格判断类型。

2、判断类型归属

	fun checkNumber(num: Number) {
    when (num) {
        is Int -> println("number is Int")
        is Double -> println("number is Double")
        else -> println("number not support")
    }
}

3、定义参数是一个Class

  • kotlin写法 curPage: Class<*>

2、【Kotlin】枚举类-密封类-数据类-继承

1、简单描述

  • 单纯的枚举类就只是枚举,自带name和位置方法
  • 单纯的数据类只有类目+构造方法参数
  • 两者结合可以有带参数的枚举类

2、使用,个人觉得kotlin里枚举类没什么卵用,正常使用还增加开销

  1. 细节说明:Android中少用枚举类(enum)
  2. 使用注解的方式优化使用枚举类:Kotlin文件@IntDef)
object MemoryConstants {
    const val BYTE = 1
    const val KB = 1024
    const val MB = 104857
    const val GB = 1073741824

    @IntDef(BYTE, KB, MB, GB)
    @kotlin.annotation.Retention(AnnotationRetention.SOURCE)
    annotation class Unit
}

四、常用设计模式

1、单例模式

  • 单例模式与静态类:单例模式VS静态方法

  • 静态类比单例模式的效率更高,因为静态方法在编译期就完成了静态绑定;单例对象可以被延迟初始化;

  • 单例对象适合管理一些状态,静态类适合封装常量和方法;

1、Kotlin下的5种单例模式

  1. 饿汉式与懒汉式声明
  • 饿汉式:提供一个静态单例对象(kotlin object就是这种模式);
  • 懒汉式:提供一个创建单例对象的方法,改对象为空就创建,不为空就返回改对象;
  1. 里面kotlin静态内部类式说的挺好的

2、 Kotlin 实现静态的几种方式详解

  1. Kotlin没有Java static这个概念,使用静态对象模拟 class 的静态属性和方法
  • companion object - 伴随对象,声明单例的方式
  • @JvmField + @JvmStatic 注解 - 使用注解标签声明 static 的部分
  • object 单例 - 静态单例其实和 companion object 类似
  • const - 包内唯一性,脱离类的束缚,kotlin 的特性,在 java 中会编译生成一个 kotlin.kt 的文件专门对齐提供支持

五、泛型

1、Kotlin 核心编程(七):Kotlin 泛型,让类型更加安全

六、反射

    val ivThumb = transformView?.findViewById<ImageView>(R.id.iv_thumb)
                val fieldVisiable = WebpDrawable::class.java.getDeclaredField("isVisible")
                fieldVisiable.isAccessible = true
                if (findViewById != null) {
                    field.setBoolean(ivThumb.drawable, true)
                    println("11111111111获取当前私有Visiable属性"+ivThumb.drawable)
                }

七、Hook

1、样例

  1. 简易版:Android android.os.DeadSystemException解决方案
  2. 细节版:Android System crash DeadSystemException(Service/Activity/终极解决方案)