ViewRoot
创建一个Canvas对象,然后调用OnDraw()
。
六个步骤:
- 绘制视图的背景;
- 保存画布的图层(Layer);
- 绘制View的内容;
- 绘制View子视图,如果没有就不用;
- 还原图层(Layer);
- 绘制滚动条。
12、View,ViewGroup事件分发
1.Touch
事件分发中只有两个主角:ViewGroup
和View
。
ViewGroup
包含onInterceptTouchEvent
、dispatchTouchEvent
、onTouchEvent
三个相关事件。
View
包含dispatchTouchEvent
、onTouchEvent
两个相关事件。
其中ViewGroup
又继承于View。
2.ViewGroup
和View
组成了一个树状结构,根节点为Activity内部包含的一个ViewGroup
。
3.触摸事件由Action_Down、Action_Move、Aciton_UP
组成,其中一次完整的触摸事件中,Down和Up都只有一个,Move有若干个,可以为0个。
4.当Acitivty
接收到Touch事件时,将遍历子View进行Down事件的分发。ViewGroup
的遍历可以看成是递归的。分发的目的是为了找到真正要处理本次完整触摸事件的View,这个View会在onTouchuEvent
结果返回true。
5.当某个子View返回true时,会中止Down事件的分发,同时在ViewGroup
中记录该子View。接下去的Move和Up事件将由该子View直接进行处理。由于子View是保存在ViewGroup
中的,多层ViewGroup
的节点结构时,上级ViewGroup
保存的会是真实处理事件的View所在的ViewGroup
对象:如ViewGroup0-ViewGroup1-TextView
的结构中,TextView
返回了true,它将被保存在ViewGroup1
中,而ViewGroup1
也会返回true,被保存在ViewGroup0
中。当Move和UP事件来时,会先从ViewGroup0
传递至ViewGroup1
,再由ViewGroup1
传递至TextView
。
6.当ViewGroup
中所有子View都不捕获Down事件时,将触发ViewGroup
自身的onTouch
事件。触发的方式是调用super.dispatchTouchEvent
函数,即父类View的dispatchTouchEvent
方法。在所有子View都不处理的情况下,触发Acitivity的onTouchEvent
方法。
7.onInterceptTouchEvent
有两个作用:
- 拦截Down事件的分发。
- 中止Up和Move事件向目标View传递,使得目标View所在的
ViewGroup
捕获Up和Move事件。
13、保存Activity状态
onSaveInstanceState(Bundle)
会在activity转入后台状态之前被调用,也就是onStop()
方法之前,onPause
方法之后被调用;
14、Android中的几种动画
帧动画:
指通过指定每一帧的图片和播放时间,有序的进行播放而形成动画效果,比如想听的律动条。
补间动画:
指通过指定View的初始状态、变化时间、方式,通过一系列的算法去进行图形变换,从而形成动画效果,主要有Alpha、Scale、Translate、Rotate四种效果。
注意:只是在视图层实现了动画效果,并没有真正改变View的属性,比如滑动列表,改变标题栏的透明度。
属性动画:
在Android3.0的时候才支持,通过不断的改变View的属性,不断的重绘而形成动画效果。相比于视图动画,View的属性是真正改变了。比如view的旋转,放大,缩小。
15、Android中跨进程通讯的几种方式
Android跨进程通信,像intent,contentProvider.广播,service都可以跨进程通信。
intent:
这种跨进程方式并不是访问内存的形式,它需要传递一个uri,比如说打电话。
contentProvider:
这种形式,是使用数据共享的形式进行数据共享。
service:
远程服务,比如aidl
广播:
广播 包含静态广播,动态广播。
三.进阶知识体系
16、AIDL理解
此处延伸:简述Binder
AIDL:
每一个进程都有自己的Dalvik VM
实例,都有自己的一块独立的内存,都在自己的内存上存储自己的数据,执行着自己的操作,都在自己的那片狭小的空间里过完自己的一生。而aidl
就类似与两个进程之间的桥梁,使得两个进程之间可以进行数据的传输,跨进程通信有多种选择,比如BroadcastReceiver
, Messenger
等,但是 BroadcastReceiver
占用的系统资源比较多,如果是频繁的跨进程通信的话显然是不可取的;Messenger进行跨进程通信时请求队列是同步进行的,无法并发执行。
Binder机制简单理解:
在Android系统的Binder机制中,是有Client,Service,ServiceManager,Binder
驱动程序组成的,其中Client,service,Service Manager
运行在用户空间,Binder驱动程序是运行在内核空间的。而Binder就是把这4种组件粘合在一块的粘合剂,其中核心的组件就是Binder驱动程序,Service Manager
提供辅助管理的功能,而Client
和Service
正是在Binder驱动程序和Service Manager
提供的基础设施上实现C/S 之间的通信。其中Binder驱动程序提供设备文件/dev/binder
与用户控件进行交互,
Client、Service,Service Manager
通过open
和ioctl
文件操作相应的方法与Binder驱动程序进行通信。而Client
和Service
之间的进程间通信是通过Binder驱动程序间接实现的。而Binder Manager是一个守护进程,用来管理Service,并向Client提供查询Service接口的能力。
17、Handler的原理
Android中主线程是不能进行耗时操作的,子线程是不能进行更新UI的。所以就有了handler,它的作用就是实现线程之间的通信。
handler整个流程中,主要有四个对象,
handler,Message,MessageQueue,Looper
。当应用创建的时候,就会在主线程中创建handler对象,
我们通过要传送的消息保存到Message
中,handler通过调用sendMessage
方法将Message发送到MessageQueue
中,Looper
对象就会不断的调用loop()方法
不断的从MessageQueue
中取出Message交给handler进行处理。从而实现线程之间的通信。
18、Binder机制原理
在Android系统的Binder机制中,是有Client,Service,ServiceManager,Binder
驱动程序组成的,其中Client,service,Service Manager
运行在用户空间,Binder驱动程序是运行在内核空间的。而Binder就是把这4种组件粘合在一块的粘合剂,其中核心的组件就是Binder驱动程序,Service Manager提供辅助管理的功能,而Client和Service正是在Binder驱动程序和Service Manager提供的基础设施上实现C/S之间的通信。其中Binder驱动程序提供设备文件/dev/binder
与用户控件进行交互,Client、Service,Service Manager
通过open和ioctl文件操作相应的方法与Binder驱动程序进行通信。而Client和Service之间的进程间通信是通过Binder驱动程序间接实现的。而Binder Manager是一个守护进程,用来管理Service,并向Client提供查询Service接口的能力。
19、热修复的原理
我们知道Java虚拟机 —— JVM
是加载类的class文件的,而Android虚拟机——Dalvik/ART VM
是加载类的dex
文件,而他们加载类的时候都需要ClassLoader,ClassLoader
有一个子BaseDexClassLoader
,而BaseDexClassLoader
下有一个数组——DexPathList
,是用来存放dex
文件,当BaseDexClassLoader
通过调用findClass
方法时,实际上就是遍历数组,找到相应的dex
文件,找到,则直接将它return。而热修复的解决方法就是将新的dex
添加到该集合中,并且是在旧的dex
的前面,所以就会优先被取出来并且return返回。
20、Android内存泄露及管理
- 内存溢出(
OOM
)和内存泄露(对象无法被回收)的区别。 - 引起内存泄露的原因
- 内存泄露检测工具 ------>
LeakCanary
内存溢出out of memory
:
是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory
;
比如申请了一个integer
,但给它存了long
才能存下的数,那就是内存溢出。内存溢出通俗的讲就是内存不够用。
内存泄露memory leak
:
是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光
内存泄露原因:
一、Handler 引起的内存泄漏。
解决:将Handler声明为静态内部类,就不会持有外部类SecondActivity
的引用,其生命周期就和外部类无关,
如果Handler里面需要context的话,可以通过弱引用方式引用外部类
二、单例模式引起的内存泄漏。
解决:Context
是ApplicationContext
,由于ApplicationContext
的生命周期是和app一致的,不会导致内存泄漏
三、非静态内部类创建静态实例引起的内存泄漏。
解决:把内部类修改为静态的就可以避免内存泄漏了
四、非静态匿名内部类引起的内存泄漏。
解决:将匿名内部类设置为静态的。
五、注册/反注册未成对使用引起的内存泄漏。
注册广播接受器、EventBus
等,记得解绑。
六、资源对象没有关闭引起的内存泄漏。
在这些资源不使用的时候,记得调用相应的类似close()、destroy()、recycler()、release()
等方法释放。
七、集合对象没有及时清理引起的内存泄漏。
通常会把一些对象装入到集合中,当不使用的时候一定要记得及时清理集合,让相关对象不再被引用。
21、Fragment与Fragment、Activity通信的方式
- 直接在一个
Fragment
中调用另外一个Fragment
中的方法 - 使用接口回调
- 使用广播
- Fragment直接调用Activity中的public方法
22、Android UI适配
字体使用sp
,
dp
,多使用match_parent,wrap_content,weight
图片资源,不同图片的的分辨率,放在相应的文件夹下可使用百分比代替。
23、app优化
app优化:
工具:Hierarchy Viewer 分析布局
工具:TraceView测试分析耗时
App启动优化
布局优化
响应优化
内存优化
电池使用优化
网络优化
App启动的方式有三种:
冷启动:
App没有启动过或App进程被killed, 系统中不存在该App进程, 此时启动App即为冷启动。
热启动:
热启动意味着你的App进程只是处于后台, 系统只是将其从后台带到前台, 展示给用户。
介于冷启动和热启动之间,
一般来说在以下两种情况下发生:
(1)用户
back
退出了App
, 然后又启动.
App进程可能还在运行, 但是activity需要重建。
(2)用户退出App后, 系统可能由于内存原因将App杀死, 进程和activity都需要重启, 但是可以在onCreate
中将被动杀死锁保存的状态(saved instance state)
恢复。
启动优化:
Application的onCreate
(特别是第三方SDK初始化),首屏Activity的渲染都不要进行耗时操作,如果有,就可以放到子线程或者IntentService
中。
布局优化
尽量不要过于复杂的嵌套。可以使用<include>,<merge>,<ViewStub>
响应优化
Android系统每隔16ms会发出VSYNC信号重绘我们的界面(Activity)。
页面卡顿的原因:
(1)过于复杂的布局.
(2)UI线程的复杂运算
(3)频繁的GC
导致频繁GC有两个原因:
1、内存抖动, 即大量的对象被创建又在短时间内马上被释放.
2、瞬间产生大量的对象会严重占用内存区域。
电池使用优化
工具:Batterystats & bugreport
(1)优化网络请求
(2)定位中使用GPS, 请记得及时关闭
网络优化
网络连接对用户的影响:流量,电量,用户等待,可在Android studio下方logcat
旁边那个工具Network Monitor检测
API设计:
App与Server之间的API设计要考虑网络请求的频次, 资源的状态等. 以便App可以以较少的请求来完成业务需求和界面的展示.
Gzip压缩:
使用Gzip来压缩request和response, 减少传输数据量, 从而减少流量消耗.
图片的Size:
可以在获取图片时告知服务器需要的图片的宽高, 以便服务器给出合适的图片, 避免浪费.
网络缓存:
适当的缓存, 既可以让我们的应用看起来更快, 也能避免一些不必要的流量消耗.
24、图片优化
(1)对图片本身进行操作。
尽量不要使用setImageBitmap、setImageResource、BitmapFactory.decodeResource
来设置一张大图,因为这些方法在完成decode后,最终都是通过 java 层的createBitmap
来完成的,需要消耗更多内存.
(2)图片进行缩放的比例,SDK中建议其值是2的指数值,值越大会导致图片不清晰。
(3)不用的图片记得调用图片的recycle()方法
25、HybridApp WebView和JS交互
Android与JS
通过WebView
互相调用方法,实际上是:
Android去调用JS的代码
通过WebView
的loadUrl()
,使用该方法比较简洁,方便。但是效率比较低,获取返回值比较困难。
通过WebView
的evaluateJavascript()
,该方法效率高,但是4.4以上的版本才支持,4.4以下版本不支持。所以建议两者混合使用。
JS去调用Android的代码
- 通过
WebView
的addJavascriptInterface()
进行对象映射 ,该方法使用简单,仅将Android对象和JS对象映射即可,但是存在比较大的漏洞。
漏洞产生原因是:当JS拿到Android这个对象后,就可以调用这个Android对象中所有的方法,包括系统类(java.lang.Runtime 类)
,从而进行任意代码执行。
解决方法:
(1)Google 在Android 4.2版本中规定对被调用的函数以
@JavascriptInterface
进行注解从而避免漏洞攻击。
(2)在Android 4.2版本之前采用拦截prompt()进行漏洞修复。
- 通过
WebViewClient
的shouldOverrideUrlLoading ()
方法回调拦截url 。
这种方式的优点:
不存在方式1的漏洞;
缺点:JS获取Android方法的返回值复杂。(ios主要用的是这个方式)
(1)Android通过 WebViewClient 的回调方法shouldOverrideUrlLoading ()拦截 url
(2)解析该url的协议
(3)如果检测到是预先约定好的协议,就调用相应方法
- 通过
WebChromeClient
的onJsAlert()
、onJsConfirm()
、onJsPrompt()
方法回调拦截JS对话框alert()、confirm()、prompt() 消息
这种方式的优点:不存在方式1的漏洞;缺点:JS获取Android方法的返回值复杂。
26、JAVA GC原理
垃圾收集算法的核心思想是:
对虚拟机可用内存空间,即堆空间中的对象进行识别,如果对象正在被引用,那么称其为存活对象,反之,如果对象不再被引用,则为垃圾对象,可以回收其占据的空间,用于再分配。垃圾收集算法的选择和垃圾收集系统参数的合理调节直接影响着系统性能。
27、ANR
ANR全名Application Not Responding, 也就是"应用无响应". 当操作在一段时间内系统无法处理时, 系统层面会弹出上图那样的ANR对话框.
产生原因:
(1)5s内无法响应用户输入事件(例如键盘输入, 触摸屏幕等).
(2)BroadcastReceiver
在10s内无法结束
(3)Service 20s内无法结束(低概率)
解决方式:
(1)不要在主线程中做耗时的操作,而应放在子线程中来实现。如
onCreate()
和onResume()
里尽可能少的去做创建操作。
(2)应用程序应该避免在BroadcastReceiver
里做耗时的操作或计算。
(3)避免在Intent Receiver里启动一个Activity,因为它会创建一个新的画面,并从当前用户正在运行的程序上抢夺焦点。
(4)service是运行在主线程的,所以在service中做耗时操作,必须要放在子线程中。
28、设计模式
此处延伸:Double Check
的写法被要求写出来。
单例模式:分为恶汉式和懒汉式
恶汉式:
public class Singleton
{
private static Singleton instance = new Singleton();
public static Singleton getInstance()
{
return instance ;
}
}
懒汉式:
public class Singleton02
{
private static Singleton02 instance;
public static Singleton02 getInstance()
{
if (instance == null)
{
synchronized (Singleton02.class)
{
if (instance == null)
{
instance = new Singleton02();
}
}
}
return instance;
}
}
29、MVP,MVC,MVVM
此处延伸:手写mvp例子,与mvc之间的区别,mvp的优势
MVP模式
对应着
Model
:业务逻辑和实体模型,
view
:对应着activity,负责View的绘制以及与用户交互,
Presenter
:负责View和Model之间的交互,
MVP模式是在MVC
模式的基础上,将Model与View彻底分离使得项目的耦合性更低,在Mvc
中项目中的activity对应着mvc
中的C–Controllor
,而项目中的逻辑处理都是在这个C中处理,同时View与Model之间的交互,也是也就是说,mvc
中所有的逻辑交互和用户交互,都是放在Controllor
中,也就是activity中。View和model是可以直接通信的。而MVP模式则是分离的更加彻底,分工更加明确Model业务逻辑和实体模型,view负责与用户交互,Presenter 负责完成View于Model间的交互,MVP
和MVC最大的区别是MVC中是允许Model和View进行交互的,而MVP中很明显,Model与View之间的交互由Presenter完成。还有一点就是Presenter
与View
之间的交互是通过接口的
Android核心知识点
面试成功其实是必然的,因为我做足了充分的准备工作,包括刷题啊,看一些Android核心的知识点,看一些面试的博客吸取大家面试的一些经验。
下面这份PDF是我翻阅了差不多3个月左右一些Android大博主的博客从他们那里取其精华去其糟泊所整理出来的一些Android的核心知识点,全部都是精华中的精华,我能面试到现在2-2资深开发人员跟我整理的这本Android核心知识点有密不可分的关系,在这里本着共赢的心态分享给各位朋友。
不管是Android基础还是Java基础以及常见的数据结构,这些是无原则地必须要熟练掌握的,尤其是非计算机专业的同学,面试官一上来肯定是问你基础,要是基础表现不好很容易被扣上基础不扎实的帽子,常见的就那些,只要你平时认真思考过基本上面试是没太大问题的。
最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上我搜集整理的2019-2021BAT 面试真题解析,我把大厂面试中常被问到的技术点整理成了PDF,包知识脉络 + 诸多细节。
节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
大厂面试中常被问到的技术点整理成了PDF,包知识脉络 + 诸多细节。
节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!