致Android开发工程师:过了笔试,千万别栽在自己最擅长得技术面试上——70道Android技术面试题分享

2,337 阅读12分钟

在这里插入图片描述

前言

想进一线互联网大企业,辛辛苦苦获得了面试机会,过了笔试,然后却在自己最擅长的技术面试中败北;实在可惜,也有点不值,对自己的辛苦付出不值。那么今天笔者就给大家分享Android70道技术面试题,帮你绕过那些技术面的坑!

为了能够在面试回答中优雅而不失体面回答面试考点,本文借鉴了不同平台对知识点的描述。

  • 如有侵权请联系我
  • 文章的不足和错误请指正,好的建议也不要吝啬,我都会采纳并更正

正文[技术面试题]

1、Activity生命周期?

onCreate() -> onStart() -> onResume() -> onPause() -> onStop() -> onDetroy()

2、Service生命周期?

service 启动方式有两种,一种是通过startService()方式进行启动,另一种是通过bindService()方式进行启动。不同的启动方式他们的生命周期是不一样.

通过startService()这种方式启动的service,生命周期是这样:调用startService() --> onCreate()--> onStartConmon()--> onDestroy()。这种方式启动的话,需要注意一下几个问题,第一:当我们通过startService被调用以后,多次在调用startService(),onCreate()方法也只会被调用一次,而onStartConmon()会被多次调用当我们调用stopService()的时候,onDestroy()就会被调用,从而销毁服务。第二:当我们通过startService启动时候,通过intent传值,在onStartConmon()方法中获取值的时候,一定要先判断intent是否为null。

通过bindService()方式进行绑定,这种方式绑定service,生命周期走法:bindService-->onCreate()-->onBind()-->unBind()-->onDestroy() bingservice 这种方式进行启动service好处是更加便利activity中操作service,比如加入service中有几个方法,a,b ,如果要在activity中调用,在需要在activity获取ServiceConnection对象,通过ServiceConnection来获取service中内部类的类对象,然后通过这个类对象就可以调用类中的方法,当然这个类需要继承Binder对象

3、Activity的启动过程(不要回答生命周期)

app启动的过程有两种情况,第一种是从桌面launcher上点击相应的应用图标,第二种是在activity中通过调用startActivity来启动一个新的activity。

我们创建一个新的项目,默认的根activity都是MainActivity,而所有的activity都是保存在堆栈中的,我们启动一个新的activity就会放在上一个activity上面,而我们从桌面点击应用图标的时候,由于launcher本身也是一个应用,当我们点击图标的时候,系统就会调用startActivitySately(),一般情况下,我们所启动的activity的相关信息都会保存在intent中,比如action,category等等。我们在安装这个应用的时候,系统也会启动一个PackaManagerService的管理服务,这个管理服务会对AndroidManifest.xml文件进行解析,从而得到应用程序中的相关信息,比如service,activity,Broadcast等等,然后获得相关组件的信息。当我们点击应用图标的时候,就会调用startActivitySately()方法,而这个方法内部则是调用startActivty(),而startActivity()方法最终还是会调用startActivityForResult()这个方法。而在startActivityForResult()这个方法。因为startActivityForResult()方法是有返回结果的,所以系统就直接给一个-1,就表示不需要结果返回了。而startActivityForResult()这个方法实际是通过Instrumentation类中的execStartActivity()方法来启动activity,Instrumentation这个类主要作用就是监控程序和系统之间的交互。而在这个execStartActivity()方法中会获取ActivityManagerService的代理对象,通过这个代理对象进行启动activity。启动会就会调用一个checkStartActivityResult()方法,如果说没有在配置清单中配置有这个组件,就会在这个方法中抛出异常了。当然最后是调用的是Application.scheduleLaunchActivity()进行启动activity,而这个方法中通过获取得到一个ActivityClientRecord对象,而这个ActivityClientRecord通过handler来进行消息的发送,系统内部会将每一个activity组件使用ActivityClientRecord对象来进行描述,而ActivityClientRecord对象中保存有一个LoaderApk对象,通过这个对象调用handleLaunchActivity来启动activity组件,而页面的生命周期方法也就是在这个方法中进行调用。

4、Broadcast注册方式与区别

此处延伸:什么情况下用动态注册

Broadcast广播,注册方式主要有两种.

第一种是静态注册,也可成为常驻型广播,这种广播需要在Androidmanifest.xml中进行注册,这中方式注册的广播,不受页面生命周期的影响,即使退出了页面,也可以收到广播这种广播一般用于想开机自启动啊等等,由于这种注册的方式的广播是常驻型广播,所以会占用CPU的资源。

