前言
由于之前从上海离职,来到深圳找工作。
然后准备面试的时候,发现网上很多Android面试题及答案整理都没有答案,
在成功的拿到几家公司的offer后(虽然不是阿里、网易这种级别的公司,但对我一个毕业三年的 Android 开发来说,算是成功的从小公司跳到大公司)
自己总结了一些最近面试过的 Android面试题以及答案。
Android基本知识点
1、常规知识点
1、 Android类加载器
在Android开发中,不管是插件化还是组件化,都是基于Android系统的类加载器ClassLoader来设计的。只不过Android平台上虚拟机运行的是Dex字节码,一种对class文件优化的产物,传统Class文件是一个Java源码文件会生成一个.class文件,而Android是把所有Class文件进行合并、优化,然后再生成一个最终的class.dex,目的是把不同class文件重复的东西只需保留一份,在早期的Android应用开发中,如果不对Android应用进行分dex处理,那么最后一个应用的apk只会有一个dex文件。
Android中常用的类加载器有两种,DexClassLoader和PathClassLoader,它们都继承于BaseDexClassLoader。区别在于调用父类构造器时,DexClassLoader多传了一个optimizedDirectory参数,这个目录必须是内部存储路径,用来缓存系统创建的Dex文件。而PathClassLoader该参数为null,只能加载内部存储目录的Dex文件。所以我们可以用DexClassLoader去加载外部的apk文件,这也是很多插件化技术的基础。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5wplRTpg-1681543295494)(https://segmentfault.com/img/remote/1460000041136600 “image”)]
2、 Service
理解Android的Service,可以从以下几个方面来理解:
- Service是在main Thread中执行,Service中不能执行耗时操作(网络请求,拷贝数据库,大文件)。
- 可以在xml中设置Service所在的进程,让Service在另外的进程中执行。
- Service执行的操作最多是20s,BroadcastReceiver是10s,Activity是5s。
- Activity通过bindService(Intent,ServiceConnection,flag)与Service绑定。
- Activity可以通过startService和bindService启动Service。
IntentService
IntentService是一个抽象类,继承自Service,内部存在一个ServiceHandler(Handler)和HandlerThread(Thread)。IntentService是处理异步请求的一个类,在IntentService中有一个工作线程(HandlerThread)来处理耗时操作,启动IntentService的方式和普通的一样,不过当执行完任务之后,IntentService会自动停止。另外可以多次启动IntentService,每一个耗时操作都会以工作队列的形式在IntentService的onHandleIntent回调中执行,并且每次执行一个工作线程。IntentService的本质是:封装了一个HandlerThread和Handler的异步框架。
2.1、生命周期示意图
Service 作为 Android四大组件之一,应用非常广泛。和Activity一样,Service 也有一系列的生命周期回调函数,具体如下图。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LeKWE03Q-1681543295495)(https:服务器托管网//segmentfault.com/img/remote/1460000041136601 “image”)]
通常,启动Service有两种方式,startService和bindService方式。
2.2、startService生命周期
当我们通过调用了Context的startService方法后,我们便启动了Service,通过startService方法启动的Service会一直无限期地运行下去,只有在外部调用Context的stopService或Service内部调用Service的stopSelf方法时,该Service才会停止运行并销毁。
onCreate
onCreate: 执行startService方法时,如果Service没有运行的时候会创建该Service并执行Service的onCreate回调方法;如果Service已经处于运行中,那么执行startService方法不会执行Service的onCreate方法。也就是说如果多次执行了Context的startService方法启动Service,Service方法的onCreate方法只会在第一次创建Service的时候调用一次,以后均不会再次调用。我们可以在onCreate方法中完成一些Service初始化相关的操作。
onStartCommand
onStartCommand: 在执行了startService方法之后,有可能会调用Service的onCreate方法,在这之后一定会执行Service的onStartCommand回调方法。也就是说,如果多次执行了Context的startService方法,那么Service的onStartCommand方法也会相应的多次调用。onStartCommand方法很重要,我们在该方法中根据传入的Intent参数进行实际的操作,比如会在此处创建一个线程用于下载数据或播放音乐等。
public @StartResult int onStartCommand(Intent intent, @StartArgFlags int flags, int startId) {
}
当Android面临内存匮乏的时候,可能会销毁掉你当前运行的Service,然后待内存充足的时候可以重新创建Service,Service被Android系统强制销毁并再次重建的行为依赖于Service中onStartCommand方法的返回值。我们常用的返回值有三种值,START_NOT_STICKY
、S服务器托管网TART_STICKY
和START_REDELIVER_INTENT
,这三个值都是Service中的静态常量。
START_NOT_STICKY
如果返回START_NOT_STICKY,表示当Service运行的进程被Android系统强制杀掉之后,不会重新创建该Service,当然如果在其被杀掉之后一段时间又调用了startService,那么该Service又将被实例化。那什么情境下返回该值比较恰当呢?如果我们某个Service执行的工作被中断几次无关紧要或者对Android内存紧张的情况下需要被杀掉且不会立即重新创建这种行为也可接受,那么我们便可将 onStartCommand的返回值设置为START_NOT_STICKY。举个例子,某个Service需要定时从服务器获取最新数据:通过一个定时器每隔指定的N分钟让定时器启动Service去获取服务端的最新数据。当执行到Service的onStartCommand时,在该方法内再规划一个N分钟后的定时器用于再次启动该Service并开辟一个新的线程去执行网络操作。假设Service在从服务器获取最新数据的过程中被Android系统强制杀掉,Service不会再重新创建,这也没关系,因为再过N分钟定时器就会再次启动该Service并重新获取数据。
START_STICKY
如果返回START_STICKY,表示Service运行的进程被Android系统强制杀掉之后,Android系统会将该Service依然设置为started状态(即运行状态),但是不再保存onStartCommand方法传入的intent对象,然后Android系统会尝试再次重新创建该Service,并执行onStartCommand回调方法,但是onStartCommand回调方法的Intent参数为null,也就是onStartCommand方法虽然会执行但是获取不到intent信息。如果你的Service可以在任意时刻运行或结束都没什么问题,而且不需要intent信息,那么就可以在onStartCommand方法中返回START_STICKY,比如一个用来播放背景音乐功能的Service就适合返回该值。
START_REDELIVER_INTENT
如果返回START_REDELIVER_INTENT,表示Service运行的进程被Android系统强制杀掉之后,与返回START_STICKY的情况类似,Android系统会将再次重新创建该Service,并执行onStartCommand回调方法,但是不同的是,Android系统会再次将Service在被杀掉之前最后一次传入onStartCommand方法中的Intent再次保留下来并再次传入到重新创建后的Service的onStartCommand方法中,这样我们就能读取到intent参数。只要返回START_REDELIVER_INTENT,那么onStartCommand重的intent一定不是null。如果我们的Service需要依赖具体的Intent才能运行(需要从Intent中读取相关数据信息等),并且在强制销毁后有必要重新创建运行,那么这样的Service就适合返回START_REDELIVER_INTENT。
onBind
Service中的onBind方法是抽象方法,所以Service类本身就是抽象类,也就是onBind方法是必须重写的,即使我们用不到。在通过startService使用Service时,我们在重写onBind方法时,只需要将其返回null即可。onBind方法主要是用于给bindService方法调用Service时才会使用到。
onDestroy
onDestroy: 通过startService方法启动的Service会无限期运行,只有当调用了Context的stopService或在Service内部调用stopSelf方法时,Service才会停止运行并销毁,在销毁的时候会执行Service回调函数。
由于文章内容比较多,篇幅有限,资料已经被整理成了PDF文档,有需要《Android面试大厂必考174题》
《Android面试大厂必考174题》
纲要
1. SD卡
2. android的数据存储方式
3. BroadcastReceiver
4. sp频繁操作会有什么后果?sp能存多少数据?
5. dvm与jvm的区别
6. ART
7. Activity的生命周期
8. Application能不能启动Activity
9. Activity的状态都有哪些
10. 横竖屏切换时Activity的生命周期****Activity的状态都有哪些
11. 如何设置activity成窗口样式
12. Activity的启动方式
13. Service的生命周期
14. IntentService
15. Fragment和Activity的onCreateOptionsMenu
16. Service的onStartCommand有几种返回值
17. Service的onRebind什么情况下执行
18. Handler防止内存泄露
19. IntentFilter的匹配法则
20. Fragment与Activity传值
21. Fragment 生命周期
22. Fragment的add和replace的区别 //replace==remove|append
23. Fragment如何实现Activity栈的压栈和出栈
24. 什么情况下造成内存泄露
25. 图片过大导致OOM
26. SoftReference跟WeakRefrence的区别
27. dp与px
28. 设置布局为一半宽、高
29. 多分辨率支持的清单文件配置
30. Android的事件分发机制
31. ArrayList和LinkedList的区别
32. LruCache
33. 什么是ANR,如何规避
34. 描述Service的启动方式
35. Android有哪几种布局
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
相关推荐: 『python爬虫』26. selenium与超级鹰处理复杂验证码的处理(保姆级图文)
目录 1. 图片选择类验证码 2. 滑块验证码 3. 滑块出错,不加载 总结 欢迎关注 『python爬虫』 专栏,持续更新中 欢迎关注 『python爬虫』 专栏,持续更新中 1. 图片选择类验证码 我们这里查看超级鹰文档 图片验证码返回的是一个 dic 结…