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

面试八股文记录(一)-Android
jetpackGoogle推出的现代化Android开发组件库集合统一兼容Android各个版本解决碎片化内存泄漏生命周期管理代码冗余等问题统一开发范式 MVVM支持Kotlin协程FlowCompose现代开发方式四大分类架构组件1、viewmodel2、LiveData/StateFlow/SharedFlow3、Lifecycle4、Room数据库SQLite封装ORM框架替代原生SQLite5、DataStore轻量本地存储替代SharedPreferences6、Paging分页式加载框架处理海量列表可以自动分页、预加载、加载状态适配RecycleView/Compose LazyList7、Navigation导航统一页面跳转管理替代Intent跳转8、WorkManager后台任务调度UI组件1、Compose2、AppCompat3、Material Components4、COnstraintLayout5、Fragment6、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页面销毁他还有四种启动模式-standardsingletopsingtasksingleinstance决定了activity如何实例化和压栈的2、Service用于执行后台长时间运行的任务启动方式分为两种startService启动后一直运行直到主动调用停止bindService提供客户端-服务器模式当所有绑定者解绑后服务自动销毁需要注意的是Service默认再主线程耗时操作需要另外开子线程否则可能ANR3、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_TOPFLAG_ACTIVITY_NEW_TASK等来动态覆盖行为。谈谈对Handler的了解和看法handler的话是Android中非常重要的消息机制主要用于线程间的通信他主要是靠四个角色来一起协同工作的Handler发送和接受消息入口sendMessage/post最终都走到enqueueMessage将消息放入队列中去MessageQueue存储消息单链表实现的优先级队列Looper死循环从MessageQueue中去消息然后发给对应的Handler的dispatchMessageMessage消息载体内部可以用obtain回收复用避免频繁创建对象运行流程1、线程创建Looper调用Looper.prepare()创建本线程唯一Looper实例同时会初始化一个MessageQueue然后调用Looper.loop()开始无限循环2、handler发送消息创建Handler时会绑定当前线程的LooperHandler发出的消息携带targe会指向自身进入Looper对应的MessageQueue3、消息分发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系统服务如AMSWMS启动时通过addService将服务名和Binder引用注册到ServiceManager。获取服务客户端通过getService来查询服务得到服务Binder的句柄封装成远程代理Proxy客户端拿到的是本地代理对象调用服务客户端调用Proxy的方法时将参数打包到Parcel通过transact将数据发给Binder驱动。驱动找到对应的服务端Binder实体唤醒服务端线程处理。服务端收到后解析参数执行真正方法将结果写回Parcel返回给客户端是同步的客户端线程会被挂起等待返回数据传递大件数据利用ashmem匿名共享内存传递Bitmap的writeToParcel内部用了Blob和FileDescriptor来传递共享内存fd因此能够零拷贝传递大图。Binder线程池与同步每个进程再初始化Binder时会启动一个Binder线程池默认最大16个线程服务端需要保证线程安全隐式意图让我们在不明确指定类名的情况下通过描述要做什么来启动其他应用的activity。1、隐式意图的匹配机制依靠actioncategorydata三要素与IntentFilter进行匹配2、实战场景打开网页分享内容调用系统拍照自定义协议拉起3、安全陷阱和防护4、包可见性限制