Android四大组件(面试篇)

基本上每次面试在这些面试中Android四大组件基本上必问,并且也会问一些细节性的问题,如果四大组件的问题不能对答如流,就让面试官感觉基础不太扎实,导致面试失败。
Android不仅是面试中很重要,在我们日常使用也很重要。

四大组件概念

面试中经常问到四大组件分别是什么,其实就是问的四大组件的概念与作用。

  1. Activity
    activity通常就代表手机中屏幕中能够与用户交互的一些界面,一个Activity可以称为一个屏幕,并且在我们日常开发中使用Activity最多。
  2. Server
    server是没有界面、生命周期比较长的程序,一般用来监控类的程序。
  3. ContentProvider
    内容提供者,用于数据共享,让一个应用程序指定数据集提供给其他应用程序。
  4. Broadcast
    广播,主要应用在程序之间传输信息的机制

Activity

一.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

一、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是完全可以的。

Broadcast

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。

ContentProvider

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是我们日常开发中最常见的,也是面试中几乎必问的点,由于我们开发中常用,但是我们确实对每个组件都不太了解,导致面试的时候基础性的问题回答不太好,导致面试失败,并且我们要形成自己的知识体系,问到一个组件就能想到一系列相关的问题并能够从问题不断攀升,所以说基础最重要

你可能感兴趣的:(Android,面试)