每天10道:Android面试题整理三(附问题答案)
相信大家都知道面试也将来到了高峰期(秋招),想从事Android开发的话,相信下面的Android面题,大家一定会感兴趣的。
由于怕文章太长我就不做太多说明了,看题目就知道这是啥了,ok,废话不多说,看下面整理出来的题,希望可以对想从事Android开发的兄弟姐妹们有所帮助,下面的题整理出来的,并不全面,欢迎各位提问和补充!Android面试题和答案已按照规范已整理完成,大家可看文末或评论/私信,一起交流技术、进阶提升~
阐述一下 Activity 的生命周期
1、Activity 生命周期的顺序为:
onCreate() -> onContentChanged() -> onStart() -> onPostCreate()-> onResume() -> onPostResume -> onPause() -> onStop() -> onDestroy()
- onCreate() 方法:首次创建 Activity 时调用,应该在此方法中执行所有正常的静态设置 — 创建视图、将数据绑定到列表等等。
- onRestart() 方法:在 Activity 已停止(调用 onStop())并即将再次启动前调用,始终后接 onStart()
- onStart() 方法:在 Activity 即将对用户可见之前调用,可后接 onStop()进入隐藏状态
- onResume() 方法:在 Activity 即将开始与用户进行交互之前调用,始终后接 onPause()
- onPause() 方法:当系统即将开始继续另一个 Activity 时调用。用于确认对持久性数据的未保存更改、停止动画以及其他可能消耗 CPU 的内容。应该非常迅速地执行所需操作,因为它返回后,下一个 Activity 才能继续执行。
- onStop() 方法:在 Activity 对用户不再可见时调用。可后接 onRestart()。
- onDestroy() 方法:在 Activity 被销毁前调用。
2、方法调用后进程是否可终止问题:
- onCreate(),onRestart(),onStart(),onResume() 调用后,系统不能随时终止 Activity 进程。
- 而 onPause(),onStop(),onDestroy() 调用后,可以终止。
- Activity 创建后,必须要走到 onPause() 方法,然后才能终止进程 — 如果系统在紧急情况下必须恢复内存,则可能不会调用 onStop() 和 onDestroy()。
- 所以,在 onPause() 调用时,向存储设备写入至关重要的持久性数据(例如用户编辑)。
3、其他几个关键点
- onPause 必须先执行完,新 Activity 的 onResume 才会执行
- 新 Activity 采用透明主题或为 dialog 样式,当前 Activity 不会回调 onStop
- 异常终止问题
- Activity 异常终止时,会调用 onSaveInstanceState 来保存当前 Activity 状态,调用时机在 onStop 之前,和 onPause 没有固定顺序
- onRestoreInstanceState 方法调用时机在 onStart 之后
- onRestoreInstanceState 一旦被调用,其参数 Bundle savedInstanceState 一定是有值的,不用判断非空;而 onCreate 的 Bundle savedInstanceState 在正常启动时为 null
Android 应用中如何保存数据。
分为保存键值集(SharedPreferences)、保存文件(分为内部存储和外部存储)、在 SQL 数据库中保存数据以及在网络中使用网络存储和 ContentProvider。
其中:
- 键值集适合保存私有原始轻量化数据
- 内部存储适合保存私有数据
- 外部存储适合保存公共数据
- 私有数据库中适合保存结构化数据
- 网络存储需使用自己的网络服务器存储数据
为什么建议只使用默认的构造方法来创建 Fragment?
- 应当使用默认构造方法创建 Fragment,然后使用 setArguments 添加 Bundle 来传递参数
- 因为系统在储存 Fragment 的状态时(比如说屏幕旋转导致的重新加载),系统会为我们自动存储 Bundle
为什么 Bundle 被用来传递数据,为什么不能使用简单的 Map 数据结构?
原因一:速度和内存占用问题
- 使用 Bundle 传递数据一般用于启动 Activity,启动 Fragment 时,数据量一般都不大
- Bundle 内部由 ArrayMap 实现。ArrayMap 的内部实现是两个数组,一个数组存放 key 的 hashCode 值,一个数组存放 key 与 value 值。在查找、添加、删除数据时,会根据二分查找法查找 key 的 hashCode 值所对应的 index 值,再根据 index 去查找 key 所对应的 value 值
- HashMap 的实现则是采用数组加链表的结构,默认使用一个容量为 16 的数组来存储,数组中每一个元素又是一个链表的头节点
- 所以在小数据量的情况下,ArrayMap(Bundle) 比 HashMap 在速度和内存上都更占优势
原因二:序列化问题
- Android 中使用 Intent 来传递数据时,需要保证数据是基本数据类型或可序列化类型
- Bundle 使用 Parcelable 序列化,HashMap 使用 Serialable 序列化
- 在 Android 中,更推荐使用 Parcelable 序列化,因为 Serializable 接口使用了反射机制,这个过程相对缓慢,而且往往会产生出很多临时对象,可能会触发垃圾回收器频繁地进行垃圾回收。相比而言,Parcelable 接口比 Serializable 接口效率更高,性能方面要高出 10x 多倍。
什么是 ViewGroup ,它与 View 的区别在哪里?
- ViewGroup 是一个放置 View 的容器,继承自 View,是一种特殊的 View
- ViewGroup 的职能为:给 childView 计算出建议的宽、高和测量模式;决定 childView 的位置;
- View 的职能为:根据测量模式和 ViewGroup 建议的宽高计算出自己的宽和高;在 ViewGroup 为其指定的区域内绘制自己的形态。
Fragment 和 Activity 有什么区别?它们之间又有什么关系?
- Fragment 在 Android 3.0 后引入,可以翻译为碎片、片段
- Activity 为活动,代表着当前屏幕显示的一个窗口
- Fragment 可以重用,必须嵌套在 Activity 中使用,由 Activity 的 FragmentManager 管理,生命周期受 Activity 影响
AsyncTask 的原理?
1、首先调用 AsyncTask 的构造方法,构造时对 Handler、WorkerRunnable(Callable) 和 FutureTask 进行初始化
2、然后调用 AsyncTask 的 execute 方法(可以手动设置 Executor,不设置则使用系统默认的 SerialExecutor)
3、首先判断当前 AsyncTask 状态,正在运行或者已经运行过就退出
4、调用 onPreExecute 执行准备工作
5、由 Executor 调用 FutureTask 的 run 方法,在 WorkerRunnable 中执行了 doInBackground
6、依旧是在 WorkerRunnable 中,调用 postResult,将执行结果通过 Handler 发送给主线程;调用 publishProgress 时,也是通过 Handler 将消息发送到主线程的消息队列中
如何理解 Android 的 LocalBroadcastManager 。
- LocalBroadcastManager 为本地广播
- 使用这个机制发出的广播仅在应用内部传递
- 广播接收器也只能接收本应用发出的广播
- 本地广播比系统全局广播更加安全、有效
什么是 JobScheduler ?
- 当一定的条件(网络、时间、电量等)被满足时,JobScheduler 会为应用执行某项任务
- 与 AlarmManager 不同,JobScheduler 的执行时间是不确定的
- JobScheduler 允许同时执行多个任务
什么是 DDMS ?你可以用它来做什么?
- DDMS 是 Android 应用程序调试和分析工具,可以截屏、查看进程、线程、堆栈信息、Logcat、广播状态信息、模拟呼叫、短信、位置等
- 但是现在已经不推荐使用
- Android Studio 3.0 以后推荐使用 Android Profile 来分析网络、内存、cpu 使用状态
- 推荐使用 ADB 来发送命令、传文件、截图等
公众号:Android Jasper 专注分享面试题|面试技巧|Android学习资料。(dd:16)