IO
原理:实际是调用系统内核的函数库,进行数据同步后,由内核将数据写入磁盘;
页
4K数据为一页,一页数据是IO操作的基本单位;
在空间局部性原理下,为了优化,如果数据量较大的情况下,可能会出现预占位4~16K的情况;实际还没写数据,只是提前先多开辟空间,减少了多次开辟空间的操作;
基础IO
FileInputSteam inputSteam/FileOutSteam outSteam:
并没有实现inputSteam.flush(), 实际每次调用inputSteam.write()都会同步写数据;
设置缓冲区:
java自己缓冲区默认大小为8K;
FileInputSteam inputSteam/FileOutSteam outSteam
BufferedOutputStream(outSteam) bos/BufferedIntputStream(inputSteam) bis:
在没有主动调用bosflush()时,每次调用bos.write(),而数据没写满缓存(8K),并不会将数据同步写入文件中;
只有写满缓存8K或者主动调用bos.flush()才会同步将数据写入文件;
对象序列化:
后面讲;
RandomAccessFile:
作用:断点续传、大数据分析;
属于基础流,每次write就会写数据;
提供了定位处理,可以移动起始位置和设置读取偏移量;
如seek(10):从第10位开始;
配合MappedByteBuffer:读写一体的缓冲区,用到了映射,读写大文件时理论速度比普通buffer快3倍;
缓存区:
由于基础IO的相关处理方案,每一次写入都会直接调用复制(比较频繁),将用户空间的数据复制到内核空间,性能不高;
所以有了缓冲区,在当前用户空间,将数据缓存起来,到达8k时一次性写入或读出;
IO模型:
读数据时:
阻塞IO:
在应用层调用内核函数后,如果内核没准备好数据,则应用层会阻塞,等内核准备好数据后,内核进行复制数据操作,处理完返回状态值;
非阻塞IO:
应用层隔断时间查询内核准备好数据没,不等待,查询到准备好时,内核进行复制数据操作,处理完返回状态值;
IO复用:
应用层找了个中间层,让中间人查询准备没,查询到准备好,通知应用层,内核进行复制数据操作,处理完返回状态值;
信号驱动IO:
应用层和内核层建立链接,内核准备好后,通知应用层,内核进行复制数据操作,处理完返回状态值;
异步IO:
应用层和内核层建立链接,内核准备好后,直接将数据进行复制,处理完返回状态值;
Okio:
专门针对网络使用的。是Okhttp内部的IO实现;
将普通的读/写IO的Buffer, 合并为一个双向链表,可以用来从头读,从尾部写;节省了两次开辟IO的Buffer;
序列化
什么是序列化?
- 目的是为了进行数据传输;计算机底层数据传输是二进制数据(010101)
- 序列化:将特定的数据对象(如User),转换为一组基本的二进制字节数据的实现(0101010);
- 反序列化:将基本的二进制字节数据转换为特定的数据对象的实现;
serialVersionUID
用来做版本管理;
当对象读写时,和当前版本不一样时(如增加减少字段),会报错;
建议自己写一个版本号;也可以不写,不写时会自动生成;
trasient瞬态变量
被trasient修饰的变量不参与序列化;
整个对象序列化后,再反序列化后,读取被trasient修饰的变量值是null;
实现序列化的对象Person有一个User变量(没有用trasient),构造中传入一个未实现序列化的对象User,会报错;
子类实现序列化,父类不实现序列化,会有问题吗?
- 子类需要提供无参构造方法;不提供会报错;因为java在反序列化时,会走无参的newInstances();
- 反序列化后,不实现序列化的父类中的变量为null或默认值0、false等;子类中的变量有值;
- 若想有值,需要定义实现两个固定的方法;反射会用到
父类实现序列化,子类不实现序列化,会有问题吗?
没有;子类在继承父类时,将序列化权限也继承了;
若不想子类实现序列化,需重新一下任意一个方法:
Dex
加密本质:
按照固定的逻辑算法将文件的二进制数据进行重新打乱排序;
解密时,按照规定的逻辑反向恢复原有的二进制数据;
App打包流程:
java->Class->dex->Apk;
- 把R.java、自己写的.java、aidl生成的接口文件使用javac编译为一个个的class文件
- 把一个个的class文件使用dx工具编译为一个个的dex文件
- 再将一个个的dex文件,打包为一个dex文件
- 再将dex文件、AndroidMnifist.xml、其他三方jar、so打包为apk
- 再将APK使用签名工具进行签名得到新的可以上架的apk;
加壳
原理:App进程启动时,AMS先返回Applacation信息,和先创建了Applaction
方案1:
- 将Applaction放在其他model中
- 将Applaction所在的model生成的dex不加密
- app业务所在的主model生成的dex加密
- Application加载时,通过dexPathClassLoad将加密的dex进行解密
缺点:将Applaction所在的model里含有解密算法,等于没加密,容易暴露;