3.Bitmap优化:
- 尺寸压缩:通过InSampleSize设置合适的缩放
- 颜色质量:设置合适的format,ARGB_6666/RBG_545/ARGB_4444/ALPHA_6,存在很大差异
inBitmap
:使用inBitmap
属性可以告知Bitmap解码器去尝试使用已经存在的内存区域,新解码的Bitmap会尝试去使用之前那张Bitmap在Heap中所占据的pixel data内存区域,而不是去问内存重新申请一块区域来存放Bitmap。利用这种特性,即使是上千张的图片,也只会仅仅只需要占用屏幕所能够显示的图片数量的内存大小,但复用存在一些限制,具体体现在:在Android 4.4之前只能重用相同大小的Bitmap的内存,而Android 4.4及以后版本则只要后来的Bitmap比之前的小即可。使用inBitmap
参数前,每创建一个Bitmap对象都会分配一块内存供其使用,而使用了inBitmap
参数后,多个Bitmap可以复用一块内存,这样可以提高性能
4.StringBuilder
替代String:
在有些时候,代码中会需要使用到大量的字符串拼接的操作,这种时候有必要考虑使用StringBuilder
来替代频繁的“+”
5.避免在类似onDraw
这样的方法中创建对象,因为它会迅速占用大量内存,引起频繁的GC
甚至内存抖动
6.减少内存泄漏也是一种避免OOM
的方法
7.说下Activity的启动模式,生命周期,两个Activity跳转的生命周期,如果一个Activity跳转另一个Activity再按下Home键在回到Activity的生命周期是什么样的
启动模式
Standard模式: Activity可以有多个实例,每次启动Activity,无论任务栈中是否已经有这个Activity的实例,系统都会创建一个新的Activity实例
SingleTop
模式: 当一个singleTop
模式的Activity已经位于任务栈的栈顶,再去启动它时,不会再创建新的实例,如果不位于栈顶,就会创建新的实例
SingleTask
模式: 如果Activity已经位于栈顶,系统不会创建新的Activity实例,和singleTop
模式一样。但Activity已经存在但不位于栈顶时,系统就会把该Activity移到栈顶,并把它上面的activity出栈
SingleInstance
模式: singleInstance
模式也是单例的,但和singleTask
不同,singleTask
只是任务栈内单例,系统里是可以有多个singleTask
Activity实例的,而singleInstance
Activity在整个系统里只有一个实例,启动一singleInstanceActivity
时,系统会创建一个新的任务栈,并且这个任务栈只有他一个Activity生命周期
onCreate
onStart
onResume
onPause
onStop
onDestroy
两个Activity跳转的生命周期
1.启动A
onCreate
- onStart
- onResume
2.在A中启动B
ActivityA
onPause
ActivityB
onCreate
ActivityB
onStart
ActivityB
onResume
ActivityA
onStop
3.从B中返回A(按物理硬件返回键)
ActivityB
onPause
ActivityA
onRestart
ActivityA
onStart
ActivityA
onResume
ActivityB
onStop
ActivityB
onDestroy
4.继续返回
ActivityA
onPause
ActivityA
onStop
ActivityA
onDestroy
8.onRestart
的调用场景
(1) 按下home键之后,然后切换回来,会调用
onRestart()
。
(2) 从本Activity跳转到另一个Activity之后,按back键返回原来Activity,会调用onRestart()
;
(3) 从本Activity切换到其他的应用,然后再从其他应用切换回来,会调用onRestart()
;
说下Activity的横竖屏的切换的生命周期,用那个方法来保存数据,两者的区别。触发在什么时候在那个方法里可以获取数据等。
9.是否了SurfaceView
,它是什么?他的继承方式是什么?他与View的区别(从源码角度,如加载,绘制等)。
SurfaceView
中采用了双缓冲机制,保证了UI界面的流畅性,同时SurfaceView
不在主线程中绘制,而是另开辟一个线程去绘制,所以它不妨碍UI线程;
SurfaceView
继承于View,他和View主要有以下三点区别:
- View底层没有双缓冲机制,
SurfaceView
有; - view主要适用于主动更新,而
SurfaceView
适用与被动的更新,如频繁的刷新 - view会在主线程中去更新UI,而
SurfaceView
则在子线程中刷新;SurfaceView
的内容不在应用窗口上,所以不能使用变换(平移、缩放、旋转等)。也难以放在ListView
或者ScrollView
中,不能使用UI控件的一些特性比如View.setAlpha()
View:显示视图,内置画布,提供图形绘制函数、触屏事件、按键事件函数等;必须在UI主线程内更新画面,速度较慢。
SurfaceView
:基于view视图进行拓展的视图类,更适合2D游戏的开发;是view的子类,类似使用双缓机制,在新的线程中更新画面所以刷新界面速度比view快,Camera预览界面使用SurfaceView。
GLSurfaceView:基于SurfaceView
视图再次进行拓展的视图类,专用于3D游戏开发的视图;是SurfaceView
的子类,openGL
专用。
10.如何实现进程保活
a: Service设置成START_STICKY kill 后会被重启(等待5秒左右),重传Intent,保持与重启前一样
b: 通过startForeground
将进程设置为前台进程, 做前台服务,优先级和前台应用一个级别,除非在系统内存非常缺,否则此进程不会被 kill
c: 双进程Service: 让2个进程互相保护对方,其中一个Service被清理后,另外没被清理的进程可以立即重启进程
d: 用C编写守护进程(即子进程) : Android系统中当前进程(Process)fork出来的子进程,被系统认为是两个不同的进程。当父进程被杀死的时候,子进程仍然可以存活,并不受影响(Android5.0以上的版本不可行)联系厂商,加入白名单
e. 锁屏状态下,开启一个一像素Activity
11.说下冷启动与热启动是什么,区别,如何优化,使用场景等。
app冷启动: 当应用启动时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用, 这个启动方式就叫做冷启动(后台不存在该应用进程)。冷启动因为系统会重新创建一个新的进程分配给它,所以会先创建和初始化Application类,再创建和初始化MainActivity
类(包括一系列的测量、布局、绘制),最后显示在界面上。
app热启动: 当应用已经被打开, 但是被按下返回键、Home键等按键时回到桌面或者是其他程序的时候,再重新打开该app时, 这个方式叫做热启动(后台已经存在该应用进程)。热启动因为会从已有的进程中来启动,所以热启动就不会走Application这步了,而是直接走MainActivity
(包括一系列的测量、布局、绘制),所以热启动的过程只需要创建和初始化一个MainActivity
就行了,而不必创建和初始化Application
冷启动的流程
当点击app的启动图标时,安卓系统会从Zygote进程中fork创建出一个新的进程分配给该应用,之后会依次创建和初始化Application类、创建MainActivity
类、加载主题样式Theme中的windowBackground
等属性设置给MainActivity
以及配置Activity层级上的一些属性、再inflate布局、当onCreate
/onStart
/onResume
方法都走完了后最后才进行contentView
的measure
/layout
/draw
显示在界面上冷启动的生命周期简要流程:
Application构造方法 –> attachBaseContext()
–>onCreate
–>Activity构造方法 –> onCreate()
–> 配置主体中的背景等操作 –>onStart()
–> onResume()
–> 测量、布局、绘制显示
冷启动的优化主要是视觉上的优化,解决白屏问题,提高用户体验,所以通过上面冷启动的过程。能做的优化如下:
1、减少onCreate()方法的工作量
2、不要让Application参与业务的操作
3、不要在Application进行耗时操作
4、不要以静态变量的方式在Application保存数据
5、减少布局的复杂度和层级
6、减少主线程耗时
12.三级缓存原理
当Android端需要获得数据时比如获取网络中的图片,首先从内存中查找(按键查找),内存中没有的再从磁盘文件或sqlite
中去查找,若磁盘中也没有才通过网络获取
13.LruCache底层实现原理:
LruCache
中Lru
算法的实现就是通过LinkedHashMap
来实现的。LinkedHashMap
继承于HashMap
,它使用了一个双向链表来存储Map中的Entry顺序关系,
对于get、put、remove等操作,LinkedHashMap
除了要做HashMap
做的事情,还做些调整Entry顺序链表的工作。
LruCache中将LinkedHashMap的顺序设置为LRU顺序来实现LRU缓存,每次调用get(也就是从内存缓存中取图片),则将该对象移到链表的尾端。
调用put插入新的对象也是存储在链表尾端,这样当内存缓存达到设定的最大值时,将链表头部的对象(近期最少用到的)移除。
14.说下你对Collection这个类的理解。
15.JVM老年代和新生代的比例
16.jvm,jre以及jdk三者之间的关系?JDK(Java Development Kit)是针对Java开发员的产品,是整个Java的核心,包括了Java运行环境JRE、Java工具和Java基础类库。
17.谈谈你对 JNIEnv 和 JavaVM 理解?
18.Serializable与Parcable的区别?
19.为什么冷启动会有白屏黑屏问题?
20.Android中的线程有那些,原理与各自特点
21.ANR的原因
最后
今天关于面试的分享就到这里,还是那句话,有些东西你不仅要懂,而且要能够很好地表达出来,能够让面试官认可你的理解,例如Handler机制,这个是面试必问之题。有些晦涩的点,或许它只活在面试当中,实际工作当中你压根不会用到它,但是你要知道它是什么东西。
最后在这里小编分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司19年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。
还有 高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
【Android核心高级技术PDF文档,BAT大厂面试真题解析】
【算法合集】
【延伸Android必备知识点】
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
《960全网最全Android开发笔记》
《379页Android开发面试宝典》
《507页Android开发相关源码解析》
因为文件太多,全部展示会影响篇幅,暂时就先列举这些部分截图
droid开发面试宝典》**
[外链图片转存中…(img-gedjJ4vx-1711895693048)]
《507页Android开发相关源码解析》
[外链图片转存中…(img-lB11Ifiv-1711895693048)]
因为文件太多,全部展示会影响篇幅,暂时就先列举这些部分截图