Fork me on GitHub

Android面试点整理

结合网上的Android面试点博客和自身的面试经历,整理一下可能会问到的问题。

这里放上原博客。我这里只是整理一下自己参考后得出的适合自己的答案,不一定适合所有人。

Android的启动过程

切勿回答生命周期

1、Launcher通过Binder进程间通信机制通知ActivityManagerService,它要启动一个Activity

2、ActivityManagerService通过Binder进程间通信机制通知Launcher进入Paused状态

3、Launcher通过Binder进程间通信机制通知ActivityManagerService,它已经准备就绪进入Paused状态,于是ActivityManagerService就创建一个新的进程,用来启动一个ActivityThread实例,即将要启动的Activity就是在这个ActivityThread实例中运行

4、ActivityThread通过Binder进程间通信机制将一个ApplicationThread类型的Binder对象传递给ActivityManagerService,以便以后ActivityManagerService能够通过这个Binder对象和它进行通信

5、ActivityManagerService通过Binder进程间通信机制通知ActivityThread,现在一切准备就绪,它可以真正执行Activity的启动操作了

Android的生命周期

基本会考,不算难也不可以丢分的地方。先放上生命周期示意图。

其中需要注意的是:

  • onCreate()和onDestroy(),处于entire lifetime(完整生命周期)。

  • onStart()和onStop(),处于visible lifetime(可见生命周期)。

  • onResume()和onPause(),处于foreground lifetime(前台生命周期)。

除以上经常提到的生命周期方法之外,还有两个常用来在横竖屏切换时用到的方法:onSaveInstanceState()和onRestoreIntanceState()。

场景模式下方法调用顺序

我曾遇到的面试问题之一,然后只答了一个场景,感觉自己被Q死了。。。。

测试环境:红米手机

  • activity首次启动

onCreate()->onStart()->onResume()

  • 按返回键返回至桌面

onPause()->onStop()->onDestroy()

桌面再点击进入的话,就会是:onCreate()->onStart()->onResume()

  • 按home键返回至桌面

onPause()->onStop()

  • 再点击应用启动activity

onRestart()->onStart()->onResume()

  • 锁屏关闭再启动

onPause()->onStop()->onRestart()->onStart()->onResume()

Android的启动模式和使用场景

Android共有四种启动模式:

  • standard
  • singleTop
  • singleTask
  • SingleInstance

既然提到了启动模式,就要先提一下Android的任务栈。在应用打开的时候,同时会创建一个任务栈,用于存储当前程序的所有activity实例,它包含了一个activity的集合。在任务栈中,只有位于栈顶的activity才可以与用户进行交互。在程序运行的过程中,任务栈会保留每一个activity的状态及信息,有序的列出它们各自的任务。在退出应用时,所有的activity会被清除出栈,任务栈被销毁。

不过这样的设计也有缺点。每开启一个新的页面,都会在任务栈中添加一个新的activity,可能会因为数据重复太多造成数据冗余,导致内存溢出(OOM);且用户应用操作深度太深的话,用户需要多次点击返回,才能将任务栈中所有activity清除出栈并销毁任务栈,这样就会使用户体验较差。

出于解决以上问题的原因,Android引入了启动模式。启动模式将决定activity跳转的过程中activity实例的生成及限制条件

standard模式

在每次跳转activity的时候,无论是否已经存在该activity的实例,系统都会在task中生成一个新的activity实例,并且放在任务栈的顶部。按下后退键,可以返回原来的activity实例。

singleTop模式

在每次跳转activity的时候,会检测一下当前任务栈栈顶是否已经存在该activity实例。如果存在,则重复利用;如果不存在,则生成新的实例。

singleTask模式

这个地方就要考虑到activity实例的入栈与出栈了。比如说,现有活动A与B,A已设置为singleTask模式。启动页面活动A,A跳转至B,B在跳转至A,A再跳转至B。在这个过程中,A页面的存在是唯一的,而B不是唯一的。这个结果与任务栈的设计有关。第一步,入栈A。第二步,入栈B。第三步,B出栈,A自动至栈顶。第四步,入栈新的B。最主要的步骤在于第三步。singleTask模式中,先检测栈中是否存在实例:如果存在,则将其之上的实例全部出栈;如果不存在,则生成新的实例。

与singleTop的不同是,前者只检查栈顶,后者检查全栈

singleInstance模式

这个模式会将跳转的新页面放入一个新的栈结构。这里要有一个例子要讲一下。

场景:A活动是standard模式,B活动是singleInsane模式。

1、A启动B,B点击返回退回A,A点击返回退出程序。

