Android 面试---Android基础知识点一

1.横竖屏切换的时候,Activity 各种情况下的生命周期

1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次

2、设置Activity的android:configChanges="orientation"时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次

3、设置Activity的android:configChanges="orientation|keyboardHidden|screenSize"时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法

4、当前Activity产生事件弹出Toast和AlertDialog的时候Activity的生命周期不会有改变.

5、Activity运行时按下HOME键(跟被完全覆盖是一样的):onSaveInstanceState --> onPause --> onStop onRestart -->onStart--->onResume;

6、Activity未被完全覆盖只是失去焦点:onPause--->onResume

2.说说ContentProvider、ContentResolver、ContentObserver 之间的关系

ContentProvider——内容提供者, 在android中的作用是对外共享数据,也就是说你可以通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider 对你应用中的数据进行添删改查。
ContentResolver——内容解析者, 其作用是按照一定规则访问内容提供者的数据(其实就是调用内容提供者自定义的接口来操作它的数据)。
ContentObserver——内容观察者,目的是观察(捕捉)特定Uri引起的数据库的变化,继而做一些相应的处理,它类似于数据库技术中的触发器(Trigger),当ContentObserver所观察的Uri发生变化时,便会触发它。

3.如何优化自定义View

(1)减少不必要的代码:对于频繁调用的方法,需要尽量减少不必要的代码。

(2)不在 onDraw 中做内存分配的事:先从 onDraw 开始,需要特别注意不应该在这里做内存分配的事情,因为它会导致 GC,从而导致卡顿。在初始化或者动画间隙期间做分配内存的动作。不要在动画正在执行的时候做内存分配的事情。

(3)减少 onDraw 被调用的次数:大多数时候导致 onDraw 都是因为调用了 invalidate().因此请尽量减少调用 invaildate()的次数。如果可能的话,尽量调用含有 4 个参数的 invalidate()方法而不是没有参数的 invalidate()。没有参数的 invalidate 会强制重绘整个 view。

(4)减少 layout 的次数:一个非常耗时的操作是请求 layout。任何时候执行 requestLayout(),会使得 Android UI 系统去遍历整个View 的层级来计算出每一个 view 的大小。如果找到有冲突的值,它会需要重新计算好几次。

(5)选用扁平化的 View:另外需要尽量保持 View 的层级是扁平化的(去除冗余、厚重和繁杂的装饰效果),这样对提高效率很有帮助。

(6)复杂的 UI 使用 ViewGroup:如果你有一个复杂的 UI,你应该考虑写一个自定义的 ViewGroup 来执行他的 layout 操作。(与内置的view 不同,自定义的 view 可以使得程序仅仅测量这一部分,这避免了遍历整个 view 的层级结构来计算大小。)继承 ViewGroup作为自定义 view 的一部分,有子 views,但是它从来不测量它们。而是根据他自身的 layout 法则,直接设置它们的大小。

4.如何在低版本SDK调用高版本API?

随着Android SDK版本不断的迭代更新,在新的SDK上总是会出现让人眼前一亮非常方便好用的API。但是这些新的API呢在低版本的SDK上是没有的,所以当我们的minSdkVersion的版本低于新API所在的版本时,我们直接使用新API在编译时会出现报错。如果只是想解决编译报错的问题呢,Android给我们提供了两种注解的方式避免编译时报错:

@SuppressLint
@TargetApi
这两种方法又有什么区别呢?

. SupressLint和TargetApi
SupressLint很显然的意思是忽略Lint检查,对于我们使用高版本API来说,可以使用@SuppressLint("NewApi")的方式让Lint在编译时忽略所调用API对版本的要求。而@TargetApi是忽略特定版本的API调用报错。

举个栗子:当你的项目minSdkVersion=9,你想使用API 11的新的方法时。此时,使用@TargetApi(11)和@SuppressLint("NewApi")的效果一样,代码都不会报错。但是如果你使用了Api 19才出现的新的方法时,在使用@TargetApi的方法中还是会给你报错,而在另一个方式中依然不会报错。

那这么讲使用@SuppressLint("NewApi")就更好了?

. 正确的使用姿势
当然不是啦!我们要清楚一点,使用上面两种注释的方式只是让lint在编译时不再报错,在低版本的手机系统中,如果直接使用高版本的API肯定会报:“NoSuchMethod”的Crash的。

所以正确的做法应该是在注解的方法中,做版本判断,在低版本中依然使用老的方式处理。版本判断时我们需要判断具体的版本号

5. 网络请求的流程

1.通过URL找IP
如何去找IP地址呢,首先先是本地的缓存,一般是以Hosts文件的形式存在,维持着一个带域名的服务器地址对IP的对应关系,路由器缓存(也算是DNS服务器缓存)

如果没有结果,则会向上层DNS服务器询问,上层DNS服务器的本地缓存中如果没有该记录,则再向上层询问,一直到DNS根服务器。

