1、Android中的四大组件及其作用
2、Service与Thread的区别
Service与Thread两个完全不一样的东西
Service
Service是Android四大组件之一,被用来执行长时间的后台任务。
在默认情况下,Service是运行在主线程中,如果需要执行耗时任务,需要在Service中创建线程。
Service的优先级高于后台挂起的Activity,也高于在Activity中创建的线程,不容易被杀死,即使被杀死,在资源可用的情况下也还会被重启。
Thread
Thread跟Service根本不是一个级别的东西,Thread只是用来创建线程的一个工具类
3、PendingIntent与Intent的区别
PendingIntent跟字面意思一样,是悬而未决的,需要在一定的条件下才会触发,PendingIntent.getActivity用于获取启动Activity的PendingIntent, PendingIntent.getService用于获取启动Service的PendingIntent,PendingIntent.getBroadcast用户获取启动广播的PendingIntetn。一般用户通知栏、闹钟、发送短信通知等
而Intent是立即执行的
a. Intent是立即使用的,而PendingIntent可以等到事件发生后触发,PendingIntent可以cancel
b. Intent在程序结束后即终止,而PendingIntent在程序结束后依然有效
c. PendingIntent自带Context,而Intent需要在某个Context内运行
d. Intent在原task中运行,PendingIntent在新的task中运行
4、Binder机制
5、Handler、Looper、Message工作方式,如何在线程中使用Handler.主线程使用Handler使用Looper.loop()为什么不会ANR.
HandlerThread.
6、Activity四种启动模式及使用场景
standard、singleTop、singleTask、singleInstance
standard: 默认,每次启动都会新建一个实例
singleTop: 如果栈顶不是该实例,则新建,如果栈顶为该实例,则复用。
singleTask: 只会有一个实例,栈中如果无实例,则新建,否则移除实例上的其他对象。
singleInstance: 不管如何,都会新建一个栈,且该栈中只有这一个实例。
7、Service启动方式区别
startService: 启动之后就独立运行,跟启动者没有关联,初次启动执行onCreate,onStartCommand(onStart)已过期,后续启动只执行onStartCommand.当调用stopSelf或调用stopService之后,Service停止运行。
bindService:启动之后与启动着绑定,获得IBinder对象,调用Service中的方法。启动者退出生命周期后需要主动调用unbindService解绑,否则会造成内存泄漏。
8、Android适配、6.0动态权限分配
9、Service服务如何得知连接断开
10、Broadcast注册方式与区别以及使用场景,有序广播和无序广播的区别
静态注册和动态注册
静态注册是在mainfest中注册,在应用停止后也能够接收广播。
动态注册是在代码中使用Context.registerBroadcast注册,退出应用后收不到广播。
11、HttpClient与HttpUrlConnection的区别
HttpClient已被Google废弃,2.3之后使用HttpUrlConnection.
HttpClient提供的接口多,但是不易于扩展
HttpUrlConnection压缩和缓存机制可以有效地减少网络访问的流量,在提升速度和省电方面也起到了较大的作用
12、HTTPS域HTTP的区别
Https是在Http应用层的基础上使用安全套接字作为子层,也就是=http + SSL
Http是以http开头,而Https以https开头
http是不安全的,而https是安全的。
http对传输数据不加密,而https对数据加密
http无需证书,而https需要证书
在OSI网络模型中,http工作在应用层,而https工作在传输层。
13、UDP/HTTP/TCP/IP协议,ISO分层,三次握手,四次挥手
TCP是一种面向连接的,可靠的,基于字节流的传输控制协议。保证数据通信的完整性和可靠性,防止丢包。
IP是英特网互联协议。路由器就是基于IP协议的,解决了多个局域网之间的互通。
TCP/IP分层,应用层->传输层->网络层->物理层
三次握手:开始发送数据,确认双方发送接收都正常。
四次挥手:结束数据发送的时候。确认双方都结束。
14、排序算法
15、进程保活与进程优先级
黑色保活:不同的app进程,用广播相互唤醒(包括利用系统提供的广播进行唤醒)
白色保活:启动前台Service
灰色保活:利用系统的漏洞启动前台Service
16、加载大图
使用BitmapRegionDecoder.decodeRegion方法来加载大图中间的部分,
17、三级缓存
内存缓存(LruCache)、本地缓存(DiskLruCache)、网络缓存
18、MVC框架、MVP框架、MVVM框架
MVC允许View和Model进行交互。MVP模式只允许View和Presenter、Presenter和Model交互,不允许View和Model直接交互。
MVP优点:
1、分离了视图逻辑和业务逻辑,降低了耦合,代码更加简洁。
2、Presenter被抽象成接口,可以有多种具体的实现,所以方便进行单元测试。
3、易于扩展与维护
MVP缺点:
1、接口与类的数量变多。
2、一定层度上降低了性能。
MVVM:数据双向绑定
19、讲解一下Context
Context有众多的实现类,其中主要的有Activity、Application、Service三类。
跟UI相关的操作(启动一个Activity、Layout Inflation、Show a Dialog)应用尽量使用Activity。
20、Dalvik虚拟机与Java虚拟机的区别
Java虚拟机使用java字节码,而Dalvik使用Dalvik字节码。Dalvik由Java字节码转换而来,并打包成Dex可执行文件。
Dex可执行文件体积更小
Java虚拟机基于栈架构。而Dalvik虚拟机基于寄存器架构,速度更快。
21、JNI
22、Android的事件传递机制
答:当手指在屏幕上按下的时候,触发ACTION_DOWN事件,事件首先会调用Activity的
dispatchTouchEvent()方法去分配触摸事件,Activity实际上会调用
PhoneWindow.superDispatchTouchEvent()方法,PhoneWindow实际上只是调用代理对象
DecorView#dispatchTouchEvent()的方法,DecorView实际上是一个ViewGroup.dispatchTouchEvent()
方法中,会先去判断disallowIntercept变量的值(这个值可以由requestDisallowInterceptTouchEvent()来
变更),这个值表示是否禁用掉事件拦截功能,如果为true,就将事件分配给子控件,调用子控件的
dispatchTouchEvent()方法,如果为false,要先调用onInterceptTouchEvent()方法来判断是否拦截事
件,如果返回true,表示拦截事件,则事件直接传给super.dispatchTouchEvent(),也就是View里面的
事件分发,这个等下会讲到。如果返回false,则不进行拦截事件,就将事件分发给子控件,如果子控
件中有一个dispatchTouchEvent()方法返回了true,则事件分发流程结束。否则就调用自己的
super.dispatchTouchEvent()。那么子控件是如何进行事件分配呢?首先如果子控件是ViewGroup,那
么分配方式跟刚才的DecorView一致,一层层分发下去,如果子控件是View类型的,那就是调用
View.dispatchTouchEvent()方法。在这个方法中,如果有给View设置了onTouchListener并且View是
Enable的时候,会先回调onTouchListener中的onTouch方法,如果这个方法返回了true,就直接结束事件
分发了。否则会调用onTouchEvent()方法,在这个方法中,回去判断单击(performClick),长按
(performLongClick)等方法。也就是设置了onClickListener,onLongClickListener等监听器。如果这里返
回了false,那么后续的事件就不会再进入了。这样一个事件流程就结束了。
23、onSaveInstanceState()
24、性能优化
答:主要由几个方面去优化性能:
- 内存优化
避免创建不必要的对象:String拼接,使用基本类型代替封装类int->Integer.
界面不可见的时候释放内存。Actvity中onTrimMemory释放内存。
避免浪费内存:只加载需要的分辨率图片,options.inSampleSize.
避免在频繁调用的方法中创建临时对象。
内存泄漏:IntentService代替Service,合理使用静态对象和内部类
- 编码优化
使用静态常量代替枚举类型
使用经过优化的数据集合类型-SparseArray
尽可能使用系统API,比如System.arraycopy
使用foreach代替其他遍历方式,ArrayList除外
静态由于继承,对于不使用到字段的工具类方法静态化
避免使用依赖注入框架
避免内部使用getter、setter
ProGuard简化代码,除了混淆之外,还具有压缩和优化代码的功能
- 布局优化
使用include复用布局
使用merge和自定义View减少布局层级
使用自定义View减少控件数量
使用ViewStub只在需要时加载控件
25、Android绘制流程
Activity调用setContentView之后,Activity调用PhoneWindow,PhoneWindow以DecorView作为根传入>LayoutInflater.最后会调用DecorView中ViewRoot的requestLayout方法开始绘制,该方法中会调用>scheduleTraversals方法,该方法最终会调用ViewRootImpl的performTraversales()。这个方法中会调
用performMeasure,performLayout,performDraw
measure: 判断是否需要重新计算View的大小,需要的话则计算;
layout: 判断是否需要重新计算View的位置,需要的话则计算;
draw: 判断是否需要重新绘制View,需要的话则重绘制。