Q:安卓为什么要用反射创建 view?
创建对象要么 new 要么反射,android 可以用代码构建视图(Flutter、Compose),但可读性和维护很艰难,远不如布局文件来得直观。 layoutinflater 的 createview 方法,他是通过名字反射创建的不用 new 对应的类。
用布局文件,里面都是文本信息,这就需要将文本转换成对象,比如 key 是一个类的名称,你怎么把他转换成对象,反射当然是最直接的。
Q:常用的序列化的实现?
原生序列化Serializable、Android的Parceble序列化、JSON序列化、XML、Protobuf 序列化
Q:java中有goto关键字吗?为什么
goto是java语言中的保留字,目前还没有在java中使用。
其实goto这个词是C语言中的,goto语句通常与条件语句配合使用,可用来实现条件转移, 构成循环,跳出循环体等功能。而在结构化程序语言 中一般不主张使用goto语句,以免造成程序流程的混乱,使理解和调试程序都产生困难。但是在java语言中,goto这个词只是作为了保留字,还没有使用。
Q:Stringbuffer 和 Stringbuilder 的区别是什么?
你在代码中点开它们的append方法,你会看到stringbuffer的方法前面用的synchronized方法修饰的,而Stringbuilder是没有的。这就是本质区别。一个,线程安全,一个线程不安全。
1.可变性 一般都与String进行对比,因为String是不可变的,但是StringBuffer和StringBuilder是可变的。 2.线程安全性 StringBuffer是线程安全的,原理是StringBuffer对内部方法加了Synchronize同步锁。 StringBuilder是线程不安全的。 3.性能 StringBuilder的性能比StringBuffer高,因为StringBuilder没有同步锁,所以性能要好一些。
Q:android 线程间通信?
Handler,AsyncTask,RxJava,eventbus,全局变量,接口回调,观察者模式,Java 锁,Threadlocal
Q:Callable 和 Runnable 的区别?
1.Callable规定重写方法是call(),Runnable规定重写方法是run();
2.Callabel任务执行完后可返回值,Runnable不可返回值;
3.call方法可以抛出异常,run方法不可以;
4.运行Callable任务可以获取一个Future对象,通过Future对象可以拿到结果,也可以取消任务。
Q:如何缩减 APK 包的大小?
方法一:资源文件压缩 方法二:去除不需要的内容。 方法三:数据交互放后端。
主要就是so包和资源文件
1. lint检测工具,删除无用的代码和资源(xml、图片、assets等);
2. 压缩图片,大于100kb的使用webp,尽量使用jpg,常用图标使用svg矢量图,删除不常用的分辨率图片;
3. 删除不常用的abi,大部分保留armeabi-v7a即可,当然得考虑64位的;
4. 删除无用的语言包;
5. 混淆压缩代码;
6. 删除dex中的打印日志代码;
7. 某些资源使用cdn网络下载;
8.插件化
Q:如何优化 ListView?
①Item 布局,层级越少越好,使用 hierarchyview 工具查看优化。
②复用 convertView
③使用 ViewHolder
④item 中有图片时,异步加载
⑤快速滑动时,不加载图片
⑥item 中有图片时,应对图片进行适当压缩
⑦实现数据的分页加载
Q:https的效率一定比http低吗,是每一次都低吗?
如果使用链接复用,http2协议规则 https只是第一次效率比http低,第一次握手、证书校验等肯定有损耗。
Q:LeakCanary 核心原理,以及源码浅析
注册activity等的生命周期监听,当调用ondestory的时候判断当前要销毁对象在内存中的实例对象是否存在,存在的话会手动调用一次回收,然后在进行判断是否存在如果还存在那就认为是有强引用无法回收,认为是内存泄漏。
Q:Android 中有几种 ANR,你是如何解决的?
死锁,native 没返回,数据库,网络操作,cpu 占用,oom 等
常见 ANR:1、应用主线程非常缓慢的执行 I/O 操作。2、在主线程进行耗时计算。3、binder 调用,另一个进程返回时间过长。4、主线程阻塞,binder 调用死锁。
1.单纯 block 在 UI 线程(主线程),看 traces 就行了 2.remoteservicereplytimeout,查看对端进程 callstack 就好了 3.短时间内大量 message-检查一下 APP 行为 4.system_wise 问题导致,查看一下 CPUloading/低内存等 就这些,应该不会有别的情况了。
死锁、锁定后操作异常导致锁没有释放、各种系统资源占用之后没有释放或者异常导致资源操作释放未执行、递归方法导致死循环,循环语句条件判断错误导致死循环、短时间内大量生成对象、大尺寸 Bitmap 并且没有办法回收导致内存溢出、主线程执行耗时操作或者上述错误操作在主线程执行导致超时、debug 模式下断点调试导致 ui 响应超时、在主线程调用第三方同步方法、native 方法,但由于第三方、native 调用时间超出预期导致无响应,所以对于自己不了解或者不可控的操作在工作线程调用比较好,保持 ui 主线程畅通。对于资源占用的任何调用,最好都安排专门的数据结构来记录存储,在 app 相应部分生命周期结束前取消、清空、置空回调接口、取消注册,如果上述置空操作导致了新的闪退,更能证明相关的处理工作不完善。
Q:recyclerview 加载大量图片如何避免 oom,同时保证滑动查看时流畅?
1、滑动停止再异步加载图片,参考小米; 2、图片高度固定; 3、采样率、大小裁剪,适当缩减; 4、适当调整 rv 的缓存池大小 5、申请大一点的内存; 6、profile 看看有没有加载耗时很长的方法。
1,降低图片的色彩解析模式,比如 glide 默认使用 RGB_565,内存直接减少一半。
2,对于网络图片可以通过 cdn 云平台按需加载,比如腾讯云 cdn 可以在图片 url 后面拼接参数,界面上只加载所需要的大小质量的图片。
3,高效的图片缓存,LRU 缓存,Glide 的多尺寸缓存等。
4,高效的处理 Bitmap【bitmap 的复用和主动回收】。
5,如果大图片有预览功能,还可以使用 BitmapRegionDecoder 切片和手势,可以优化超大图片。
6,加载图片使用 http2.0。
7,加载 webp 格式的图片。
8,本地的图片等资源,要放置在合理的分辨率目录下面。
9,对于某一些图片可以预加载。
10,滑动列表的停止加载图片,停止的时候继续加载。
11,安卓 5.0 以下的手机,可以使用 Fresco,他将图片数据放在 native 堆里面,目前 8.0 以后都是放在 native 堆里面,可以有效减少 oom。
12,图片加载和页面的生命周期绑定,glide 有这个功能。
13,内存不足的时候,清除内存缓存。
14,对于本地大图片,先进行压缩。
Q:约束布局,线性布局,相对布局绘制层级一样的情况下的性能对比及最佳使用场景?
按照谷歌官方的说法,相对布局的性能优于线性布局。线性布局容易出现多重嵌套的情况,而相对布局可以很大程度上减少布局的层叠关系。但在单行并列的布局中,因为相对布局会进行二次绘制,线性布局只有在使用 weight 属性下才会进行二次绘制。在单行并列布局中,线性布局优于相对布局
官方描述中,约束布局的性能是优于相对布局的,但是经过测试,在简单的布局页面中,其结果恰恰相反,相对布局的性能要优于约束布局。
所以,从开发效率方面考虑,哪个顺手就用哪个吧,不要纠结太多