Android知识点归纳-Android部分
2. Android部分
2.1 四大组件
Activity相关
1.Activity生命周期分析
2.Activity的四种状态
考点:running/paused/stopped/killed
参考答案:
- running是可以响应操作的状态,activity处于栈顶
- pause是该activity失去焦点时或被非全屏的(或者透明的)activity覆盖,但所有内存信息和成员变量都存在(内存紧张的时候会被回收)
- stopped是该activity被其他activity完全覆盖,和pause区别就是是否可见
- killed表示activity已经被系统回收了,相关信息和成员变量都不存在了
3.Activity启动模式
考点:4种启动模式和应用场景
参考答案:
- standard:每启动一次activity都会创建一个实例
- singleTop:栈顶复用,如果待启动的activity在栈顶,则不会走onCreate->onStart,而是onPause->onNewIntent->onResume
- singleTask:栈内复用,启动的Activity在指定的taskAffinity的task栈中存在相应的实例,则会把它上面的Activity出栈,直到当前Activity实例位于栈顶,执行onNewIntent。若指定的task不存在,则创建,如果存在则移到前台。应用场景:应用的主界面
- singleInstance:单一实例模式,整个手机操作系统里只有一个activity实例,且该task内只有该activity,如果实例存在,执行onNewIntent。应用场景:闹钟、浏览器、电话
4.scheme跳转协议
Service相关
1.Service的应用场景,以及和Thread的区别
2.开启Service的两种方式以及区别
Broadcast相关
1.广播的安全漏洞
2.本地广播的实现
ContentProvider相关
2.2 热点组件
Fragment相关
1.为什么fragment为什么被称为第五大组件,怎么加载到Activity里?
2.FragmentPagerAdapter和FragmentStatePagerAdapter区别
WebView相关
1.WebView常见的坑
2.3 异步
2.4 系统设计
View相关
1.View树的绘制流程
考点:
- 绘制的大致流程
- requestLayout和invalidate区别
- measure核心的两个类
- layout的核心方法
- 绘制的5大步骤
参考答案:
- 绘制大致流程:
activity接收到焦点,就开始请求绘制布局,入口是ViewRoot的performTraversal()函数,判断是否需要重新measure、layout、draw(测量、摆放、绘制) - requestLayout和invalidate区别:
- invalidate()请求重绘View树,即draw过程,假如视图发生大小没有变化就不会调用layout()过程,并且只绘制那些调用了invalidate()方法的 View。
- requestLayout()当布局变化的时候,比如方向变化,尺寸的变化,会调用该方法,在自定义的视图中,如果某些情况下希望重新测量尺寸大小,应该手动去调用该方法,它会触发measure()和layout()过程,但不会进行draw
- measure核心的两个类:LayoutParams(View自身的布局参数)、MeasureSpecs(父视图对子视图对测量要求)
- LayoutParams注意可能的强制类型转换错误
- MeasureSpecs有UNSPECIFIED、EXACTLY、AT_MOST(不约束、精确约束、限定最大尺寸)三种模式
- 子视图的具体位置都是相对于父视图而言的,View的onLayout方法为空实现。
- draw的五大步骤:背景(background.draw(canvas))、自身(onDraw)、子视图(dispatchDraw)、装饰(onDrawScrollBars)
2.View的事件分发机制
点击事件产生后,首先传递给 Activity 的 dispatchTouchEvent 方法,通过 PhoneWindow 传递给 DecorView,然后再传递给根 ViewGroup,进入 ViewGroup 的 dispatchTouchEvent 方法,执行 onInterceptTouchEvent 方法判断是否拦截,再不 拦截的情况下,此时会遍历 ViewGroup 的子元素,进入子 View 的 dispatchToucnEvent 方法,如果子 view 设置了 onTouchListener,就执行 onTouch 方法,并根据 onTouch 的返回值为 true 还是 false 来决定是否执行 onTouchEvent 方法,如果是 false 则继续执行 onTouchEvent,在 onTouchEvent 的 Action Up 事件中判断,如果设置了 onClickListener,就执行 onClick 方法。
Handler相关
1.谈谈消息机制Handler作用?有哪些要素?流程是怎样的?
考点:
- 作用
- 四大要素
- 具体流程
参考答案:
- Handler的作用主要是与UI线程进行通信和延迟任务执行
- 四大要素:Message、MessageQueue、Handler、Looper
- MessageQueue负责消息的存储与管理,使用单链表实现,为了快速插入和删除,在其next()方法无限循环判断是否有新消息,有就返回并移除
- Handler负责Message的发送和处理
- Looper负责关联线程和分发消息,在该线程的MessageQueue中取Message,分发给Handler。
- Looper在创建的时候会创建一个MessageQueue,调用loop()方法开始消息循环,然后不断调用MessageQueue的next()方法,有消息处理,没有就阻塞。
2.一个线程能否创建多个Handler,Handler跟Looper之间的对应关系?
对于一个线程来说,只能有一个Looper,创建Looper的时候创建一个MessageQueue,可以分发到多个Handler
---> 可以从Looper扩展到ThreadLocal
3.Handler的内存泄露原因和解决方案
根本原因:Handler允许延时消息和Message持有Handler,Handler作为内部类会持有外部类,如果延时期间Activity被关闭,该Activity会被泄露。
解决方法:Handler定义为静态内部类,内部持有Activity的弱引用,并且在onDestroy中移除所有消息
4.UI设计为何都是单线程的?
UI采用单线程模型的原因是,加锁会让UI的访问逻辑变得复杂且低效
5.Looper死循环为什么不会导致应用卡死?
- 主线程的主要方法就是消息循环,一旦退出消息循环,表示应用退出了
- 造成ANR的原因不是主线程阻塞,而是主线程的Looper消息处理没有在预期内完成
- 阻塞和ANR没有必然联系,ANR只是消息处理机制中的一个预警机制
- 无消息时,native调用的是epoll_wait,本身阻塞,不消耗CPU时间片
6.Handler的延时是怎么实现的?精确吗?
考点:
- 底层实现延迟的原理
- 不精确的原因?
- 如何优化?
参考答案:
- Handler如何实现延迟?
- MessageQueue(单链表实现)的enqueue为入口调用到Message的next方法获取消息
- 进入一个for(;;)的大死循环,不断调用nativePollOnce,其中nextPollTimeoutMills为-1表示阻塞且不会超时,为0表示立即返回,大于0表示下一次唤醒的时间
- 唤醒时间是从开机开始计算的
- 不精确的原因是如果任务堆积太多或者任务很耗时,会导致Looper负载很高,进而导致卡顿
- 解决方法:从消息队列优化和Looper入手
- 队列优化(重复消息过滤、互斥消息取消、复用消息)
- Looper:利用IdleHandler(空闲)和HandlerThread(避免主线程太挤)
7.可以在子线程中直接new一个Handler吗?
考点:
- 子线程能否使用Handler?
- 子线程怎么使用Handler?
- 多次prepare有什么问题?
参考答案:
- 直接new肯定是不可以的,主线程可以直接使用Handler是因为Activity内部包含一个Looper对象,而对于子线程来说,干干净净,没有帮我们创建Looper对象,所以需要自己手动维护,创建Looper,并开启Looper循环。
- 多次prepare会抛运行时异常<为了保证一个线程对应一个Looper>
小细节点:Message的创建可以用obtain,利用消息池化,避免生成过多的Message实例<有的说默认大小是10,看28的代码是50,不过这不重要>
2.5 难点前沿问题
组件化相关
插件化相关
热修复相关
2.6 Framework
Activity相关
1.说说Activity的启动流程?
- 向AMS发送startActivity请求
- 如果应用没启动,通过Socket向zygote发送启动进程请求
- zygote收到以后,会去启动应用进程
- 应用进程启动之后就会向AMS发起attachApplication的IPC调用,目的是注册ApplicationThread
- 接下来AMS会向应用发起bindApplication的IPC调用,目的是初始化应用Application
- 完了之后,AMS又向应用发起了scheduleLaunchActivity的IPC调用,目的是给应用执行和加载Activity,并且执行Activity的生命周期
2.说说Activity的显示原理?
3.WMS的作用
- 分配surface,掌管surface显示顺序、尺寸、位置等
- 输入事件分发
- 控制窗口动画