手记

Android日常基础知识整理(上)

1.java char

占两个字节
unicode 字符集 不是编码,类似于ASCII码char 不存utf-8,而是存utf-16utf-8 占1~3个字节
字符串长度与字符数不相等

2.java String

最大长度
字面量,代码中,栈 字节码,65535 javac 65534 kt正常
读文件,堆 虚拟机指令newarray Integer.MAX_VALUE 内存大小限制

3.java匿名内部类限制

匿名内部类有名字的,只是我们看不太懂 xx.xx.xx$1匿名内部类的继承结构 
匿名内部类的构造方法
SAM类型 只能是接口,并且只能有一个方法

4.java方法分派

方法分给谁
静态分派  重载 编译的时候确认,根据调用者的声明类型和参数的类型
动态分派  覆写 运行的时候,根据实际的类型来分派
Groovy 根据实际的类型调用哪个方法

5.java 泛型

类型擦除 与C#对比类型擦除后为Object,所以不兼容基本数据类型
基本类型无法作为实参,只能引用装箱,拆箱,需要有开销
泛型类型无法用作方法重载
无法当做真实的类型使用
java选择类型擦除主要考虑到了兼容问题
擦除后,在一定场景下可以通过反射获得泛型类型签名信息
Gson Retrofit

6.onActivityResult

实际中怎么使用
使用的时候有哪些不好的地方
能否用回调来替代
自己设计一个方案来替代onActivityResult

7.线程的终止

线程的stop都被废弃了 因为不安全boolean标志位
interrupt

8.线程安全

可变资源(内存)线程间共享
不变,即安全
可见,能正常处理,也会安全
原子性,每一个指令都没有争议
禁止指令重排序

9.ConcurrentHashMap

如何支持并发HashTable 整个都加锁,线程安全,暴力,影响效率JDK1.5,引入段,分段锁,给段加锁,但hash散列值不均匀,会退化成HashTableJDK1.6,优化散列值不均匀的问题JDK1.7,之前的16个段都直接初始化了,这个版本的段延迟初始化,用到哪个初始化哪个,并对数组使用volatile,保证段的可见性JDK1.8,没有分段锁,直接给table使用volatile

10.AR 和 ARFU

AtomicReference 和 AtomicReferenceFiledUpdater 保证原子性,作用于线程安全

AtomicReference 比较消耗内存,每个实例需要额外开辟空间存储一些信息 一般用在实例化较少的场景
AtomicReferenceFiledUpdater 不用额外开辟一些空间,但使用起来比较不友好,一般用于静待对象

11.异步

不是按照顺序执行代码,可以是在同一线程
当回调嵌套态度,就会出现回调地狱,看起来累
引入RxJava,扁平化,解决嵌套,但要注意异常处理和取消处理的操作
Kotlin协程异步同步化,看起来和同步产不多,还是要注意异常与取消 的处理

12.CPU架构 适配

native开发关注
mips 废弃
x86 废弃
armeabi  兼容性最好
armeabi-v7a
arm64-v8a
机器根据自身对应的cpu架构,查找对应的目录so库,因此提供so要提供一整套,要么某一个架构下一个也不提供
兼容也会出现一些问题

提供合适的架构(一个目录),里面也可以放入其他架构的so库,使用时使用动态加载(动态识别机器的cpu架构)
线上监控,根据实际数据来判断哪些应该使用动态加载其他架构的so库
云端下载
so库体积优化
默认隐藏所有符号,只公开必要的
禁用 C++ Exception RTTI,会增加so库大小,Android一般用不了
iostream尽量不使用,尽量使用Android log使用gc-sections 去除无用代码,类似java中的proguard混淆
构建时分包,不同架构只有相应的so库,依靠应用商城,用户下载 时下载相应cpu架构下的ap

13.java native方法和native函数的绑定

静态绑定  命令规则映射
java包名的点替换成下划线native方法中需要有修饰符号 避免 C++编译的时候把名字给搞乱了,找不到函数
 
动态绑定  通过jni函数注册  NativeRegister
在动态 绑定之前调用,还是走静态绑定方式
动态绑定后,走动态绑定方式,可以取消绑定,恢复静态绑定方式,比较灵活

比较
函数名 动态绑定无要求,静态绑定有命名规则
可见性 动态绑定无要求,静态绑定需要明文符号修饰,可见
动态更换 动态绑定可以替换,静态绑定写死的,更换不了
调用性能  动态绑定无需查找,静态绑定需要查找,有额外开销
开发体验  动态绑定没啥副作用,静态绑定重构的时候比较繁琐
AS的支持  动态绑定没法自动关联,静态绑定可以关联,可以点击跳过去,开发时方便查看

14.jni数据传递

通过long类型传递底层对象指针给java层
注意string的几组函数操作的区别于适用场景
GetStringUTFChars/ReleaseStringUTFChars const char *  MUTF-8  \0编码成两个字节,避免C字符的结尾
GetStringChars/ReleaseStringChars const jchar* jni函数自动处理字节序转换
GetStringUTFRegion/GetStringRegion  拷贝一部分字符串出来
GetStringCritical/ReleaseStringCritical  GC停掉,回收不了这一块内存
注意对象数组较大时的LocalRef超过上限的问题
注意使用DirectBuff时字节序的问题

15.捕获native异常

捕获系统sig信号来捕获native异常
使用JniEnv的findClass 堆栈的classLoader
Native线程绑定到jvm 有内存泄露问题
java对象全局引用 获取到的都是LocalRef,需要新建一个全局
Native调用Java方法 反射 
异常回调到java层

16. 其他native语言

Golang
Kotlin native@CName静态绑定
动态绑定



作者:进击的欧阳
链接:https://www.jianshu.com/p/6975b768b8a6


0人推荐
随时随地看视频
慕课网APP