基本上每次面试在这些面试中Android四大组件基本上必问,并且也会问一些细节性的问题,如果四大组件的问题不能对答如流,就让面试官感觉基础不太扎实,导致面试失败。
Android不仅是面试中很重要,在我们日常使用也很重要。
面试中经常问到四大组件分别是什么,其实就是问的四大组件的概念与作用。
一.activity生命周期面试题
1.activity生命周期都有哪些?每个生命周期都负责什么?
onCreate:不可见状态。第一次创建时调用,创建视图,
并且能传递该Activity的上一个状态的Bundle参数。
onStart:可见状态,可以显示Activity界面,但此时不能与用户交互。
onResume:可见状态,当前界面可以进行交互。
onPause:可见状态,此时activity正在停止,接下来会调用onStop。
在onPause中可以进行一些数据存储、动画停止、资源回收等。
onStop:不可见状态,当前activity停止或者被完全覆盖,当前activity不可见,运行在后台。
可以做一些资源释放的操作,不能做太耗时的操作。
onRestart:在activity重新启动时调用,由不可见状态变为可见状态。
一般打开一个新的Activity在返回之前的activity,旧的activity会调用该生命周期。
onDestory:activity销毁。一般可以做一些回收工作和最终资源释放。
2.activity各种场景下生命周期调用面试题
正常启动:onCreat->onStart->onResume
正常退出:onPause->onStop->onDestory
横竖屏切换:
①在Manifest.xml没有设置android:configChanges属性
启动:onCreat->onStart->onResume
切换横屏:onSavedInstance->onPause->onStop->onDestory->onCreate->
onStart->onRestoreInstanceState->onResume
从横屏切换成竖屏:onSavedInstance->onPause->onStop->onDestory->
onCreate->onStart->onRestoreInstanceState->onResume->
onSavedInstance->onPause->onStop->onDestory->
onCreate->onStart->onRestoreInstanceState->onResume(会重新创建两次)
②在Manifest.xml中设置了android:configChanges=“orientation”属性
启动:onCreate->onStart->onResume
切换横竖屏:onSavedInstanceState->onPause->onStop->onDestory->
onCreate->onStart->onRestoreInstanceState->onResume
在从横屏切换回竖屏:onSavedInsatnceState->onPause->onStop->onDestpry->
onCreate->onStart->onRestoreInstanceState->onResume
->onConfigurationChanged
③在Manifest.xml中设置android:configChanges="orientation|screenSize|keyboardHidden"
进行横屏切换:只会调用一次onConrigurationChanged
从横屏切换回竖屏:onConfigurationChanged->onConfigurationChanged
3.当ActivityA跳转ActivityB,在按下back返回
activirtA:onCreate->onStart->onResume->onPause
activityB:onCreate->onStart->onResume
activityA:onStop
当按下返回键
activityB:onPause
activityA:onRestart->onStart->onResume
activityB:onStop->onDestory
4.按下Home键
onCreate->onStart->onResume
按下home键:
onPause->onSaveInstanceState->onStop
(如果在任务栈中删除了任务会继续执行到onDestory)
在点击应用回到之前的界面:
onRestart->onStart->onResume
(如果你在按下home键之后将任务删除了,再次点开始会重新创建一次)
二、Activity启动模式
1.activity中有几种启动模式?分别有什么不同?
①standard:标准模式。
每次启动一个activity都会重新创建一个新的activity实例,不管这个activity实例是否创建过。
②singleTop:栈顶复用模式。
如果要创建的activity已经位于栈顶则不会重新创建,直接复用。如果当前activity已经创建但不在栈顶则会重新创建。
③singleTask:栈内复用模式。
只要activity实例在栈中存在,再次启动不会重新创建,会把该activity上面的activity实例弹出栈。否则会重新创建。
④singleInstance:单实例模式。
activity中在android系统中只有一个实例,如果使用该启动模式,会创建一个单独的任务栈,并且任务栈中只有一个activity实例。只有第一次的时候会创建,创建之后都是复用该实例。
2.activity各种启动模式的使用场景
①standard:默认启动模式,一般面试都不会问这个,没有什么太需要注意的地方。
②singleTop应用场景
当前的activity又会启动相同类型的activity。例如推送消息的展示页。
③singleTask应用场景
最常见的应用场景就是我们开启一个程序之后仅有一个activity实例。
例如应用的主页面,当用会从主页跳转到其他页面,跳转多次之后想返回主页面,
如果不使用该启动模式,在返回中会多次看到主页面,这样就感觉非常差。
④InstanceTask应用长场景
由于该启动模式会重新创建一个任务栈,所以一般适合启动与程序分离的页面。
例如跳转到拨打电话页面或者打开其他应用程序(打开地图App、分享等)
3.复用activity生命周期回调
一般我们在携带参数跳转时不能将启动模式设置为SingleTop或者SingleTask。
因为回复用原来的activity,在复用的时候不会再去执行onCreate,只有在第一次创建时才会调用onCreate。
此时会有一个onNewIntent方法,在activity实例被复用的时候都会执行该方法,
我们可以在该方法中会传入最新的intent,就可以解决上面的问题。
一般在该方法中都会重新setIntent并初始化数据等。
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
initData();
initView();
}
一、Service绑定方式
1.Service的两种绑定方式及其生命周期
①start方式:onCreate->onStartCommad->onDestory
②bind方式:onCreate->onBind->onUnbind->onDestory
通过bind方式开启服务会与调用者生命周期进行绑定,
并且能够与activity进行通信,调用者销毁service也会销毁。
用过start方式开启服务即便是调用者销毁service也不会被销毁,
与现有的activity分离,不能与activity进行通信。
③先bind在进行start
onCreate->onBind->onServiceConnected->onStartCommand->onUnbind->onDestory
④先start在bind
onCreate->onStartCommand->onBind->onServiceConnected->onUnbind->onDestory
2.Service执行在哪个线程,能否进行耗时操作?
Service一般默认都运行在主线程(除非指定Service的运行线程),
所以Service中不能进行耗时操作。
如果有特殊情况可以在清单文件中配置Service所在的线程
<service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote" >
</service>
3.如何保证Service不被杀死?
①设置优先级,通过在清单文件中intent-filter中通过android:priority=“1000”
来设置优先级,优先级越高越不容易被杀死。
②在onStartCommend中调用startForeground将service提升为前台进程,
最后记得在onStop中调用stopForeground。
③将Service设置为START_STICKLY,当service被杀死之后会重启,
重传intent,保持与之前一样。
④service被杀死之后进行拉活。例如双线程唤起,当一个线程被杀死之后,
另一个线程可以立即重启进程。或者依靠系统唤起。
4.重复调用startService或者bindService会重复执行生命周期吗?
①重复执行startService会重复执行onStartCommand,但是onCreate只执行一次。
①重复执行startService会重复执行onStartCommand,但是onCreate只执行一次。
②重复执行bindService所有生命周期不会重复执行,onBind和onCreate只执行一次。
提示:如果采用了混合启动(bing和start都调用了),在关闭Service至少调用一次unbindService和stopService。
5.在Service中onStartCommand中能否执行网络操作?如何在Service中进行网络操作(如何在service中进行网络操作)
首先说:可以在onStartCommand中进行网络操作。
如果要在网络请求中进行耗时操作可以选择IntentService,
IntentService是Service的子类,用来处理异步请求。
IntentService在onCreate中通过HandleThread单独开启一个线程来处理Intent请求
对象对应的任务,可以避免事务处理而阻塞线程。
onHandleIntent()方法针对不同的intent进行不同的事务处理即可,
执行完一个Intent请求对象的工作之后,如果没有新的intent请求到达,
则自动停止Service,否则会取出下一个intent请求处理任务。
6.Service中可以弹出Toast吗?
可以的,弹出toast就需要一个上下文对象context,而Service本身就是Context的子类,
因此在Service中弹出Toast是完全可以的。
1.什么是广播?那些场景都会用到广播呢?
①概念:广播在Android中就是广泛应用在程序之间传输消息的机制。
广播的内容就是一个intent,在intent中携带数据。
②应用场景:(1)同一个App中不同组件之间的消息通信。
(2)不同App组件之间传递消息。
2.Android中有哪几种广播?分别有什么区别?(这个问题其实问的挺多的,之前我也没太注意过)
①按照注册方式分为:静态广播和动态广播。
静态广播:在Manifest.xml中通过 进行注册的广播
动态广播:通过context.registerReceiver显示注册的广播
两者区别:
(1)静态广播在程序没有运行或者程序已经销毁了,仍然可以收广播。
动态广播是在程序中通过代码显示注册,因此必须在程序运行的时候才能收到广播。
(2)静态广播处理的时候每次都创建一个新的广播其接收对象,但动态广播一般都是一个广播接收器。
(3)针对一个无序广播,所有动态广播接收者都优先于所有的静态广播。
同一个应用内先注册的广播接收者先收到广播。
②从广播的发送方式来说:
普通广播(无序广播):通过context.sendBroadcast或者context.sendBroadcastAsUser
发送给当前系统中所有注册的接收者。
有序广播:接收者按照优先级处理广播,并且前面处理广播的接收者可以终止
广播的传递,一般通过context.sendOrderBroadcast或者context.sendOrderBroadcastAAsUser.
(有序广播可以中止广播也能修改数据,无序广播都不能)
粘性广播:可以发送给以后注册的广播接收者。系统会将之前发送的粘性广播
保存在AMS中,一旦注册了与已保存广播符合的接收者,注册完成之后
就会立刻收到广播。一般通过context.sendStickyBroadcast或者context.sendStickyOrderBroadcast。
1.在Android中为什么要使用ContentProvider?
①隐藏数据的实现方式,对外提供统一的数据访问接口。
②更好的数据访问权限管理。contentProvider可以对开发的数据进行权限设置,
不同的Uri对应不同的权限,只有符合权限要求的组件才能访问到ContentProvider的具体操作。
③封装了跨进程共享的逻辑,我们只需要使用Uri即可访问数据。
由系统管理ContentProvider的创建、生命周期及访问的线程分配。
我们只管通过ContentResolver访问ContentProvider所提示的数据接口,不需要关心他所在的线程是否启动。
2.运行在主线程的ContentProvider为什么不会影响主线程UI操作?
ContentProvider的onCreat是运行在主线程的,而query、insert、delete等等
一些操作是运行在线程池中的工作线程的。
所以调用这些方法并不会阻塞ContentProvider所在进程的主线程,但可能会阻塞调用者所在进程的UI线程。
所以调用ContentProvider操作仍然需要放在子线程去做。
虽然直接进行的增删改查操作直接是在工作线程进行的,但是系统会让你的调用线程
等待这个异步操作完成才能进行其他操作。
3.为什么要用ContentProvider,与sql实现上有什么区别?
①ContentProvider隐藏了数据存储的细节,内部实现对用户完全透明,用户只要关心
操作数据的Uri就可以,ContentProvider可以实现不同app之间数据共享。
②sql也能进行增删改查,但是这能对本程序下的数据进行操作,不能操作其他程序的数据。
③ContentProvider可以增删改查本地文件、xml文件的读取。
4.如何访问asserts中的数据库?
以前工程中由db文件,会存放在raw文件中 ,用户安装后将db文件复制到data/data/packagename/database下就能直接访问。
但现在只需要几行代码即可:
//初始化
AssetsDatabaseManager.initManager(context);
//数据库都需要获取管理对象
AssetsDatabaseManager assets=AssetsDatabaseManager.getManager();
//通过管理对象获取数据库
db=assets.getDatabase("address.db);
Android四大组件Activity、Service、Broadcast、ContentProvider是我们日常开发中最常见的,也是面试中几乎必问的点,由于我们开发中常用,但是我们确实对每个组件都不太了解,导致面试的时候基础性的问题回答不太好,导致面试失败,并且我们要形成自己的知识体系,问到一个组件就能想到一系列相关的问题并能够从问题不断攀升,所以说基础最重要!