当前位置: 首页 > news >正文

面试八股文记录(一)-Android

jetpack

Google推出的现代化Android开发组件库集合,统一兼容Android各个版本,解决碎片化,内存泄漏,生命周期管理,代码冗余等问题

统一开发范式 MVVM,支持Kotlin协程,Flow,Compose现代开发方式

四大分类:

架构组件

1、viewmodel

2、LiveData/StateFlow/SharedFlow

3、Lifecycle

4、Room数据库,SQLite封装ORM框架,替代原生SQLite

5、DataStore:轻量本地存储,替代SharedPreferences

6、Paging:分页式加载框架,处理海量列表,可以自动分页、预加载、加载状态,适配RecycleView/Compose LazyList

7、Navigation导航:统一页面跳转管理,替代Intent跳转

8、WorkManager:后台任务调度

UI组件

1、Compose

2、AppCompat

3、Material Components

4、COnstraintLayout

5、Fragment

6、View Binding:自动生成控件绑定类,替代findviewbyid / Data Binding:支持xml直接绑定数据,表达式,MVVM双向绑定

7、WindowManager:适配折叠屏,大屏,多窗口设备

基础工具组件

1、Core KTX:给原生API扩展kotlin语法糖

2、Annotations:注解

3、Multidex:方法数超过65536的分包方案

4、Startup:应用初始化框架,替代ContentProvider启动,优化冷启动速度

行为组件-系统权限,媒体,安全

1、Permissions:简化动态权限申请,封装授权回调,判断权限状态

2、Media3:音视频播放器

3、Security:加密存储密钥,文件加密,适配不同系统加密方案

4、Biometric:生物识别

5、SplashScreen:统一标准启动页,替代自定义闪屏,优化冷启动体验

核心优势:

1、版本兼容,全部组件通过androidx.*包名,最低可兼容API14,不用写大量版本判断

2、生命周期安全:Lifecycle体系杜绝大量的内存泄露:组件可以自动感知页面生命周期状态,页面销毁时自动取消订阅

四大组件

1、Activity:

负责跟用户交互的界面组件,一个activity通常对应一个屏幕页面,核心是生命周期的管理,oncreate初始化,onstart可见,onresume可交互,onpause部分可见,onstop不可见,ondestroy页面销毁,他还有四种启动模式-standard,singletop,singtask,singleinstance,决定了activity如何实例化和压栈的

2、Service

用于执行后台长时间运行的任务,启动方式分为两种

startService:启动后一直运行,直到主动调用停止

bindService:提供客户端-服务器模式,当所有绑定者解绑后服务自动销毁,需要注意的是,Service默认再主线程,耗时操作需要另外开子线程,否则可能ANR

3、BroadcastReceiver

广播接收器,用来接收系统或应用发出的广播,如开机完成,网络变化等,注册方式有静态注册 Manifest中声明和动态注册 (代码中registerReceiver)。动态注册需要在合适的生命周期中去注册和反注册,比如onresume和onpause,防止内存泄漏或者崩溃。onReceive方法运行在主线程,不能耗时操作,也不可以直接弹窗。通常用于启动service或发送通知,进程内通信现在更倾向于LiveData或Flow来代替

4、ContentProvider

为应用间数据共享提供标准接口,底层可以是SQLite,文件等。外部应用通过ContentResolver配合URI进行CRUD操作,系统通过他来管理联系人,媒体库等,需要在manifest中注册,可以精细控制读写能力,保证数据安全。

这四个组件大多用Intent交互

四大启动模式

1、standard 标准模式

默认模式

2、singTop 栈顶复用模式

系统会判断要启动的activity是否在目标栈的栈顶,如果在就不建立新实例,而是调用他的onnewIntent方法复用现有实例;如果不在栈顶就新建,适合那些被重复打开,又不希望栈顶出现相同连续页面的场景

3、singleTask 栈内复用模式

整个栈内只存在一个实例,启动时,会先检测目标任务栈里是否已经有该activity实例了,如果没有就新建并放入栈中;如果有,会把该实例上面的所有activity全部出栈,让这个实例重新置于栈顶,并调用onNewIntent,通常用来做主页面

4、singleInstance 全局单例模式

是singleTask加强版,不仅栈内唯一,而且这个activity独占一个任务栈,不允许有其他activity,无论从哪个任务栈启动,它都会在一个独立的任务栈中。场景为:来电界面,闹钟提醒。

这些启动方式设置除了用manifest中硬编码设置launchMode外,还可以用Intent的FLAG_ACTIVITY_SINGLE_TOP,FLAG_ACTIVITY_NEW_TASK等来动态覆盖行为。

谈谈对Handler的了解和看法

handler的话是Android中非常重要的消息机制,主要用于线程间的通信,他主要是靠四个角色来一起协同工作的:

Handler:发送和接受消息入口,sendMessage/post最终都走到enqueueMessage将消息放入队列中去

MessageQueue:存储消息,单链表实现的优先级队列

Looper:死循环从MessageQueue中去消息,然后发给对应的Handler的dispatchMessage

Message:消息载体,内部可以用obtain回收复用,避免频繁创建对象

运行流程:

1、线程创建Looper:调用Looper.prepare()创建本线程唯一Looper实例,同时会初始化一个MessageQueue,然后调用Looper.loop()开始无限循环

2、handler发送消息:创建Handler时会绑定当前线程的Looper,Handler发出的消息携带targe会指向自身,进入Looper对应的MessageQueue

3、消息分发:Looper的loop()中,queue.next()取出下一条到时的消息,然后执行msg.target.dispatchMessage(msg),最终回调到Handler的handleMessage或Runnable

延时消息与阻塞唤醒

