1、如何对Android应用进行性能分析
答案:
App启动优化
在APP冷启动、热启动、温启动过程中不要进行耗时的操作。
布局优化
尽量减少布局层级和复杂度
响应优化
主线程阻塞的:开辟单独的子线程来处理耗时阻塞事务.
CPU满负荷, I/O阻塞的:I/O阻塞一般来说就是文件读写或数据库操作执行在主线程了, 也可以通过开辟子线程的方式异步执行.
内存不够用的:增大VM内存, 使用largeHeap属性, 排查内存泄露(这个在内存优化那篇细说吧)等.
内存优化
避免频繁的GC:执行GC操作的时候,任何线程的任何操作都会需要暂停,等待GC操作完成之后,其他操作才能够继续运行, 故而如果程序频繁GC, 自然会导致界面卡顿.
内存抖动(Memory Churn), 即大量的对象被创建又在短时间内马上被释放.
瞬间产生大量的对象会严重占用Young Generation的内存区域, 当达到阀值, 剩余空间不够的时候, 也会触发GC. 即使每次分配的对象需要占用很少的内存,但是他们叠加在一起会增加Heap的压力, 从而触发更多的GC.
网络优化
1.减少网络数据获取的频次:这就减少了radio的电量消耗, 控制电量使用.
2.减少获取数据包的大小:可以减少流量消耗,也可以让每次请求更快
3.Gzip压缩:使用Gzip来压缩request和response, 减少传输数据量, 从而减少流量消耗.
4.网络缓存:适当的缓存, 既可以让我们的应用看起来更快, 也能避免一些不必要的流量消耗.
5.
2、什么情况下会导致内存泄露
内存泄露根本原因:长生命周期的对象持有短生命周期的对象,导致短周期对象无法及时释放;
3、如何避免OOM异常
OOM,全称“Out Of Memory”,翻译成中文就是“内存用完了”
1.比如虚拟机本身可使用的内存(一般通过启动时的VM参数指定)太少。
2.应用用的太多,并且用完没释放,浪费了。此时就会造成内存泄露或者内存溢出。
资源对象没关闭造成的内存泄露,try catch finally中将资源回收放到finally语句可以有效避免OOM。
1-1,Cursor
1-2,调用registerReceiver后未调用unregisterReceiver()
1-3,未关闭InputStream/OutputStream
1-4,Bitmap使用后未调用recycle()
作用域不一样,导致对象不能被垃圾回收器回收
非静态内部类会隐式地持有外部类的引用
内存压力过大
3-1,图片资源加载过多,超过内存使用空间,例如Bitmap 的使用
3-2,重复创建view,listview应该使用convertview和viewholder
处理方法:
3-1.使用缓存技术,比如LruCache、DiskLruCache、对象重复并且频繁调用可以考虑对象池
3-2.对于引用生命周期不一样的对象,可以用软引用或弱引用SoftReferner WeakReferner
4、Android中如何捕获未获得的异常
CrashHandler
关键是实现Thread.UncaughtExceptionHandler
然后是在application的oncreate里面注册。
5、ANR如何避免和解决
5-1.KeyDispatchTimeout(5 seconds) --主要类型按键或触摸事件在特定时间内无响应
5-2.BroadcastTimeout(10 seconds)BroadcastReceiver在特定时间内无法处理完成
5-3.ServiceTimeout(20 seconds) --小概率类型Service在特定的时间内无法处理完成超时的
6、android线程间通信有那几种方式
1. 通过Handler机制
2. runOnUiThread方法
3. View.post(Runnable r)
4. AsyncTask
7、Devik进程,Linux进程,线程的区别
8、android系统架构
从下往上依次分为Linux内核、HAL、系统Native库和Android运行时环境、Java框架层以及应用层这5层架构,其中每一层都包含大量的子模块或子系统。
9、android对内存是如何限制的,我们该如何合理使用内存
通过activitymanager.getMemoryClass() 获取内存限制。
10、android运行时权限与系统权限的区别
11、Framework的工作方式以及原理,Activity如何生成一个View,机制是什么
所有的框架都是基于反射 和 配置文件(manifest)的。
普通的情况:Activity 创建一个 view 是通过 ondraw 画出来的, 画这个 view 之前呢,还会调用 onmeasure 方法来计算显示的大小.
特殊情况:Surfaceview 是直接操作硬件的, 因为 或者视频播放对帧数有要求,onDraw 效率太低,不够使,Surfaceview 直接把数据写到显存。
12、多线程与多进程之间通信有什么不同,怎么实现
13、android屏幕适配
1.屏幕分辨率限定符适配
根据当前市面上手机的屏幕的分辨率创建不同的文件夹,系统运行的时候,会自动去选择读取对应的文件夹中的xml,即每种屏幕分辨率的设备需要定义一套 dimens.xml 文件
14、AIDL如何使用
用在Android进程间通信中,Android中有一种进程间通信方式是Binder,AIDL就是帮我们自动生成了Binder相关代码,不需要我们自己去手动书写复杂的Binder类,我们只需要在AIDL接口文件中书写自己的调用远程服务的业务方法就可以了,大大简化了开发过程。当然,AIDL不是Binder通信所必须的,我们也可以不使用AIDL而自己去书写Binder代码。
AIDL支持的数据类型
基本数据类型(int、long、char、boolean、double等);
String和CharSequence;
List:只支持ArrayList,而且里面的每个元素也必须是AIDL所支持的类型;
Map:只支持HashMap,而且里面的每个key和value都必须是AIDL所支持的类型;
Parcelable:所有实现了Parcelable接口的对象;
AIDL:所有的AIDL接口自身也可以在AIDL中使用;
使用步骤:
步骤1:在server端添加aidl包,在里面添加Book.java、Book.aidl、IBookManager.aidl三个文件。
Book.java类,需要实现Parcelable接口
Book.aidl文件,需要声明一下:package com.znh.aidl.server; parcelable Book;
IBookManager.aidl文件:接口
步骤2:编译server端代码,会自动生成一个 IBookManager的java类, 里面书写了Binder相关代码。
步骤3:编写远程服务代码RemoteService
步骤4:在server端的清单文件中注册该服务:
步骤5:经过以上4步,服务端代码就编写完毕了,接下来,把服务端的aidl包连同它下面的文件都拷贝到客户端,aidl文件的包名不能变,要和服务端保持一致
15、Handle机制
//说明:该方法的使用时机是当前view在attachdToWindow之后进行调用的。其中post的调用时机分为两种:
// 当 View 还没 attachedToWindow 时,会先将这些 Runnable 操作缓存下来,等attachedToWindow之后在主线程执行。
// 否则就直接通过 mAttachInfo.mHandler 将这些 Runnable 操作 post 到主线程的 MessageQueue 中等待执行。
16、事件分发机制
17、如何修改Activity的进入和退出动画
1.使用代码设定
通过调用overridePendingTransition() 可以实时修改Activity的切换动画。但需注意的是:该函数必须在调用startActivity()或者finish()后立即调用,且只有效一次。
2.修改Activity Theme
例子:
<style name="AnimationActivity" parent="@android:style/Animation.Activity">
<item name="android:activityOpenEnterAnimation">@anim/slide_in_left</item>
<item name="android:activityOpenExitAnimation">@anim/slide_out_left</item>
<item name="android:activityCloseEnterAnimation">@anim/slide_in_right</item>
<item name="android:activityCloseExitAnimation">@anim/slide_out_right</item>
</style>
然后在themes.xml中
<style name="ThemeActivity">
<item name="android:windowAnimationStyle">@style/AnimationActivity</item>
<item name="android:windowNoTitle">true</item>
</style>
在AndroidMainfest.xml中为Activity指定theme
18、SurfaceView与View 的区别
surfaceView和View最本质的区别在于:
surfaceView是在一个新起的单独线程中可以重新绘制画面,而View必须在UI的主线程中更新画面。那么在UI的主线程中更新画面
可能会引发问题,比如你更新画面的时间过长,那么你的主UI线程会被你正在画的函数阻塞。那么将无法响应按键,触屏等消息。
surfaceView由于是在新的线程中更新画面所以不会阻塞你的UI主线程。但这也带来了另外一个问题,就是事件同步。
22、进程保活
如何查看进程解基本信息 通过adb shell ps|grep <package_name>的方式来查看它的基本信息
通过修改进程的优先级达到保活
25、android Fragment生命周期与Activity生命周期
Fragment生命周期:
场景演示 : 切换到该Fragment
onAttach
onCreate
onCreateView
onActivityCreated
onStart
onResume
屏幕灭掉:
onPause
onSaveInstanceState
onStop
屏幕解锁
onStart
onResume
切换到其他Fragment:
onPause
onStop
onDestroyView
切换回本身的Fragment:
onCreateView
onActivityCreated
onStart
onResume
回到桌面
onPause
onSaveInstanceState
onStop
回到应用
onStart
onResume
退出应用
onPause
onStop
onDestroyView
onDestroy
onDetach
26、线程锁、线程安全、多线程
线程的状态:
new : 线程被创建
runnable : 线程处于可运行或者正在运行状态,
blocked : 线程被阻塞,等待获取对象锁
sleep : 休眠状态,过程不释放对象锁
join : 在B线程中执行A.join,则B进入等待状态,直到A执行完毕
yield : 降低线程优先级,如果其他线程需要则让给其他线程,但此方法不一定会使线程处于暂停状态
27、String 、StringBuffer 、StringBuild区别
String 字符串常量
StringBuffer 字符串变量(线程安全)
StringBuilder 字符串变量(非线程安全)
String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象
StringBuilder和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。
(1)如果要操作少量的数据用 String;
(2)多线程操作字符串缓冲区下操作大量数据 StringBuffer;
(3)单线程操作字符串缓冲区下操作大量数据 StringBuilder。
28、ArryList 与LinkedList的区别
ArrayList是Array(动态数组)的数据结构,LinkedList是Link(链表)的数据结构。
当随机访问List(get和set操作)时,ArrayList比LinkedList的效率更高,因为LinkedList是线性的数据存储方式,所以需要移动指针从前往后依次查找。
当对数据进行增加和删除的操作(add和remove操作)时,LinkedList比ArrayList的效率更高,因为ArrayList是数组,所以在其中进行增删操作时,会对操作点之后所有数据的下标索引造成影响,需要进行数据的移动
29、HashTable 、HashMap 区别
Hashtable继承自Dictionary类,而HashMap继承自AbstractMap类。但二者都实现了Map接口。
Hashtable计算hash是直接使用key的hashcode对table数组的长度直接进行取模:
HashMap计算hash对key的hashcode进行了二次hash,以获得更好的散列值,然后对table数组长度取摸
HashMap的初始容量为16,Hashtable初始容量为11,两者的填充因子默认都是0.75。
HashMap扩容时是当前容量翻倍即:capacity*2,Hashtable扩容时是容量翻倍+1即:capacity*2+1。
HashMap是非线程安全的,只是用于单线程环境下,多线程环境下可以采用concurrent并发包下的concurrentHashMap。HashTable是线程安全的。
HashMap中key和value都允许为null。key为null的键值对永远都放在以table[0]为头结点的链表中。HashTable在遇到null时,会抛出NullPointerException异常。
HashMap仅支持Iterator的遍历方式,Hashtable支持Iterator和Enumeration两种遍历方式。
判断是否含有某个键 :
在HashMap 中,null 可以作为键,这样的键只有一个;可以有一个或多个键所对 应的值为null。当get()方法返回null 值时,既可以表示HashMap 中没有该键,也可 以表示该键所对应的值为null。因此,在HashMap 中不能用get()方法来判断HashMap 中是否存在某个键,而应该用containsKey()方法来判断
Hashtable 的键值都不能为null,所以可以用get()方法来判断是否含有某个键。
- Service的绑定与解绑,生命周期
31、BrodcastRecive
32、ListView、RcycleView的优化
RecyclerView缓存寻找过程:
RecyclerView在找到可用ViewHodler的顺序是:如果在缓存CacheViews中找到,则直接复用;如果在缓存池RecycerViewPool找到,则需要bindView;如果没有找到可用的ViewHolder,则需要create新建一个ViewHolder,并bindView绑定view
当Item的高度如是固定的,设置这个属性为true可以提高性能,尤其是当RecyclerView有条目插入、删除时性能提升更明显。RecyclerView在条目数量改变,会重新测量、布局各个item,如果设置了setHasFixedSize(true),由于item的宽高都是固定的,adapter的内容改变时,RecyclerView不会整个布局都重绘。具体可用以下伪代码表示
优化: 局部刷新,避免过多的创建对象
33、http、https、tcp\ip
TCP/IP协议中最重要的特点就是分层。由上往下分别为 应用层,传输层,网络层,数据链路层,物理层。
TCP/IP(Transmission Control Protocol/Internet Protocol,传输控制协议/网际协议)是指能够在多个不同网络间实现信息传输的协议簇。同时是Internet最基本的协议、Internet国际互联网络的基础,由网络层的IP协议和传输层的TCP协议组成
UDP 和 TCP 的特点:
用户数据报协议 UDP(User Datagram Protocol):无连接;尽最大努力的交付;面向报文;无拥塞控制;支持一对一、一对多、多对一、多对多的交互通信
传输控制协议 TCP(Transmission Control Protocol):面向连接;每一个TCP连接只能是点对点的(一对一);提供可靠交付服务;提供全双工通信;面向字节流。
TCP的三次握手与四次挥手:
第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。
当数据传送完毕,断开连接就需要进行TCP的四次挥手:
第一次挥手,客户端设置seq和 ACK ,向服务器发送一个 FIN(终结)报文段。此时,客户端进入 FIN_WAIT_1状态,表示客户端没有数据要发送给服务端了。
第二次挥手,服务端收到了客户端发送的 FIN 报文段,向客户端回了一个 ACK 报文段。
第三次挥手,服务端向客户端发送FIN 报文段,请求关闭连接,同时服务端进入 LAST_ACK 状态。
第四次挥手,客户端收到服务端发送的 FIN 报文段后,向服务端发送 ACK 报文段,然后客户端进入 TIME_WAIT状态。服务端收到客户端的 ACK 报文段以后,就关闭连接。此时,客户端等待2MSL(指一个片段在网络中最大的存活时间)后依然没有收到回复,则说明服务端已经正常关闭,这样客户端就可以关闭连接了
HTTPS:是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。
HTTPS协议的主要作用可以分为两种:一种是建立一个信息安全通道,来保证数据传输的安全;另一种就是确认网站的真实性。
HTTPS 并非是应用层的一种新协议。只是 HTTP 通信接口部分用SSL(Secure Socket Layer)和 TLS(Transport Layer Security)协议代替而已。通常,HTTP 直接和 TCP 通信。当使用 SSL时,则演变成先和 SSL通信,再由 SSL和 TCP 通信了。简言之,所谓 HTTPS,其实就是身披SSL协议这层外壳的 HTTP。
34、android动画,属性动画
插值器:根据时间流逝的百分比计算出当前属性值改变的百分比。
估值器:根据当前属性改变的百分比来计算改变后的属性值。
默认插值器:
LinearInterpolator 线性(匀速)
AccelerateInterpolator 持续加速
DecelerateInterpolator 持续减速
AccelerateDecelerateInterpolator 先加速后减速
OvershootInterpolator 结束时回弹一下
AnticipateInterpolator 开始回拉一下
BounceInterpolator 结束时Q弹一下
CycleInterpolator 来回循环
35、android 版本兼容性问题
答案:可以利用高版本的SDK开发应用,并在程序运行时(Runtime)对应用所运行的平台判断,旧平台使用旧的API,而新平台可使用新的API,这样可以较好的提高软件兼容性,在应用运行期间获取版本号,版本之间向下兼容
36、android各个版本之间的区别