20个基本的安卓面试问题 *
Toptal搜集了最优秀的Android开发人员和工程师可以回答的基本问题. 在我们社区的推动下,我们鼓励专家提交问题并提供反馈.
聘请顶尖的Android开发者面试问题
这四个Java类涉及到传感器在Android平台上的使用
-
Sensor
:提供方法来识别特定传感器可用的功能. -
SensorManager
提供注册传感器事件侦听器和校准传感器的方法. -
SensorEvent
:提供原始传感器数据,包括有关精度的信息. -
SensorEventListener
接口,该接口定义了接收传感器事件通知的回调方法.
要了解更多关于 sensors,请参考Android开发者指南.
A 内容提供者
管理对结构化数据集的访问. 它封装数据并提供定义数据安全性的机制. 内容提供者
将一个进程中的数据与另一个进程中运行的代码连接起来的标准接口是否存在.
可以找到有关内容提供者的更多信息 here Android开发者指南.
下面的代码示例在什么情况下会使应用程序崩溃? 如何修改代码以避免这个潜在的问题? 解释你的答案.
sendIntent = new Intent();
sendIntent.setAction(意图.ACTION_SEND);
sendIntent.putExtra(意图.EXTRA_TEXT textMessage);
sendIntent.setType(HTTP.PLAIN_TEXT_TYPE); // "text/plain" MIME type
startActivity (sendIntent);
隐式意图指定一个操作,该操作可以调用设备上任何能够执行该操作的应用. 当你的应用不能执行动作时,使用隐式意图是很有用的, 但其他应用可能可以. 如果有多个已注册的应用程序可以处理此请求, 用户将被提示选择使用哪一个.
然而,有可能没有应用程序可以处理你的意图. 在这种情况下,调用时应用程序将崩溃 startActivity ()
. 为了避免这种情况,在打电话之前 startActivity ()
您应该首先验证系统中至少有一个注册的应用程序可以处理该意图. 要做到这一点,使用 resolveActivity ()
在你的意图对象上:
//验证是否有应用程序注册来处理这个意图
//(如果没有注册,resolveActivity返回null)
如果(sendIntent.resolveActivity (getPackageManager ()) != null) {
startActivity (sendIntent);
}
参见Android开发者指南 更多的信息 关于内隐意图.
申请加入Toptal的发展网络
并享受可靠、稳定、远程 自由Android开发者职位
Normally, 在进行屏幕重新定向的过程中, Android平台会删除前台活动并重新创建它, 恢复活动布局中的每个视图值.
在你正在开发的应用程序中, 你注意到视图的值在屏幕重定向后没有被恢复. 您应该验证的问题的可能原因是什么, at a minimum, 关于那个特定的观点?
您应该验证它是否具有有效的 id
. 为了让Android系统在你的活动中恢复视图的状态, 每个视图必须有一个唯一的ID, 由 android:id
attribute.
更多信息请访问 here.
活动生命周期中的最后一个回调是 onDestroy()
. 系统在你的activity上调用这个方法,作为你的activity实例被完全从系统内存中移除的最后信号. 通常,系统会调用 onPause()
and onStop()
在调用之前 onDestroy()
. 不过,请描述一个场景 onPause()
and onStop()
would not be invoked.
onPause()
and onStop()
会不会被调用 finish()
的内部调用 onCreate()
method. 例如,如果在过程中检测到错误,就可能发生这种情况 onCreate()
and call finish()
as a result. 但是,在这种情况下,您期望的任何清理都将在 onPause()
and onStop()
不会被执行.
Although onDestroy()
最后一个回调是在一个活动的生命周期吗, 值得一提的是,这个回调可能并不总是被调用,也不应该依赖它来销毁资源. 最好是有资源创建在 onStart()
and onResume()
,并将其销毁 onStop()
and onPause()
分别.
参见Android开发者指南 更多的信息 关于活动生命周期.
下面哪个代码片段是检查系统上是否存在Compass传感器的正确方法? 解释你的答案.
Answer 1:
PackageManager m = getPackageManager();
if (!m.hasSystemFeature (PackageManager.FEATURE_SENSOR_COMPASS)) {
//该设备没有指南针,请关闭指南针功能
}
Answer 2:
SensorManager = getSensorManager();
if (!m.hasSystemFeature (SensorManager.FEATURE_SENSOR_COMPASS)) {
//该设备没有指南针,请关闭指南针功能
}
Answer 3:
Sensor s = getSensor();
if (!s.hasSystemFeature(传感器.FEATURE_SENSOR_COMPASS)) {
//该设备没有指南针,请关闭指南针功能
}
正确答案是 Answer 1的版本 PackageManager
.
SensorManager
and Sensor
是Android传感器框架的一部分,用于直接访问和获取原始传感器数据. 这些类不提供任何方法 hasSystemFeature ()
哪个用于系统能力的评估.
Android定义功能id, 以enum的形式, 设备上可用的任何硬件或软件功能. 例如,罗盘传感器的特征ID为 FEATURE_SENSOR_COMPASS
.
如果系统上没有可用的特定特性,应用程序就无法工作, 你可以阻止用户安装你的应用
元素来指定一个不可协商的依赖项.
However, 如果您只是想在缺少某个特性时禁用应用程序的特定元素, 你可以使用 PackageManager
class. PackageManager
用于检索与设备上当前安装的应用程序包相关的各种信息.
要了解更多关于 兼容性和处理不同类型的设备 or sensors 请参考Android开发者指南.
的常用用例 Intent
include:
-
启动一个活动:你可以通过传递Intent来启动一个Activity的新实例
startActivity ()
method. -
启动一个服务:你可以通过传递Intent来启动一个服务来执行一次性操作(比如下载文件)
startService ()
. -
播送广播:你可以通过传递Intent来传递一个广播到其他应用
sendBroadcast ()
,sendOrderedBroadcast ()
, orsendStickyBroadcast ()
.
更多关于 intents 可以在Android开发者指南中找到.
假设你在Activity中启动一个服务,如下所示:
Intent service = new Intent(context, MyService).class);
startService(服务);
where MyService
通过Internet连接访问远程服务器.
如果Activity正在显示一个动画来指示某种进度, 你可能会遇到什么问题,你如何解决它?
通过Internet的远程服务的响应通常需要一些时间, 要么是因为网络延迟, 或者在远程服务器上加载, 或者远程服务处理和响应请求所需的时间.
As a result, 如果发生这样的延迟, 活动中的动画(甚至更糟), 在客户端等待服务的响应时,整个UI线程可能会被阻塞,并且在用户看来可能会被“冻结”. 这是因为服务是在Activity中的主应用程序线程(或UI线程)上启动的.
可以(而且应该)通过将任何此类远程请求降级到后台线程或线程中来避免这个问题, when feasible, 使用异步响应机制.
Note well: 在较新的Android版本中,从UI线程访问网络会抛出一个运行时异常,导致应用程序崩溃.
DDMS is the Dalvik调试监控服务器 Android自带的. 它提供了广泛的调试功能,包括:
- 端口转发服务
- 屏幕截图
- 线程和堆信息
- 网络流量跟踪
- 来电和短信欺骗
- 模拟网络状态、速度和延迟
- 位置数据欺骗
AsyncTask与包含它的Activity的生命周期无关. So, for example, 如果你在Activity中启动AsyncTask并且用户旋转设备, Activity将被销毁(并创建一个新的Activity实例),但是AsyncTask将被销毁 not 死去,而是继续活着,直到生命结束.
Then, 当AsyncTask完成时, 而不是更新新Activity的UI, 它更新了 former 活动(i)的实例.e.,即创建它的目录,但不再显示!). 这可能导致该类型的异常 java.lang.IllegalArgumentException
:视图未附加到窗口管理器 例如,如果你用, findViewById
来检索Activity中的视图).
这也有可能导致内存泄漏,因为AsyncTask维护对activity的引用, 这可以防止垃圾收集的活动,只要AsyncTask仍然活着.
由于这些原因,使用AsyncTasks long-running 后台任务通常是一个坏主意 . Rather, for long-running 对于后台任务,应该采用不同的机制(例如服务).
The Intent
对象是启动新活动和将数据从一个活动传输到另一个活动的通用机制. 但是,您不能启动 内容提供者
using an Intent
.
中访问数据时 内容提供者
,则必须使用 ContentResolver
对象中的 Context
作为客户端与提供者进行通信. The ContentResolver
对象与提供程序对象通信,提供程序对象是实现 内容提供者
. 提供者对象接收来自客户机的数据请求, 执行请求的操作, 并返回结果.
An activity 通常是单一的, 用户可以执行的重点操作(如拨号), 拍张照片, send an email, view a map, etc.). 然而与此同时, 没有什么可以阻止开发人员创建任意复杂的活动.
活动实现可以选择性地使用 Fragment类 用于生成更模块化的代码等目的, 为更大的屏幕构建更复杂的用户界面, 帮助在小屏幕和大屏幕之间扩展应用程序, and so on. 多个片段可以在单个活动中组合, conversely, 相同的片段通常可以跨多个活动重用. 这种结构主要是为了促进代码重用和促进规模经济.
片段本质上是活动的模块化部分, 具有自己的生命周期和输入事件, 并且可以随意添加或删除. 记住这一点很重要, though, that a fragment’s lifecycle is directly affected by its host activity’s lifecycle; i.e., 当活动暂停时, 所有的碎片都是如此, 当活动被破坏时, 所有的碎片也是如此.
更多信息请访问 here Android开发者指南.
Serializable是一个标准的Java接口. 您只需通过实现接口将类标记为可序列化的, Java会在某些情况下自动序列化它.
Parcelable是一个Android特定的接口,你可以自己实现序列化. 它的创建是为了比Serializable高效得多, 并绕过默认Java序列化方案的一些问题.
“启动模式”是将活动的新实例与当前任务相关联的方式.
启动模式可以使用以下两种机制之一来定义:
-
Manifest file. 在清单文件中声明活动时, 您可以指定活动在启动时应该如何与任务关联. 支持的值包括:
-
standard
(default). 活动类的多个实例可以被实例化,多个实例可以被添加到相同的任务或不同的任务中. 这是大多数活动的通用模式. -
singleTop
. 区别在于standard
is, 如果活动的实例已经存在于当前任务的顶部,并且系统将意图路由到该活动, 不会创建新的实例,因为它将触发一个onNewIntent()
方法,而不是创建新对象. -
singleTask
. 将始终创建一个新任务,并将一个新实例作为根推送到该任务. However, 如果任何活动实例存在于任何任务中, 方法将意图路由到该活动实例onNewIntent()
method call. 在这种模式下,活动实例可以被推送到相同的任务. 此模式对于充当入口点的活动非常有用. -
singleInstance
. Same assingleTask
除了no activities实例可以被推入singleInstance的相同任务之外. 因此,具有启动模式的活动总是在单个活动实例任务中. 这是一种非常特殊的模式,应该只在完全作为一个活动实现的应用程序中使用.
-
-
Intent flags. Calls to startActivity () 可以在 Intent 它声明新活动是否以及如何与当前任务相关联. 支持的值包括:
-
FLAG_ACTIVITY_NEW_TASK
. Same assingleTask
清单文件中的值(见上文). -
FLAG_ACTIVITY_SINGLE_TOP
. Same assingleTop
清单文件中的值(见上文). -
FLAG_ACTIVITY_CLEAR_TOP
. 如果正在启动的活动已经在当前任务中运行, 然后不启动该活动的新实例, 它上面的所有其他活动都被销毁,这个意图被传递给该活动的恢复实例(现在在上面)。, throughonNewIntent()
. 清单文件中没有产生此行为的相应值.
-
更多关于发射模式的信息 here.
Service
Android服务的基类是否可以扩展为创建任何服务. 直接扩展的类 Service
在主线程上运行,所以它会阻塞UI(如果有的话),因此应该只用于短任务,或者应该使用其他线程来执行较长的任务.
IntentService
的子类是 Service
按需处理异步请求(表示为“意图”). 客户端通过 startService(意图)
calls. 服务根据需要启动,处理每个 Intent
反过来使用工作线程,并在工作耗尽时停止自己. Writing an IntentService
can be quite simple; just extend the IntentService
类并重写 onHandleIntent(目的意图)
方法,您可以在其中管理所有传入请求.
的构造参数 Fragment
通过 Bundle
using the 片段# setArgument(包)
method. The passed-in Bundle
然后可以通过 片段# getArguments ()
方法中适当的 Fragment
生命周期方法.
通过自定义构造函数传递数据是一个常见的错误. 类上的非默认构造函数 Fragment
不可取是因为 Fragment
可能由于配置更改而销毁并重新创建(例如.g. 方向变化). Using # setArguments ()
/getArguments ()
确保在需要重新创建Fragment时 Bundle
是否适当地序列化/反序列化,以便恢复施工数据.
Android中的“ANR”是“应用程序没有响应”.这意味着当用户与活动交互时,活动在 onResume()
方法时,将出现一个显示“应用程序未响应”的对话框.”
这是因为我们在主UI线程中启动了一个繁重且长时间运行的任务,比如下载数据. 这个问题的解决方案是在后台使用Async Task类启动繁重的任务.
面试不仅仅是棘手的技术问题, 所以这些只是作为一个指南. 并不是每一个值得雇佣的“A”候选人都能回答所有的问题, 回答所有问题也不能保证成为A级考生. 一天结束的时候, 招聘仍然是一门艺术,一门科学,需要大量的工作.
Why Toptal
提出面试问题
提交的问题和答案将被审查和编辑, 并可能会或可能不会选择张贴, 由Toptal全权决定, LLC.
寻找Android开发者?
Looking for Android开发者? 看看Toptal的Android开发者吧.
穆罕默德Mutahr
自由Android开发者
Muhammad是一名高级软件工程师,在公共教育部门(WSU), 私营医疗保健公司(Meridian), 汽车行业的财富500强上市公司(通用汽车 & AAM). 在他的职业生涯中, 他用HTML/CSS设计网页应用, 使用JavaScript框架(Angular/Ionic)开发客户端应用, 并使用Java和c#开发健壮的服务器端应用程序.
Show More鲍里斯Yordanov
自由Android开发者
Boris是一名全职web开发人员,主要使用香草JS和最流行的JavaScript框架(如Angular), React, and Meteor. 14岁时,他创建了自己的第一个网站, 从那时起, 在他的自由职业生涯中,他已经创建了400多个WordPress网站. 现在,他设计和构建定制的web应用程序和网站.
Show MoreToptal连接 Top 3% 世界各地的自由职业人才.
加入Toptal社区.