MessageQueue中会按照when字段升序排列,next取消息时如果队头还没到时间,就计算等待时间,调用nativePollOnce进入epoll等待,释放CPU,当新消息插入对头或时间更早时,通过nativeWake()唤醒等待,所以主线程的Looper.loop()不会导致CPU空转,无消息时线程会挂起

主线程与子线程:

主线程在应用启动时已调用prepareMainLooper和loop,所有可以直接创建Handler更新ui

子线程必须手动调用Looper.prepare()和loop(),或者使用HandlerThread

内存泄漏与优化

调用handler.removeCallbacksAndMessages()清空所有待处理消息,现在更推荐用Lifecycle组件配合LiveData

高级特性

同步屏障:通过postSyncBarrier插入屏障消息,优先处理异步消息,如view的绘制调度

IdleHandler:在MessageQueue空闲时回调,可做低优先级任务,如GC触发

HandlerThread:自带Looper的子线程,需注意及时quit释放

Binder机制 进程间的通信

选用binder的理由:

1、安全性:UID/PID可信传递,内核可以识别调用方身份,便于权限校验,而Socket无法确认对方真实身份。

2、高效性:一次数据拷贝(通过copy_from_user到内核空间,再映射到目标进程,本质是拷贝一次),比管道,Socket两次拷贝快,而共享内存缺乏同步机制且安全控制弱

3、面向对象:基于C++接口,服务端暴露IInterface,客户端像调用本地方法一样调用远程服务,开发体验好

4、引用计数与死亡通知:自动管理服务生命周期,死亡时能通知客户端,避免悬空指针

核心原理:

基于Client-Server-驱动三层架构

注册服务:ServiceManager再binder驱动中注册为句柄0,系统服务如AMS,WMS启动时,通过addService将服务名和Binder引用注册到ServiceManager。

获取服务:客户端通过getService来查询服务,得到服务Binder的句柄,封装成远程代理Proxy,客户端拿到的是本地代理对象

调用服务:客户端调用Proxy的方法时,将参数打包到Parcel,通过transact将数据发给Binder驱动。驱动找到对应的服务端Binder实体,唤醒服务端线程处理。服务端收到后解析参数,执行真正方法,将结果写回Parcel,返回给客户端,是同步的,客户端线程会被挂起等待返回,

数据传递:大件数据利用ashmem匿名共享内存传递,Bitmap的writeToParcel内部用了Blob和FileDescriptor来传递共享内存fd,因此能够零拷贝传递大图。

Binder线程池与同步:

每个进程再初始化Binder时会启动一个Binder线程池,默认最大16个线程,服务端需要保证线程安全

隐式意图

让我们在不明确指定类名的情况下,通过描述要做什么来启动其他应用的activity。

1、隐式意图的匹配机制

依靠action,category,data三要素与IntentFilter进行匹配

2、实战场景

打开网页,分享内容,调用系统拍照,自定义协议拉起

3、安全陷阱和防护

4、包可见性限制

http://www.jsqmd.com/news/1100582/

相关文章:

  • 别再只盯着代码了!聊聊ADAS测试工程师的日常工具箱:从校准板到数据记录仪
  • 如何用G-Helper实现华硕笔记本的精准性能控制与优化
  • 告别命令行!用JGit在Java项目里优雅地操作Git(附完整代码示例)
  • 如何快速获取网盘直链下载地址:LinkSwift下载助手终极指南
  • 别再手动调阈值了!用OpenCV直方图找谷底,5行代码搞定图像自动分割
  • Gemini镜像站 解决 PHP/Java 编程问题实战:2026 年开发者调试与优化指南
  • 杰理之支持提示音断点播放【篇】
  • 别再手动敲代码了!用STM32CubeMX 6.10.0图形化配置你的第一个FreeRTOS工程(STM32F407探索者)
  • Java Web路径穿越漏洞实战:从WEB-INF泄露到安全防御
  • 无犯罪记录公证书需要什么材料?无犯罪记录公证多久拿到?
  • 车载音乐下载 | 2026年更新最全网盘资源转存免费下载分享+副业变现方法
  • 淘宝拍立淘图片搜索API完整文档
  • Web应急响应实战:从入侵排查到溯源加固的完整指南
  • QT常用控件篇(3)(上)
  • 外卖退潮与AI浪潮:2026年餐饮业运营逻辑的艰难重构
  • 基础控件的信号:
  • 靠谱的装修公司哪家专业
  • 哑光亮调lr预设|高级哑光柔焦人像写真Lightroom下载lr调色风格
  • 给国产大模型 Agent 一副身体:我用魔珐星云搭建具身交互智能数字人
  • 广货行天下!超高清供需会现场体验VEGA H2
  • 从 Token Approval 到权限撤销:自托管钱包授权管理实践
  • 【华为OD机试真题 新系统】1034、数据包分段传输的最小最大延迟 | 机试真题+思路参考+代码解析(C++、Java、Py、C语言、JS)
  • 我把橘子洲头做成了AI客服:本地大模型落地的第一个真实场景
  • DCMTK:如何构建医疗影像系统的完整解决方案?
  • 【Claude Code】----Claude Code 23个高效技巧,效率拉满!!
  • 普通人靠挖漏洞也能高薪?揭秘白帽黑客 5K 到 13.2W 收入蜕变全过程,梳理合法变现全部渠道
  • 企业级AI改造实战:Agent、RAG与MCP组合拳破解复杂系统知识鸿沟
  • AI代理运行时解耦:会话即事件日志的工程实践
  • Codex客户端插件推荐:TOP 10 插件盘点,新手和开发者都值得收藏
  • 【稀缺干货】VMware KB 81992原始补丁分析:精简磁盘在vSAN 8.0U2中触发SCSI Reservation Timeout的底层链路图解