第二种是动态注册,而动态注册的话,是在代码中注册的,这种注册方式也叫非常驻型广播,收到生命周期的影响,退出页面后,就不会收到广播,我们通常运用在更新UI方面。这种注册方式优先级较高。最后需要解绑,否会会内存泄露

广播是分为有序广播和无序广播。

5、HttpClient与HttpUrlConnection的区别

此处延伸:Volley里用的哪种请求方式(2.3前HttpClient,2.3后HttpUrlConnection)

首先HttpClient和HttpUrlConnection 这两种方式都支持Https协议,都是以流的形式进行上传或者下载数据,也可以说是以流的形式进行数据的传输,还有ipv6,以及连接池等功能。HttpClient这个拥有非常多的API,所以如果想要进行扩展的话,并且不破坏它的兼容性的话,很难进行扩展,也就是这个原因,Google在Android6.0的时候,直接就弃用了这个HttpClient.

而HttpUrlConnection相对来说就是比较轻量级了,API比较少,容易扩展,并且能够满足Android大部分的数据传输。比较经典的一个框架volley,在2.3版本以前都是使用HttpClient,在2.3以后就使用了HttpUrlConnection。

6、讲解一下Context

Context是一个抽象基类。在翻译为上下文,也可以理解为环境,是提供一些程序的运行环境基础信息。Context下有两个子类,ContextWrapper是上下文功能的封装类,而ContextImpl则是上下文功能的实现类。而ContextWrapper又有三个直接的子类, ContextThemeWrapper、Service和Application。其中,ContextThemeWrapper是一个带主题的封装类,而它有一个直接子类就是Activity,所以Activity和Service以及Application的Context是不一样的,只有Activity需要主题,Service不需要主题。Context一共有三种类型,分别是Application、Activity和Service。这三个类虽然分别各种承担着不同的作用,但它们都属于Context的一种,而它们具体Context的功能则是由ContextImpl类去实现的,因此在绝大多数场景下,Activity、Service和Application这三种类型的Context都是可以通用的。不过有几种场景比较特殊,比如启动Activity,还有弹出Dialog。出于安全原因的考虑,Android是不允许Activity或Dialog凭空出现的,一个Activity的启动必须要建立在另一个Activity的基础之上,也就是以此形成的返回栈。而Dialog则必须在一个Activity上面弹出(除非是System Alert类型的Dialog),因此在这种场景下,我们只能使用Activity类型的Context,否则将会出错。

getApplicationContext()和getApplication()方法得到的对象都是同一个application对象,只是对象的类型不一样。

Context数量 = Activity数量 + Service数量 + 1 (1为Application)

7、理解Activity,View,Window三者关系

这个问题真的很不好回答。所以这里先来个算是比较恰当的比喻来形容下它们的关系吧。Activity像一个工匠(控制单元),Window像窗户(承载模型),View像窗花(显示视图)LayoutInflater像剪刀,Xml配置像窗花图纸。

1:Activity构造的时候会初始化一个Window,准确的说是PhoneWindow。

2:这个PhoneWindow有一个“ViewRoot”,这个“ViewRoot”是一个View或者说ViewGroup,是最初始的根视图。

3:“ViewRoot”通过addView方法来一个个的添加View。比如TextView,Button等

4:这些View的事件监听,是由WindowManagerService来接受消息,并且回调Activity函数。比如onClickListener,onKeyDown等。

10、四种LaunchMode及其使用场景

此处延伸:栈(First In Last Out)与队列(First In First Out)的区别

8、保存Activity状态

onSaveInstanceState(Bundle)会在activity转入后台状态之前被调用,也就是onStop()方法之前,onPause方法之后被调用;

9、Android中的几种动画

帧动画:指通过指定每一帧的图片和播放时间,有序的进行播放而形成动画效果,比如想听的律动条。

补间动画:指通过指定View的初始状态、变化时间、方式,通过一系列的算法去进行图形变换,从而形成动画效果,主要有Alpha、Scale、Translate、Rotate四种效果。注意:只是在视图层实现了动画效果,并没有真正改变View的属性,比如滑动列表,改变标题栏的透明度。

属性动画:在Android3.0的时候才支持,通过不断的改变View的属性,不断的重绘而形成动画效果。相比于视图动画,View的属性是真正改变了。比如view的旋转,放大,缩小。

10、Android中跨进程通讯的几种方式

Android 跨进程通信,像intent,contentProvider,广播,service都可以跨进程通信。