在根域名服务器中虽然没有每个域名的具体信息,但储存了负责每个域(如COM、NET、ORG等)的解析的域名服务器的地址信息。根域名服务器会将其管辖范围内顶级域名(如.com)服务器IP告诉本地DNS服务器,这样你的域名查询请求会进入到相应的顶级域名服务器。顶级域名服务器收到请求后查看区域文件记录,若找到则将其管辖范围内主域名(不带任何前缀的域名,如 baidu.com)服务器的IP地址告诉本地DNS服务器。如果还是没有找到,则进入到下一级域名服务器进行查找。如此重复,直到找到正确的 结果为止,返回 IP地址结果给本地DNS服务器。

本地DNS服务器缓存结果,设置(Time-To-Live)即一条域名解析记录在DNS服务器上缓存时间,关于TTL如果IP经常改变,那么TTL设的短一点长一点都没有太大的 影响,而如果IP经常不变,可以把TTL时间拉长,这样有利于提高命中率。

2.对IP结果建立TCP连接

自己主机IP端口的对目标IP的端口(例:http://www.baidu.com http协议所占用的TCP端口为80端口)三次握手建立TCP连接。

3.向服务器发送数据

浏览器将网络请求封装成HTTP报文,把HTTP报文通过TCP的分包,分成一个个TCP数据包。IP层把上层传输层数据包打包成IP层数据包,并把该数据包发送到更低层数据链路层,相反,IP层也把从低层接收来的数据包传送到更高层TCP或UDP层。(补:IP数据包是不可靠的,因为IP并没有做任何事情来确认数据包是否按顺序发送的或者有没有被破坏,IP数据包中含有发送它的主机的地址(源地址)和接收它的主机的地址(目的地址))

通过这套封装包过程,发送到服务器端,服务器端则是一个拆包的过程,IP层是不可靠的,所以没有确认的机制,而在上层的TCP层则会对数据包的可靠性进行验证,丢失则会重传数据。保证传输的可靠性。服务器最终解包会拼接成一个完整的HTTP报文,完成整个数据的发送。

4.服务器解析,并返回

对HTTP报文进行解析,根据HTTP报文决定它请求了什么。将处理的结果组装成响应报文(如www.baidu.com , 请求报文为GET,要获取的是缺省值默认的index.html这个主页,则返回网页的源码,将网页源码添加到响应报文正文中),其中比较关键的是状态码(200OK表示成功没毛病),然后将响应报文,通过之前的过程返还给咱们的主机IP。

5.浏览器解析HTML

浏览器加载显示html的顺序是:从上到下,渲染的顺序也是从上到下,下载和渲染是同时进行的。如果遇到语义解释性的标签嵌入文件(JS脚本,CSS 下载过程会启用单独连接进行下载,并且在下载后进行解析,解析过程中,停止页面所有往下元素的下载(断点)。最终加载完成显示在浏览器上。

6.自定义View如何考虑机型适配

这里要考虑的是屏幕的问题:

合理使用warp_content,match_parent.
尽可能的是使用RelativeLayout
针对不同的机型,使用不同的布局文件放在对应的目录下,android会自动匹配。
尽量使用点9图片。
使用与密度无关的像素单位dp,sp
引入android的百分比布局。
切图的时候切大分辨率的图,应用到布局当中。在小分辨率的手机上也会有很好的显示效果

7.ActivityThread,AMS,WMS的工作原理

Activity与Window:
Activity只负责生命周期和事件处理

Window只控制视图
一个Activity包含一个Window,如果Activity没有Window,那就相当于Service

AMS与WMS:
AMS统一调度所有应用程序的Activity

WMS控制所有Window的显示与隐藏以及要显示的位置

8.SparseArray实现原理

SparseArray采用两个数组,用来存放key以及value值的,核心思想是通过折半查找来找到key对应的位置,然后取出值,或者插入值

9.SP(SharedPreferences)是进程同步的吗?有什么方法做到同步?

1,SharedPreferences不支持进程同步

一个进程的情况,经常采用SharePreference来做,但是SharePreference不支持多进程,它基于单个文件的,默认是没有考虑同步互斥,而且,APP对SP对象做了缓存,不好互斥同步。

MODE_MULTI_PROCESS的作用是什么?

在getSharedPreferences的时候,会强制让SP进行一次读取操作,从而保证数据是最新的,但是若频繁多进程进行读写, 若某个进程持有了一个外部sp对象, 那么不能保证数据是最新的,因为刚刚被别的进程更新了。

2,考虑用ContentProvider来实现SharedPreferences的进程同步

ContentProvider基于Binder,不存在进程间互斥问题,对于同步,也做了很好的封装,不需要开发者额外实现。

另外ContentProvider的每次操作都会重新getSP,保证了sp的一致性。

你可能感兴趣的:(Android 面试---Android基础知识点一)