2、A启动B,B启动A(此时生成了一个新的A实例)。A点击两次返回才退回至B。B点击返回,退出程序。

这其中的主要差距在于,第二个场景中,B启动A,此时B所在的栈成为起点,A点击返回,退回的起点必须是B所在栈,然后才能推出程序。

总结

singleTop适合接收通知启动的内容显示页面。比如QQ的后台消息弹窗,在未启用QQ时,可以重复利用栈顶的消息弹窗,减少内存使用。

singleTask适合作为程序入口点,或者说重用率比较高的主界面。比如浏览器的主界面,不管怎么从别的应用启动,主界面是一定要启动的。

singleInstance适合需要与程序分离的界面,例如闹钟提醒。切忌将singleInstance页面作为中转页面。

Service的两种启动方式

startService

采用start的方法开启服务,步骤:

1、定义一个继承自service的类

2、在Mainfest.xml中配置service

3、使用context的startService(Intent)方法启动该service

4、不再使用时,使用stopService(Intent)方法停止该服务

这种启动方式下,service的生命周期如下:

onCreate()->onStartCommand()->onDestory()

一个service在它的生命周期内只会调用一次onCreate()和onDestory()方法,在之后的所有startService()方法调用后,都只会调用onStartCommand()方法。

特点:一旦服务开启,跟开启环境就没有任何关系了。且,开启环境内不能调用服务里面的方法。

bindService

采用bind的方法开启服务,步骤:

1、定义一个继承自service的类

2、在Mainfest.xml中配置service

3、使用context的bindService(Intent,ServiceConnection,int)方法启动该service

4、不再使用时,调用unbindService(ServiceConnection)方法停止该service

生命周期:

onCreate()->onBind()->onunbind()->onDestory()

注意:绑定服务不调用onstartCommand()方法

特点:bind的方法开启服务,服务的生命周期会与调用者的生命周期一致。绑定者可以调用服务里面的方法。

Broadcast的两种注册及发送方式

注册

动态注册

代码中的动态注册步骤如下:

1、实例化自定义的广播接收器

2、实例化意图过滤器,并设置要过滤的广播类型(如接受短信系统的广播)

3、使用context的registerReceiver(BroadcasrReceiver,IntentFilter,String,Handler)方法注册广播

静态注册

直接在Manifest.xml文件中的节点中配置广播接收器,like this:

<receiver android:name=".MyBroadCastReceiver">  
            <!-- android:priority属性是设置此接收者的优先级(从-1000到1000) -->
            <intent-filter android:priority="20">
            <actionandroid:name="android.provider.Telephony.SMS_RECEIVED"/>  
            </intent-filter>  
</receiver>

不同:

1、第一种不是常驻型广播,也就是说广播跟随程序的生命周期

2、第二种是常驻型,也就是说即使应用程序被关闭,如果有信息广播来,程序也会被系统调用自动运行

发送广播

广播的发送有无序广播和有序广播两种。

无序广播的使用:通过conetxt.sendBroadcast(Intent)或context.sendBroadcast(Intent,String)发送

有序广播的使用:通过context.sendOrderedBroadcast(Intent,String,BroadcastReceiver,Handler,int,String,Bundle)发送

区别:

无序广播:所有的接受者都会接收事件,不可以被拦截,不可以被修改

有序广播:按照优先级,一级一级向下传递,可以终止,也可以修改广播内容数据

HttpClient,HttpURLConnection

http与https

HTTPS(基于安全套接字层的超文本传输协议或者是HTTP over SSL)是Netscape开发的一个Web协议。

可以说:HTTPS=HTTP+SSL。

SSL,全称Secure Socket Layer,为Netscape所研发,利用数据加密技术,确保数据在网络传输过程中不会被截取及窃听。

相同点:

大多数情况下,两者相同,因为采用了同一个基础的协议。在客户端或浏览器,建一个连接到web服务器指定的端口。当服务器收到请求,返回状态码及消息。系统使用统一资源定位器URI模式,因为资源可以被唯一指定。

不同点:

1、URL开头不同,http以http://开头,https以https://开头

2、前者不加密,不安全;后者对传输数据加密,安全

3、前者标准端口是80,后者标准端口是443

4、前者无需证书,后者需要认证证书

5、在OSI网络模型中,http工作于应用层,https工作在传输层

PS:OSI网络模型,即常说的TCP/IP模型

七层从上往下依次分别为:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层。详细如下图:

手写排序算法

这部分的话,主要就是对算法进行一个回顾。(冒泡选择插入要会写,其他的掌握思想)

-------------本文结束感谢您的阅读-------------