intent:这种跨进程方式并不是访问内存的形式,它需要传递一个uri,比如说打电话。

contentProvider:这种形式,是使用数据共享的形式进行数据共享。

service:远程服务,aidl

其他Android面试题

Activity

11、onSaveInstanceState(),onRestoreInstanceState的掉用时机 12、activity的启动模式和使用场景 13、Activity A跳转Activity B,再按返回键,生命周期执行的顺序 14、横竖屏切换,按home键,按返回键,锁屏与解锁屏幕,跳转透明Activity界面,启动一个 Theme 为 Dialog 的 Activity,弹出Dialog时Activity的生命周期 15、onStart 和 onResume、onPause 和 onStop 的区别 16、Activity之间传递数据的方式Intent是否有大小限制,如果传递的数据量偏大,有哪些方案 17、Activity的onNewIntent()方法什么时候执行 18、显示启动和隐式启动 19、scheme使用场景,协议格式,如何使用 20、ANR 的四种场景 21、onCreate和onRestoreInstance方法中恢复数据时的区别 22、activty间传递数据的方式 23、跨App启动Activity的方式,注意事项 24、Activity任务栈是什么 25、有哪些Activity常用的标记位Flags 26、Activity的数据是怎么保存的,进程被Kill后,保存的数据怎么恢复的

Service

26、service 的生命周期,两种启动方式的区别 27、Service与Activity怎么实现通信 28、IntentService是什么,IntentService原理,应用场景及其与Service的区别 29、Service 的 onStartCommand 方法有几种返回值?各代表什么意思? 30、bindService和startService混合使用的生命周期以及怎么关闭

BroadcastReceiver

31、广播的分类和使用场景 32、广播的两种注册方式的区别 33、广播发送和接收的原理 34、本地广播和全局广播的区别

ContentProvider

35、什么是ContentProvider及其使用 36、ContentProvider,ContentResolver,ContentObserver之间的关系 37、ContentProvider的实现原理 38、ContentProvider的优点 39、Uri 是什么

Handler

40、Handler的实现原理 41、子线程中能不能直接new一个Handler,为什么主线程可以 42、Handler导致的内存泄露原因及其解决方案 43、一个线程可以有几个Handler,几个Looper,几个MessageQueue对象 44、Message对象创建的方式有哪些 & 区别 45、Handler 有哪些发送消息的方法 46、Handler的post与sendMessage的区别和应用场景 47、handler postDealy后消息队列有什么变化,假设先 postDelay 10s, 再postDelay 1s, 怎么处理这2条消息sendMessageDelayed-sendMessageAtTime-sendMessage 48、MessageQueue是什么数据结构 49、Handler怎么做到的一个线程对应一个Looper,如何保证只有一个MessageQueue ThreadLocal在Handler机制中的作用 50、HandlerThread是什么 & 好处 &原理 & 使用场景 51、IdleHandler及其使用场景 52、消息屏障,同步屏障机制what 53、子线程能不能更新UI 54、为什么Android系统不建议子线程访问UI 55、Android中为什么主线程不会因为Looper.loop()里的死循环卡死? 56、Handler消息机制中,一个looper是如何区分多个Handler的当Activity有多个Handler的时候,怎么样区分当前消息由哪个Handler处理处理message的时候怎么知道是去哪个callback处理的 57、Looper.quit/quitSafely的区别 58、通过Handler如何实现线程的切换 59、Handler 如何与 Looper 关联的

View绘制

60、View绘制流程 61、MeasureSpec是什么 62、子View创建MeasureSpec创建规则是什么 63、自定义Viewwrap_content不起作用的原因 64、在Activity中获取某个View的宽高有几种方法 65、为什么onCreate获取不到View的宽高 66、View#post与Handler#post的区别 67、Android绘制和屏幕刷新机制原理 68、Choreography原理 69、什么是双缓冲 70、为什么使用SurfaceView

写在最后

限于篇幅,本文无法给出所有的Android技术面试题答案(其中还有View事件分发、RecycleView、Viewpager&Fragment、WebView、动画、Bitmap、mvc&mvp&mvvm、Binder、内存泄漏&内存溢出、性能优化、Window&WindowManager、AMS、系统启动、App启动&打包&安装、序列化、Art & Dalvik 及其区别、模块化&组件化、热修复&插件化、AOP、jectpack、开源框架等全方面的面试题),需要的的朋友点击我的Gitee即可免费领取PDF版完整文档

如果本文能够在你面试的道路上锦上添花,那么请不要吝啬你的赞,也请帮忙转发一下! 在这里插入图片描述