全面而详尽的Android面试题集
Android面试系列2018总结(全方面覆盖Android知识结构)
1. 什么是ANR?如何避免?
ANR(Application NotResponding)指的是应用程序在一段时间内无响应,系统会向用户弹出一个应用无响应的对话框,用户可以选择关闭应用或者继续等待应用响应,这往往是由于程序的性能所引发的。在Android开发中,不同的组件发生ANR的时间是不一样的。Activity是5秒,BroadCastReceiver是10秒,Service是20秒(均为前台)。 注意,BroadCastReceiver和Service都是运行在主线程中的,应该尽量避免在其中做耗时操作。
解决方案:将所有耗时操作:如网络请求,Socket通信,查询大量SQL语句,复杂的逻辑计算等都放到子线程中去处理,然后将处理结果通过Handler、AsyncTask等方式更新UI。
2. Android各版本新特性
Android5.0新特性:
- MaterialDesign设计风格
- 支持多种设备(智能手机、平板电脑、笔记本电脑、智能电视、汽车、智能手表等)
- 支持64位ART虚拟机
Android6.0新特性:
- 动态权限管理
- 指纹识别
- 支持快速充电的切换
- 支持文件夹拖拽应用
- 相机新增专业模式
Android7.0新特性:
- 分屏多任务
- 支持Java8开发
- 夜间模式
Android8.0新特性:
- 画中画
- 通知标志
- 自动填写
- 系统优化
- 后台限制
Android9.0新特性:
- 支持刘海屏
- 室内wifi定位
- 新的图片解码等
3. 你在项目中遇到过哪些难题?最终是如何解决的?
Android技术难题解决方案
之前在开发时需要设置一张大图片,按照正常的做法,直接放个ImageView然后加载图片,但是奇怪的是既没有出现OOM异常,也没有正常显示图片,显示的是一个空白页面。
出现原因:
https://blog.csdn.net/super_zq/article/details/52756286,其实就是不同的厂家手机系统对长图做了限制
开源控件:
https://github.com/LuckyJayce/LargeImage
[https://github.com/davemorrissey/subsampling-scale-image-view](https://github.com/davemorrissey/subsampling-scale-image-view)
4. String,StringBuffer,StringBuilder有哪些不同
执行速度:StringBuilder > StringBuffer > String
String每变化一个值就会开辟一个新的内存空间
StringBuilder是线程非安全的
StringBuffer是线程安全的
对于三者使用的总结:
1.如果要操作少量的数据用 = String
2.单线程操作字符串缓冲区下操作大量数据 = StringBuilder
3.多线程操作字符串缓冲区下操作大量数据 = StringBuffer
5. Android系统提供了哪些动画机制?
- 逐帧动画 — 将一个完整的动画拆分成一张张单独的图片,然后再将它们连贯起来进行播放,类似于动画片的工作原理
- 补间动画(View动画) — 可以对View进行一系列的动画操作,包括淡入淡出、缩放、平移、旋转四种(缺点:只是改变了View的显示效果而已,而不会真正去改变View的属性,即经过补间动画移动过后,点击事件的效果还是在移动前的位置上)
- 属性动画 — ObjectAnimator可以做各种动画操作(ValueAnimator是整个属性动画机制当中最核心的一个类)
6. 写一种你认为最优的单例模式?
在实际开发中,我写得最多的是双重检索式,但是这种写法在第一次调用的时候还是会synchronized 同步,会浪费一定的时间。相比来说,静态内部类式会更好:【Java】线程安全的单例模式----静态内部类
public class SingletonPattern {
private SingletonPattern() {
}
private static class SingletonPatternHolder {
private static final SingletonPattern singletonPattern = new SingletonPattern();
}
public static SingletonPattern getInstance() {
return SingletonPatternHolder.singletonPattern;
}
}
7. Android里的Intent传递的数据有大小限制吗,如何解决?
Intent传递数据大小的限制大概在1M左右,超过这个限制就会静默崩溃。处理方式如下:
- 进程内:EventBus,文件缓存、磁盘缓存。
- 进程间:通过ContentProvider进行进程间数据共享和传递。
8. Serializable和Parcelable的区别?
序列化Serializable和Parcelable的理解和区别
所谓序列化就是将对象变成二进制流,便于存储和传输
- Serializable — Java自带,实现Serializable接口即可,性能低
- Parcelable — Android专用,可通过AndroidStudio插件实现,性能高
对比:
- 在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable
- Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。
- Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点,但此时还是建议使用Serializable 。
- Parcelable的速度比Serializable 高十倍以上,在Android中应该尽量采用Parcelable
- 实现Serializable接口这种方法的缺点是使用了反射,序列化的过程较慢,导致性能相对低下
- Parcelable方式的实现原理是将一个完整的对象进行分解,而分解后的每一部分都是Intent所支持的数据类型,这样也就实现传递对象的功能了(注意,在Activity跳转之间传入序列化的对象或者数据时,数据大小不能超过1M,对于数据量大的传输,推荐使用EventBus进行传输)
9. Android中可能引起内存泄露的原因?
- 资源对象没关闭或者Bitmap使用后没有调用recycle()释放内存
- 构造Adapter时,没有使用缓存的convertView
- 在单例中传入Context时传入的是Activity相关的Context(解决方案:使用Application的Context代替Activity相关的Context)
- 注册广播或者EventBus事件后没有在对应的生命周期取消注册
- 集合中对象没有清理造成内存泄露
- 使用Handler造成的内存泄露 Handler造成的内存泄露原因
- 非静态内部类/匿名内部类的静态实例容易造成内存泄漏 android-内部类导致的内存泄漏实战解析
10. 谈谈Android中四种启动模式?Intent的Flag属性?
彻底弄懂Activity四大启动模式
Android 深入解析 Activity 的 launchMode 启动模式,Intent Flag,taskAffinity
- standard: 每启动一个Activity都会创建一个新的实例。谁启动了该模式的Activity,该Activity就属于启动它的Activity的任务栈中,例如
Activity a
启动了Activity b
,那么Activity b
就属于Activity a
的任务栈中。 - singleTop: 该模式分两种情况:
- 当前栈中没有该Activity的实例或者当前栈中存在该Activity的实例但是不位于栈顶,此时其行为和standard启动模式一样,当启动该Activity还是会创建一个新的实例。
- 当前栈中已有该Activity的实例且该实例位于栈顶,当再启动该Activity时,不会再新建实例,而是复用栈顶的实例,并且会将Intent对象传入,回调
onNewIntent(Intent intent)
方法。
- singleTask: 在该模式下,只要当前栈中存在该Activity的实例,就会复用该Activity,并回调
onNewIntent(Intent intent)
方法。需要注意的是,在复用该Activity时,会将该Activity上的其他Activity全部出栈。该模式下,需要注意可以在activity配置文件中配置taskAffinity
属性,如果我们指定了自定义的taskAffinity属性值,那么启动该Activity时会创建一个新的Task(栈)并将当前Activity入栈道新创建的Task中。这样的话,我们可以将两个不同App中的Activity设置为相同的taskAffinity,这样虽然在不同的应用中,但是Activity会被分配到同一个Task中去。 - singleInstance: 该模式和singleTask差不多,它们之间的区别就是这种模式下的Activity会单独占用一个Task栈,具有全局唯一性,即整个系统中就这么一个实例。由于栈内复用的特性,后续的请求均不会创建新的Activity实例,除非这个特殊的任务栈被销毁了。以singleInstance模式启动的Activity在整个系统中是单例的,如果在启动这样的Activiyt时,已经存在了一个实例,那么会把它所在的任务调度到前台,重用这个实例。其实singleInstance启动模式和singleTask启动模式指定自定义的
taskAffinity
属性是一样的。
11. 谈谈你对Handler机制的理解?
12.谈谈Android中的事件分发机制?
Android事件分发机制完全解析,带你从源码的角度彻底理解(上)
Android事件分发机制完全解析,带你从源码的角度彻底理解(下)