会自动生成一个findCachedViewById的函数,从这个函数里获取一个HashMap的id资源id所对应的实例缓存,如果没有缓存,就会调用findViewById函数来查找控件实例,并写入HashMap缓存中。问题是每个Activity都需要一个额外的HashMap来存储所有控件的实例,增加了一些内存开支。
2.viewBinding的原理及使用一旦启动了ViewBinding功能之后,Android Studio会自动为我们所编写的每一个布局文件都生成一个对应的Binding类。比如说,前面我们定义了一个activity_main.xml布局,那么与它对应的Binding类就是ActivityMainBinding。如果有些布局文件你不希望为它生成对应的Binding类,可以在该布局文件的根元素位置加入如下声明:tools:viewBindingIgnore="true”。使用如下:
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.textView.text = "Hello"
3.IO操作SP的写入是基于IO操作的,为了了解IO,需要了解用户空间和内核空间,虚拟内存被操作系统划分为两块(用户空间和内核空间)用户空间是用户程序代码运行的地方,内核空间是内核代码运行的地方。为了安全,它们是隔离的,即使用户的程序崩溃了,内核也不受影响。
写入文件流程:
==调用write,告诉内核需要写入数据的开始地址和长度
==内核将数据拷贝到内核缓存
==由操作系统调用,将数据拷贝到磁盘,完成写入
4.MMAPLinux通过将一个虚拟内存区域与一个磁盘上的对象关联起来,以初始化这个虚拟内存区域的内容,这个过程称为内存映射。
对文件进行mmap,会在进程的虚拟内存分配地址空间,创建映射关系。
实现映射关系后,就可以采用指针的方式读写操作这一段内存,系统会自动回写到对应的磁盘上
MMAP优势:
-MMAP对文件的读写操作只需要从磁盘到用户主存的一次数据拷贝过程,减少了数据的拷贝次数,提高了文件读写效率。
-MMAP使用逻辑内存对磁盘文件进行映射,操作内存就相当于操作文件,不需要开启线程,操作MMAP的速度和操作内存的速度一样快;
-MMAP提供一段可供随时写入的内存块,App 只管往里面写数据,由操作系统如内存不足、进程退出等时候负责将内存回写到文件,不必担心 crash 导致数据丢失。
5.mmkv优点-1.MMKV实现了SharedPreferences接口,可以无缝切换
-2.通过 mmap 内存映射文件,提供一段可供随时写入的内存块,App 只管往里面写数据,由操作系统负责将内存回写到文件,不必担心 crash 导致数据丢失。
-3.MMKV数据序列化方面选用 protobuf 协议,pb 在性能和空间占用上都有不错的表现
-4.SP是全量更新,MMKV是增量更新,有性能优势
6.butterKnife简单实现-使用注解加反射实现,注解如下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MlBindLayoutId {
int value();
}
-使用反射获取类信息,方法,使用方法调用value
fun injectLayoutId(activity: Activity){
//获取 Activity的对象
val javaClass = activity.javaClass
//判断是否有ML注解
val annotationPresent = javaClass.isAnnotationPresent(MlBindLayoutId::class.java)
if (annotationPresent){
val layoutId = javaClass.getAnnotation(MlBindLayoutId::class.java)
val id=layoutId.value
Timber.d("=====injectLayoutId===$id")
//拿到setContentView方法
try {
val setContentViewMethod=javaClass.getMethod("setContentView",Int::class.java)
setContentViewMethod.invoke(activity,id)
}catch (e:Exception){
e.printStackTrace()
}
}
}
-如果有接口回调(比如点击事件),需要使用动态代理方式调用



