面试题

Android知识点归纳-Android部分

2020-02-03  本文已影响0人  New_X

2. Android部分

2.1 四大组件

Activity相关

1.Activity生命周期分析

2.Activity的四种状态
考点:running/paused/stopped/killed

参考答案:

  1. running是可以响应操作的状态,activity处于栈顶
  2. pause是该activity失去焦点时或被非全屏的(或者透明的)activity覆盖,但所有内存信息和成员变量都存在(内存紧张的时候会被回收)
  3. stopped是该activity被其他activity完全覆盖,和pause区别就是是否可见
  4. killed表示activity已经被系统回收了,相关信息和成员变量都不存在了

3.Activity启动模式
考点:4种启动模式和应用场景

参考答案:

  1. standard:每启动一次activity都会创建一个实例
  2. singleTop:栈顶复用,如果待启动的activity在栈顶,则不会走onCreate->onStart,而是onPause->onNewIntent->onResume
  3. singleTask:栈内复用,启动的Activity在指定的taskAffinity的task栈中存在相应的实例,则会把它上面的Activity出栈,直到当前Activity实例位于栈顶,执行onNewIntent。若指定的task不存在,则创建,如果存在则移到前台。应用场景:应用的主界面
  4. 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树的绘制流程
考点:

  1. 绘制的大致流程
  2. requestLayout和invalidate区别
  3. measure核心的两个类
  4. layout的核心方法
  5. 绘制的5大步骤

参考答案:

  1. 绘制大致流程:
    activity接收到焦点,就开始请求绘制布局,入口是ViewRoot的performTraversal()函数,判断是否需要重新measure、layout、draw(测量、摆放、绘制)
  2. requestLayout和invalidate区别:
    1. invalidate()请求重绘View树,即draw过程,假如视图发生大小没有变化就不会调用layout()过程,并且只绘制那些调用了invalidate()方法的 View。
    2. requestLayout()当布局变化的时候,比如方向变化,尺寸的变化,会调用该方法,在自定义的视图中,如果某些情况下希望重新测量尺寸大小,应该手动去调用该方法,它会触发measure()和layout()过程,但不会进行draw
  3. measure核心的两个类:LayoutParams(View自身的布局参数)、MeasureSpecs(父视图对子视图对测量要求)
    1. LayoutParams注意可能的强制类型转换错误
    2. MeasureSpecs有UNSPECIFIED、EXACTLY、AT_MOST(不约束、精确约束、限定最大尺寸)三种模式
  4. 子视图的具体位置都是相对于父视图而言的,View的onLayout方法为空实现。
  5. 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作用?有哪些要素?流程是怎样的?
考点:

  1. 作用
  2. 四大要素
  3. 具体流程

参考答案:

  1. Handler的作用主要是与UI线程进行通信和延迟任务执行
  2. 四大要素:Message、MessageQueue、Handler、Looper
    1. MessageQueue负责消息的存储与管理,使用单链表实现,为了快速插入和删除,在其next()方法无限循环判断是否有新消息,有就返回并移除
    2. Handler负责Message的发送和处理
    3. 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死循环为什么不会导致应用卡死?

  1. 主线程的主要方法就是消息循环,一旦退出消息循环,表示应用退出了
  2. 造成ANR的原因不是主线程阻塞,而是主线程的Looper消息处理没有在预期内完成
  3. 阻塞和ANR没有必然联系,ANR只是消息处理机制中的一个预警机制
  4. 无消息时,native调用的是epoll_wait,本身阻塞,不消耗CPU时间片

6.Handler的延时是怎么实现的?精确吗?
考点:

  1. 底层实现延迟的原理
  2. 不精确的原因?
  3. 如何优化?

参考答案:

  1. Handler如何实现延迟?
    1. MessageQueue(单链表实现)的enqueue为入口调用到Message的next方法获取消息
    2. 进入一个for(;;)的大死循环,不断调用nativePollOnce,其中nextPollTimeoutMills为-1表示阻塞且不会超时,为0表示立即返回,大于0表示下一次唤醒的时间
    3. 唤醒时间是从开机开始计算的
  2. 不精确的原因是如果任务堆积太多或者任务很耗时,会导致Looper负载很高,进而导致卡顿
  3. 解决方法:从消息队列优化和Looper入手
    1. 队列优化(重复消息过滤、互斥消息取消、复用消息)
    2. Looper:利用IdleHandler(空闲)和HandlerThread(避免主线程太挤)

7.可以在子线程中直接new一个Handler吗?
考点:

  1. 子线程能否使用Handler?
  2. 子线程怎么使用Handler?
  3. 多次prepare有什么问题?

参考答案:

  1. 直接new肯定是不可以的,主线程可以直接使用Handler是因为Activity内部包含一个Looper对象,而对于子线程来说,干干净净,没有帮我们创建Looper对象,所以需要自己手动维护,创建Looper,并开启Looper循环。
  2. 多次prepare会抛运行时异常<为了保证一个线程对应一个Looper>

小细节点:Message的创建可以用obtain,利用消息池化,避免生成过多的Message实例<有的说默认大小是10,看28的代码是50,不过这不重要>

2.5 难点前沿问题

组件化相关
插件化相关
热修复相关

2.6 Framework

Activity相关

1.说说Activity的启动流程?

  1. 向AMS发送startActivity请求
  2. 如果应用没启动,通过Socket向zygote发送启动进程请求
  3. zygote收到以后,会去启动应用进程
  4. 应用进程启动之后就会向AMS发起attachApplication的IPC调用,目的是注册ApplicationThread
  5. 接下来AMS会向应用发起bindApplication的IPC调用,目的是初始化应用Application
  6. 完了之后,AMS又向应用发起了scheduleLaunchActivity的IPC调用,目的是给应用执行和加载Activity,并且执行Activity的生命周期

2.说说Activity的显示原理?

3.WMS的作用

  1. 分配surface,掌管surface显示顺序、尺寸、位置等
  2. 输入事件分发
  3. 控制窗口动画
上一篇 下一篇

猜你喜欢

热点阅读