Android知识点汇总
Activity生命周期:
正常流程:onCreate()->onStart()->onResume()->onpause()->onStop()->onDestory();
再次点击回到Activity:onRestart()->onStart()->onResume()
2.service生命周期:
(1)通过startService()启动:
startService()->onCreate()->onStartCommon()->onDestory();
在startService()被反复执行时,在ocreate中会触发onceOnly(ocreate),而oscmultipleTimes(osc)则会被持续触发。
调用stopService(),onDestory()执行,销毁服务;
通过intent传值时,必须判null
(2)通过bindService()启动:
bindService()->onCreate()->onBind()->unBind()->onDestory()
3.Activity启动过程:
通过调用startActivitySafely()方法并结合PMS机制对AndroidManifest.xml文件进行解析,在服务层和广播层提取与服务(service)、广播(broadcast)相关的应用程序信息以及启动所需的活动配置(包括action和category)。随后,在内部直接调用startActivityForResult()即可完成无需返回结果的操作;当无需返回结果时,在内部直接调用startActivityForResult()即可;通过Instrumentation类中的execStartActivity()方法获取 AMS 的代理对象,并利用该代理对象执行后续操作;当应用启动时,在 scheduleLaunchActivity() 方法下生成 ActivityClientRecord 对象,并根据该对象执行相应的操作以启动组件;最后通过handleLaunchActivity方法完成整个组件的启动流程
4.Broadcast注册方式与区别:
(1)静态注册:
其特点在于不受网页生命周期的影响。即使退出页面也会继续接收广播信息,并导致使用一定数量的CPU资源。通常应用于系统在开机时自动启动的各种场景。
(2)动态注册:
特点:它会受到页面生命周期的影响,在退出页面时不会接收广播,并且处于较高的优先等级以实现用户界面更新;
5.HttpClient和HttpUrlConnection的区别:
HttpClient的api很多,但是不易扩展,所以在6.0时已经废弃;
HttpUrlConnection比较轻量级,易扩展;
6.Java虚拟机与Dalvik虚拟机区别:
Java虚拟机:
该系统的特点是以栈作为其核心数据结构,并采用一系列指令序列用于加载和执行栈内的数据操作。由于所需的指令数量较多,并且运行在Java虚拟机之上。
Dalvik虚拟机:
特点:基于寄存器,运行.dex字节码格式,常量池被修改为只使用32位所有,
一个应用实例、一个虚拟机实例以及一个独立的进程被分配给每个D Dalvik应用程序。
7.进程保活:
(1)黑色保活:不同的app进程,用广播相互唤醒(包括利用系统广播进行唤醒)
例1:开机,网络切换,拍照,拍视频等,利用系统产生的广播进行唤醒;
例2:集成第三方软件开发库同样会激活相关应用程序进程;例如打开支付宝可能会触发淘宝的相关功能。
(2)白色保活:启动前台Service
调用系统的api启动一个前台的Service进程
(3)灰色保活:利用系统漏洞启动一个前台的service:
实现思路:api<18时,启动前台Service时直接传入new Notification();
在API版本达到或超过18时,在同一时间开启两个具有相同ID的前后台Service,并在后续启动的那个Service完成之后执行停止操作
8.关于Context:提供一些程序的运行环境基础信息;
两个子类:
(1)该类为Context的一种封装实现,在其下属三个子类中分别对应了Application、service以及ContextThemeWrapper三个功能模块。其中ContextThemeWrapper特指带主题功能的封装类,在实际应用中较为少见;而Activity继承自该封装基类,在开发实践中较为常见。综上所述,在Android生态体系中通常将应用划分为Application、Service和Activity三大类型;其中Application和Service两种类型在大多数场景下均可实现相同的业务逻辑功能;然而当存在特殊需求时则需采用Activity来完成相关的操作流程;需要注意的是,在启动新活动或弹出对话框的过程中必须基于已有活动进行操作,并且根据Android官方规范禁止在任意页面直接出现Dialog界面元素;只有当某个活动被激活后才允许在其之上弹出对话框供用户交互操作。
(2)ContextImpl是一个专门负责处理与上下文相关功能的功能实现类;它所包含的具体功能类型均是通过调用该实例来完成相应的操作;
9.理解Activity,Window,View三者关系:
Activity将负责创建一个名为PhoneWindow的窗口。该手机窗口包含一个ViewRoot组件。这个组件既可以是一个单独的View,也可以被视为一个ViewGroup。
利用addView方法逐个地将各个View加入到ViewRoot中。每个View都带有相应的监听事件响应机制,并通过WindowManageService来处理来自设备的消息。
利用addView方法逐个地将各个View加入到ViewRoot中。每个 View 都带有相应的 监听 事件响应机制,并通过 WindowManageService 来处理来自设备的消息。
比喻:Activity就像是一位能工巧匠(工匠),View就像是精美的艺术品(窗花),Window就像是一个透明的窗口(窗户),Facade适配类工具包实现了与Android系统交互的需求;Xml文件就像绘制窗户蓝图的详细说明。
10.四种LaunchMode及其使用场景:
(1)Standard(标准)模式:
启动方式定义为:每当一次Activity被激活时,系统都会生成一个新的Activity实例,并将其压入任务栈中。
使用场景:大多数的Activity
(2)singleTop(栈顶复用)模式:
启动策略规定:当任务栈顶端存在一个对应的Activity实现时,则可直接使用该现有实例(将执行其onNewIntent方法),否则就需要生成新的一个此类Activity对象。
使用场景:新闻类或者阅读类App的内容页面;
(3)singleTask(栈内复用)模式:
启动方式采用如下策略:当栈内存在该Activity类的一个实例时,在复用过程中会触发该Activity的onNewIntent事件。当一个Activity被重用时,它会被移动到栈顶位置上,并导致位于其上方的所有Activity会被移出栈体。
场景描述:当从任意多个应用启动浏览器时
(4)singleInstance(单实例)模式:
启动策略涉及在独立的新线程环境中生成一个特定的应用程序实例, 并允许所有这些应用程序共用这个活动实现. 当其他任何应用程序再次启动这个活动时, 这些重用了同一个实现的所有后续操作将直接访问并执行相应的intent方法(如...onNewIntent()). 等效于所有这些应用场景实际都采用了同一个具体实现.
使用场景:闹铃提醒,将闹铃与设置相分离;
11.View的绘制流程:(自定义控件的过程)
关于自定义控件:
自定义控件:无需自行绘制界面,即通过将多个原生控件进行组合实现对新界面的承载。例如标题栏元素。
(2)继承现有功能模块:除了原生控件提供的基础功能之外,在项目中增添一些自定义的功能。例如,在界面设计中添加圆角和圆形图片等元素;
(3)定制化控件:通过指定的开发接口如onMeasure、onLayout和onDraw等实现自定义绘制功能;例如创建水波纹型进度条。
关于View的绘制流程:
onMeasure():计算视图尺寸,并从顶层父VIew向下依次计算各子View的尺寸;当measure方法完成计算后会再次触发onMeasure()函数。
(2)onLayout():计算View位置的过程是从顶层父View开始递归地将子View纳入布局计算过程,在此过程中,父View根据上一步骤对子View进行尺寸与布局参数测量,并依据这些信息将子View安置于适当的位置。
在onDraw方法中进行绘图操作,在ViewRoot中创建一个Canvas对象后随后调用相同的onDraw方法完成六步流程
<1>绘制视图的背景
<2>保存画布的图层(Layer)
<3>绘制VIew的内容
<4>绘制VIew的子视图(如果没有就不用)
<5>还原图层
<6>绘制滚动条
12.android事件分发机制:
从Activity发起事件传递开始,在onDispatchTouchEvent()方法中经super向下传递事件时,默认会将事件发送至viewGroup中;当onDispatchTouchEvent()返回super()时,则会继续将事件转发给子view的onInterceptTouchEvent()方法;若子view的onInterceptTouchEvent()返回super()则停止分发;若返回true则子view自身会处理本层事务并调用自身的onTouchEvent()方法;若上层返回false则继续向上转发;当子view的onDispatchTouchEvent()返回super()时,则会将事件传送给自身的onTouchEvent()方法;若返回true则停止分发;若返回false则继续向上转发;当子view的ontouchEvent()方法返回super()或false时,则完成事件转发过程;若ontouchEvent()返回false则会继续向上转发该事件。
当一个Android Activity接收触控事件时,会将所有子View进行触控事件的分发;如果某个View需要此触控事件,则应在该View自身的onTouchEvent方法中返回true.
13.保存Actiivty状态:
saveInstanceState(Bundle)方法会在activity切换至后台状态前被调用,在onPause()方法之后,在执行onStop()方法之前。
14.Android几种动画:
(1)帧动画:通过安排每一帧的图片和播放事件,并按照一定的顺序进行播放而形成的动画效果;其中,图片部分包含背景图、角色图以及场景图等基本元素;播放事件部分则主要涵盖启动、结束、重放以及重复播放等功能;
(2)补间动画:由指定view的初始状态决定其变换时长和变换路径或模式,并基于一系列算法实现图形转换过程以生成动画效果。该技术特别关注于alpha通道、缩放、平移和旋转四种核心操作,并确保这些操作不会影响到view本身的属性
(3)属性动画:通过不断的改变view的属性,不断的重绘而形成动画效果;
15.Android跨进程通信的几种方式:
(1)service
(2)广播
(3)binder
(4)contentprovider
(5)intent
16.binder机制:
每个进程都配置了一个D Dalvik虚拟机实例,并专设有属于自身的内存区域,在其内存中存储着自身数据并负责执行各自的操作;其中Binder充当了两个进程之间通信的中介,并由客户端(Client)、服务端(Service)、服务管理器(Servicemanager)以及Binder驱动程序组成;其中客户端(Client)和服务端(Service)运行在用户空间中;而Binder驱动程序则位于内核空间中。
17.Handler原理:
在Handler系统中包含四个关键的对象:handler、message、messageQueue以及Looper循环处理单元;其中,在收到请求后, handler负责将消息发送至消息队列;Looper循环处理单元则会持续地从消息队列中提取并传递消息给handler进行处理
18.热修复原理:
每当虚拟机需要加载一个类时, 都会依赖于 ClassLoader 类加载器来进行操作. 其中包含一个名为 BaseDexClassLoader 的子类, 它下面还有一个名为 DexPathList 的数组, 用于存储 dex 文件. 当 BaseDexClassLoader 调用 findClass() 方法时, 其本质上是遍历该数组中的元素, 寻找与所需 class 对应的 dex 文件. 找到对应的 dex 文件后就直接返回; 然而, 热修复机制则是将新的 dex 文件插入到该列表中, 并且总是放在旧文件的前面. 因此, 在后续的操作中会优先取出这些文件并进行处理.
19.android内存泄漏即管理:
(1)handler,Asynctask等引起的内存泄漏;
实现方式:将handler声明为静态嵌套类,并持有一个外部对象的弱引用,在onDestroy事件处理中触发removeAllMessage方法;
(2)单例模式下的内存泄漏:
提供applicationContext, 因为ApplicationContext的生命周期与App保持一致, 从而避免了潜在的内存泄漏问题.
(3)非静态内部类创建静态实例引起的内存泄漏:
解决方法:将内部类修改为静态的
(4)资源对象没有关闭引起
(5)集合对象没有及时清理
(6)注册/反注册未成对使用
20.fragment与fragment,activity通信的方式:
(1)直接在fragment中调用另外一个fragment中的方法;
(2)使用接口回调
(3)使用广播
(4)fragment直接调用Activity的public方法
21.app优化问题“
(1)冷启动优化:当app处于未启动状态或其进程被强行终止时,在系统资源中并未记录该app进程的信息;在onCreate事件处理阶段以及首屏Activity的渲染流程中应当避免进行时间较长的操作;如果确实需要执行这些耗时操作,则应将其逻辑封装至子线程或者调用IntentService实现以保证主线程响应速度
(2)布局优化:应尽量避免过度复杂的嵌套结构,并推荐采用merge、viewStub和include等标准组件进行组织。当布局需求极为复杂时,则可选择开发自定义组件以满足特定需求
(3)响应优化:Android系统每隔16ms会发出VSYNC
UI卡顿的原因:
<1>过于复杂的布局
<2>主线程做了复杂运算
<3>频繁发生的GC操作通常会引发内存抖动现象。造成GC操作频繁发生的主要原因是两个主要原因:一是系统在执行过程中会快速生成大量新的对象并随后迅速销毁它们;二是程序运行过程中可能出现瞬间产生大量临时对象的情况而导致内存占用过高。其中,在序列化操作时使用Serializable进行序列化处理属于内存抖动的一种常见原因
(4)电池优化:
<1>优化网络请求
<2>定位中使用GPS,记得关闭
(5)网络优化:
<1>使用GZip压缩request和response,减少传输数据量,从而减少流量消耗
<2>适当做网络缓存
<3>可以和服务端沟通,优化API
(5)图片优化
在处理图片时,建议避免采用setImageBitmap、setImageResource及BitmapFactory.decodeResource等方法来设置大尺寸图片;这是因为这些方法均需在解码完成后经由Java层的createBitmap方法处理,最终会导致较大的内存占用问题。
<2>图片进行缩放的比例,sdk建议值为2;
<3>不用的图片需要调用recycle()方法回收内存
22.Java GC
GC算法的本质机制是通过分析内存管理机制中的堆空间来识别程序运行时占用的内存区域。该过程主要分为两个阶段:一是通过检查这些内存区域是否被其他活动生成的对象引用来区分存活对象与垃圾对象——若被其他活动生成的对象引用,则属于存活对象;否则属于可回收的垃圾对象。二是选择合适的GC策略及其优化配置对系统性能有着显著影响。
23.ANR
产生原因:
(1)5s内无法响应用户输入事件(例如键盘的输入,触摸屏幕等)
(2)BroadcastReceiver在10s内无法结束
(3)Service在20s内无法结束
解决方法:
避免在主线程中执行长时间的操作,并建议将这些耗时的操作限制为仅在子线程中的onCreate()和onResume内进行,并且尽量减少其数量
(2)应用程序应该避免在BroadcastReceiver里进行耗时操作
不向Intent receiver启动一个Activity,因为这会导致创建一个新的界面,从而从当前用户正在运行的程序中夺取焦点
Service运行在其主线程上,在Service内部进行耗时操作时需要特别注意将这些操作置于子线程内以避免潜在的问题
