博客
关于我
Android 基础与底层机制面试题(1)
阅读量:441 次
发布时间:2019-03-06

本文共 2984 字,大约阅读时间需要 9 分钟。

Android 开发核心知识点探解

Activity、Window、View 三者如何协同构建用户界面

Activity、Window、View 三者是Android UI组件体系的三大核心构件,它们各自承担不同的角色,协同工作以实现用户界面的显示和交互。

  • Activity:作为应用程序的主控件,负责管理窗口的生命周期和状态。它是用户与应用程序交互的入口,控制整个应用程序的运行流程。
  • Window:承载UI界面的容器,负责管理视图的布局和显示。Window类似于传统操作系统中的窗口,负责绘制界面并处理用户输入。
  • View:是用户界面中可视化的元素,包括按钮、文本、图像等。View类是Android UI系统的基础构件,负责绘制和交互。

这三个构件通过LayoutInflater(剪刀工具)将布局文件转换为实际的UI视图,共同完成界面的绘制和展示。


Fragment 的特点及使用体验

Fragment是一种轻量级的UI组件,旨在将Activity的界面拆分成多个独立的模块,提高开发效率和代码复用性。

  • 模块化设计:Fragment可以独立存在,作为Activity的一部分组成,支持多个Fragment同时存在于同一Activity中。
  • 灵活组装:Fragment可以在运行时动态添加、删除或替换,支持多种组合方式,适用于多样化的UI需求。
  • 生命周期管理:Fragment具有独立的生命周期,可以响应用户事件和状态变化,支持数据保存和恢复。
  • 代码复用:Fragment内部可以封装自定义逻辑,适用于重复使用的UI逻辑和功能模块。
  • 踩过的坑

    • 重叠:需谨慎管理Fragment的添加和移除,避免UI状态混乱。
    • 注解新API:在低版本SDK上使用新API时需借助兼容包,确保兼容性。
    • 数据初始化: Fragment生命周期中需谨慎管理数据初始化,避免Commit操作在onSaveInstanceState后执行。
    • 事务管理: Fragment事务操作需谨慎处理,避免入栈出栈逻辑错误。

    低版本SDK实现高版本API

    在某些情况下,高版本API在低版本SDK中不存在,需手动实现或通过兼容包适配。

  • 使用兼容包:如Fragment、Notification等API在v4兼容包中有替代实现,需根据版本判断使用兼容包或原API。
  • 手动实现:对于没有兼容包支持的API,需自行实现或在低版本SDK中去除该功能。
  • 版本检测:使用@TargetApi注解控制特定版本的API使用,避免编译错误。
  • 废弃API:尽量避免使用已废弃API,防止兼容性问题。

  • Activity的启动模式与内存管理

    Activity的启动模式

    Activity的启动模式主要通过AndroidManifest.xml配置控制,常见模式包括:

    • 标准模式:默认模式,支持多个Activity并存。
    • SingleTop:仅保留栈顶的Activity,适用于书签、聊天等场景。
    • SingleTask:将指定Activity设为唯一任务,适用于主界面。
    • SingleInstance:通过intent-filter控制唯一性,常用于耗内存的Activity(如闹钟)。

    内存管理

    每个应用程序由Android为其分配内存资源,最大值根据配置决定。内存泄露会导致OOM,需注意以下几点:

  • 对象复用:通过ListView、RecyclerView等使用convertView复用UI元素,减少对象创建。
  • 图片管理:使用Bitmap的inSampleSize和decodeFormat优化图片加载,避免大图导致OOM。
  • 对象池技术:通过LRU机制管理Bitmap、View等对象,确保内存利用率。
  • 避免内存抖动:在onDraw方法中避免频繁创建对象,减少GC压力。

  • ANR问题的分析与解决方案

    ANR(Application Not Responding)通常由主线程阻塞导致,需重点关注以下场景:

  • IO/网络操作:需在子线程执行,避免阻塞主线程。
  • 耗时计算:自定义控件的onDraw方法中避免复杂计算,减少内存抖动。
  • BroadCastReceiver:确保在10秒内完成处理,减少异步化处理。
  • Service耗时操作:在子线程执行耗时任务,避免阻塞主线程。
  • AsyncTask使用:确保AsyncTask执行在子线程,避免UI阻塞。

  • 内存泄露的防范策略

  • 减少对象占用:使用ArrayMap、SparseArray等高效数据结构替代HashMap。
  • 避免大图加载:使用inSampleSize压缩图片,减少内存占用。
  • 对象池技术:通过LRU机制管理 Bitmap、View等对象,确保内存利用率。
  • 避免内存抖动:在onDraw方法中避免频繁创建对象,减少GC压力。
  • 优化代码:避免在onDraw方法中创建对象,减少内存抖动。

  • Service与Activity间通信方式

    Service和Activity之间可以通过多种方式通信:

  • Binder:通过IBinder接口实现远程过程调用,适用于简单数据传递。
  • 广播:通过发送广播实现异步通信,适用于不需要实时响应的场景。

  • Android各版本API的区别

    了解不同版本API的特性有助于开发兼容性代码:

    • 3.0/4.0:引入Material Design设计理念,优化UI组件。
    • 4.4:性能优化,改进内存管理。
    • 5.0:引入向量动画、直接布局API等新特性。
    • 6.0/7.0:多任务窗口、悬停效果等新功能。

    RequestLayout、onLayout、onDraw与drawChild的区别

  • RequestLayout():触发Measure和Layout,决定View的大小和位置。
  • onLayout():为ViewGroup内部子View布局,调用子View的onLayout。
  • onDraw():绘制View自身,ViewGroup需调用子View的onDraw。
  • drawChild():绘制ViewGroup中的子View,按顺序执行。

  • invalidate()与postInvalidate()的区别

    • invalidate():在主线程刷新视图,立即生效。
    • postInvalidate():在子线程发送消息,延迟刷新,适用于非UI线程调用。

    Android动画框架的实现原理

    Android动画框架通过Canvas进行绘制,实现透明度、缩放等效果。所有动画操作都通过View的draw方法完成,动画效果通过矩阵变换实现。


    内存分配与优化

    Android为每个应用程序分配的内存大小根据手机型号和版本而定,常见值为64M/32M。内存泄露是导致OOM的主要原因,需注意以下优化点:

  • 减少对象占用:使用ArrayMap、SparseArray等高效数据结构。
  • 优化图片加载:使用inSampleSize压缩图片,减少内存占用。
  • 复用UI元素:通过ListView、RecyclerView等实现View的复用。
  • 优化自定义控件:避免在onDraw方法中频繁创建对象。

  • Service与Activity通信

    Service与Activity之间的通信可通过Binder实现,支持远程方法调用和数据传递,适用于复杂场景。


    如需获取更多技术内容,请扫码关注!

    转载地址:http://eioyz.baihongyu.com/

    你可能感兴趣的文章