应届毕业生可以去刷算法来拿到不错的offer,但社招不行。
技术要求面试前的准备
- 良好的开发习惯
- 独立思考的能力
- 主动并且善于沟通
高级安卓所要掌握的知识点。
- 一,基本知识点
- 二,深入知识点
- 三,基本知识点的细节
- 四,系统核心机制
如果遇到自己不懂的问题,绝对不能说不知道。就算不知道,也要把面试官的问题。复述一遍,拆解成123小点来。阐述自己知道的东西,显示自己的能力。
感悟
1.选一个自己比较擅长的领域(比如网络框架OKhttp)去了解它的内部实现,用流程图画出调用逻辑
2.基础要背,安卓四大组件,常用API,要把它背的滚瓜乱熟。
3.试着去了解这个领域市面上的技术(热更新,rxjava 等)
4.如果有时间研究,其中一个众所周知的库的源码。
Activity面试详解
1.Activity生命周期
Activity的四种状态:running/paused/stoped/killed
onCreate : 该方法是在Activity被创建时回调,它是生命周期第一个调用的方法,我们在创建Activity时一般都需要重写该方法,然后在该方法中做一些初始化的操作,如通过setContentView设置界面布局的资源,初始化所需要的组件信息等。
onStart : 此方法被回调时表示Activity正在启动,此时Activity已处于可见状态,只是还没有在前台显示,因此无法与用户进行交互。可以简单理解为Activity已显示而我们无法看见摆了。
onResume : 当此方法回调时,则说明Activity已在前台可见,可与用户交互了(处于前面所说的Active/Running形态),onResume方法与onStart的相同点是两者都表示Activity可见,只不过onStart回调时Activity还是后台无法与用户交互,而onResume则已显示在前台,可与用户交互。当然从流程图,我们也可以看出当Activity停止后(onPause方法和onStop方法被调用),重新回到前台时也会调用onResume方法,因此我们也可以在onResume方法中初始化一些资源,比如重新初始化在onPause或者onStop方法中释放的资源。
onPause : 此方法被回调时则表示Activity正在停止(Paused形态),一般情况下onStop方法会紧接着被回调。但通过流程图我们还可以看到一种情况是onPause方法执行后直接执行了onResume方法,这属于比较极端的现象了,这可能是用户操作使当前Activity退居后台后又迅速地再回到到当前的Activity,此时onResume方法就会被回调。当然,在onPause方法中我们可以做一些数据存储或者动画停止或者资源回收的操作,但是不能太耗时,因为这可能会影响到新的Activity的显示——onPause方法执行完成后,新Activity的onResume方法才会被执行。
onStop : 一般在onPause方法执行完成直接执行,表示Activity即将停止或者完全被覆盖(Stopped形态),此时Activity不可见,仅在后台运行。同样地,在onStop方法可以做一些资源释放的操作(不能太耗时)。
onRestart :表示Activity正在重新启动,当Activity由不可见变为可见状态时,该方法被回调。这种情况一般是用户打开了一个新的Activity时,当前的Activity就会被暂停(onPause和onStop被执行了),接着又回到当前Activity页面时,onRestart方法就会被回调。
onDestroy :此时Activity正在被销毁,也是生命周期最后一个执行的方法,一般我们可以在此方法中做一些回收工作和最终的资源释放。
android进程优先级:前台/可见/服务/后台/空
2.Android任务栈
一个应用程序当中通常都会包含很多个Activity,每个Activity都应该设计成为一个具有特定的功能,并且可以让用户进行操作的组件。另外,Activity之间还应该是可以相互启动的。
除此之外,一个Activity甚至还可以去启动其它应用程序当中的Activity。打个比方,如果你的应用希望去发送一封邮件,你就可以定义一个具有"send"动作的Intent,并且传入一些数据,如对方邮箱地址、邮件内容等。这样,如果另外一个应用程序中的某个Activity声明自己是可以响应这种Intent的,那么这个Activity就会被打开。在当前场景下,这个Intent是为了要发送邮件的,所以说邮件应用程序当中的编写邮件Activity就应该被打开。当邮件发送出去之后,仍然还是会回到你的应用程序当中,这让用户看起来好像刚才那个编写邮件的Activity就是你的应用程序当中的一部分。所以说,即使有很多个Activity分别都是来自于不同应用程序的,Android系统仍然可以将它们无缝地结合到一起,之所以能实现这一点,就是因为这些Activity都是存在于一个相同的任务(Task)当中的。
3.Activity启动模式
- standard:默认
- singletop:栈顶复用,onNewIntent()会被调用
- singletask:栈内复用,onNewIntent()会被调用
- singleinstance:只有一个实例,独享任务栈
4.scheme跳转协议
android中的scheme是一种页面内跳转协议,应用场景:
服务端下发一个url路径,客户端根据此路径,跳转到相应的页面
从H5页面跳转到相应app的activity
app根据url跳转到另一个app
Fragment
1.Fragment为什么被成为第五大组件
使用频率高,并且有声明周期,相比activity更节省内存,UI切换效果也更加舒适。
2.Fragment加载到Activity的两种方式
静态加载。添加到Fragment到Activity的布局文件当中,Fragment作为xml的标签
动态加载。动态在activity中添加fragment,用fragmentManager,利用容器资源id表示位来确定位置
3.FragmentPagerAdapter与FragmentStatePagerAdapter的区别
FragmentPagerAdapter适用于页面较少的情况,FragmentStatePagerAdapter适用于页面较多的情况。
FragmentStatePagerAdapter源码中的destoryItem()方法是调用了Fragment事务管理器的remove(),释放了Fragment所占的内存;FragmentPagerAdapter的destoryItem()内则调用了Fragment事务管理器的detach(),只是将Fragment与Activity分离,并不回收内存
4.Fragment的生命周期
onAttach()
onCreate():用于创建Fragment
onCreateView():绘制Fragment UI
onViewCreated():Fragment UI已绘制好,可以初始化Fragment里的控件资源
5.Fragment通信
1.在Fragment中调用Activity中的方法getActivity()
2.在Activity中调用Fragment中的方法 使用接口回调
3.在Fragment中调用Fragment中的方法 首先通过getActivity(),然后调用findFragmentById()
Service
Service是什么?
是一个一种可以在后台执行长时间运行操作而没有用户界面的应用组件。不能做耗时操作!!
service和Thread的区别
Thread程序执行的最小单元,相对独立,Service是Android的四大组件之一,被用来执行长时间的后台任务。默认情况下Service是运行在主线程中的。
他们之间没有任何关联,android中后台与子线程是不同的概念,android的后台指完全不依赖于UI线程,即使activity被销毁了,服务进程仍然存在运行;service不能做耗时操作
应用场景上,当需要去访问网络、文件查询,都应开启子线程去操作,避免UI阻塞;而service主要是用来长时间在后台运行,而不需要交互的情况下,如后台播放音乐、天气预报的统计
如果需要执行复杂耗时的操作,必须在Service中再创建一个Thread来执行任务。Service的优先级高于后台挂起的Activity,当然也高于Activity所创建的Thread,因此,系统可能在内存不足的时候优先杀死后台的Activity或者Thread,而不会轻易杀死Service组件,即使被迫杀死Service,也会在资源可用时重启被杀死的Service。
详解参考:https://blog.csdn.net/mynameishuangshuai/article/details/51821662
service的启动方式
1.startService():
①,定义一个类继承Service;
②,在清单文件中配置改service;
③,使用Context的startService(intent)方法启动该服务;
④,不再使用时,调用stopService(intent)方法停止该服务。
注意onStartCommand()的返回值,START_STICKY:系统因内存不足杀死service,一段时间内存充足后,会重新启动该service
2.bindService()
绑定服务的时候,服务和Activity处于绑定状态。允许Activity和Service进行数据交互(客户端和服务端)。发送请求获取结果等。甚至服务在不同进程间的时候。可以进行进程间通信传输数据。多个界面可以绑定同一个服务。当绑定全部取消,服务会自动被销毁。不必像startService(),要stopService()。
步骤:
1.创建BindService服务端,继承自Service并在类中,创建一个实现IBinder接口的实例对象,并提供公共方法给客户端调用
2.从onBind()回调方法返回此Binder实例;
3.在客户端中,从onServiceConnected()回调方法接收Binder,并使用提供的方法调用绑定服务。
BroadcaseReceiver
在android中,broadcast是一种广泛运用的在应用程序之间传输信息的机制,android中我们要发送的广播内容是一个Intent,这个Intent中可以携带我们要传送的数据。
广播的场景
同一app具有多个进程的不同组件之间的消息通信
不同app之间的组件之间消息通信
广播的种类
Normal Broadcast:Context.sendBroadcast
System Broadcast:Context.sendOrderedBroadcast
Local Broadcast:只在自身App内传播
实现广播-receiver
静态注册:注册完成就一直运行,在清单文件中
动态注册:跟随activity的生命周期
内部实现机制
1.自定义广播接收者BroadcastReceiver,并复写onReceive()方法;
2.通过Binder机制(android进程间通信的核心,整体架构是C/S结构,)向AMS(Activity Manager Service,负责四大机制的启动、切换、调度)进行注册;
3.广播发送者通过Binder机制向AMS发送广播;
4.AMS查找符合相应条件(IntentFilter/Permission等)的BroadcastReceiver,将广播发送到BraodcastReceiver(一般情况 下是Activity)相应的消息循环队列中;
5.消息循环执行拿到此广播,回调BroadcastReceiver中的onReceive()方法
LocalBroadcastManager详解
1.使用它发送的广播将只有在自身App内传播,因此不必担心泄漏隐私数据
2.其他App无法对你的App发送该广播,因为你的App根本就不可能接收到非自身应用发送的广播,因此你不必担心有安全漏洞可以利用
3.比系统的全局广播更加高效
LocalBroadcastManager源码分析:
1.LocalBroadcastManager高效的原因主要是因为它内部是通过Handler实现的,它的sendBroadcast()方法含义并非和我们平时所用的一样,他的sendBroadcast()方法其实是通过handler发送一个Message实现的。
2.既然它内部是通过Handler来实现广播发送,那么相比与系统广播通过Binder实现,那肯定是更高效了,同时使用Handler来实现,别的应用无法向我们的应用发送该广播,而我们应用内发送的广播也不会离开我们的应用
3.LocalBroadcastManager内部协作主要是靠这两个Map集合:mReceivers和mActions,当然还有一个List集合mPendingBroadcasts,这个主要就是存储待接收的广播对象
Binder
Binder是Android跨进程通信方式,它实现了IBinder接口,是ServiceManager连接各种Manager(如WindowManager、ActivityManager等)的桥梁
参考:https://blog.csdn.net/huachao1001/article/details/51504469