Android面试题-四大组件

在 Activity 的生命周期中,可以将 Activity 表现为 3 种状态

  • 激活态:当 Acitivity 位于屏幕前端,并可以获得用户焦点、接收用户输入时,这种状态称为激活态,也可以称为运行态;
  • 暂停态:当 Activity 在运行时被另一个 Activity 所遮挡,但此时 Activity 仍然可见,也就是说另一个 Activity 是部分遮挡的,或者另一个 Activity 是透明的或半透明的,此时Activity 处于暂停状态;
  • 停止态:当 Activity 被另一个 Activity 完全遮挡不可见时处于停止状态,这个 Activity 仍然存在,它保留在内存中并保持所有状态和成员信息,但是当该设备内存不足时,该 Activity 可能会被系统杀掉以释放其占用的内存空间,当再次打开该 Activity 时,它会被重新创建;

Activity 生命周期中的 7 个方法

  1. onCreate():当 Activity 被创建时调用;
  2. onStart():当 Activity 被创建后即将可见时调用;
  3. onResume():(继续开始)当 Activity 位于设备最前端,对用户可见时调用;
  4. onPause():(暂停)当另一个 Activity 遮挡当前 Activity,当前 Activity 被切换到后台时调用;
  5. onRestart():(重新启动)当另一个 Activity 执行完 onStop()方法,又被用户打开时调用;
  6. onStop():如果另一个 Activity 完全遮挡了当前 Activity 时,该方法被调用;
  7. onDestory():当 Activity 被销毁时调用;

Activity 的四种启动模式及使用场景

Standard、SingleTop、SingleTask 和 SingleInstance,他们是在配置文件中通过 android:launchMode 属性配置;

  1. Standard:默认的启动模式,每次启动会在任务栈中新建一个启动的 Activity 的实例;
  2. SingleTop:如果要启动的 Activity 实例已位于栈顶,则不会重新创建该 Activity 的实例,否则会产生一个新的运行实例;
  3. SingleTask:如果栈中有该 Activity 实例,则直接启动,中间的 Activity 实例将会被关闭,关闭的顺序与启动的顺序相同;
  4. SingleInstance:该启动模式会在启动一个 Activity 时,启动一个新的任务栈,将该 Activity实例放置在这个任务栈中,并且该任务栈中不会再保存其他的 Activity 实例;

Activity 任务栈

即存放 Activity 任务的栈,每打开一个 Activity 时就会往 Activity 栈中压入一个 Activity 任务,每当销毁一个 Activity 的时候,就会从 Activity 任务栈中弹出一个 Activity 任务,由于安卓手机的限制,只能从手机屏幕获取当前一个 Activity 的焦点,即栈顶元素(最上面的 Activity),其余的 Activity 会暂居后台等待系统的调用;
关于任务栈的更多概念:当App打开时就创建了一个任务栈,用于存储当前App的 Activity,当前App(包括被当前App所调用的)所有的 Activity 都属于一个任务栈;一个任务栈包含了一个 Activity 的集合,可以有序的选择哪个 Activity 和用户进行交互,只有任务栈顶的Activity 才可以与用户进行交互;任务栈可以移动到后台,并保留每一个 Activity 的状态,并且有序的给用户列出他们的任务,而且还不会丢失他们的状态信息;退出应用程序时,当把所有的任务栈中所有的 Activity 清除出栈时,任务栈会被销毁,程序退出;

Fragment

Android3.0 引入 Fragment 技术,译为“碎片”,在 Activity 中可以通过 FragmentManager来添加、移除和管理所加入的 Fragment,每个 Fragment 都有自己的布局、生命周期、交互事件的处理,由于Fragment 是嵌入到 Activity 中的,所以 Fragment 的生命周期又和 Activity的生命周期有密切的关联。

Fragment 的生命周期的方法

1.onAttach():当 Fagment 和 Activity 产生关联时被调用;
2.onCreate():当 Fragment 被创建时调用;
3.onCreateView():创建并返回与 Fragment 相关的 view 界面;
4.onViewCreate():在 onCreateView()执行完后立即执行;
5.onActivityCreated():通知 Fragment,他所关联的 Activity 已经完成了 onCreate()的调用;
6.onStart():让 Fragment 准备可以被用户所见,该方法和 Activity 的 onStart()方法相关联;
7.onResume():Fragment 可见,可以和用户交互,该方法和 Activity 的 onResume()方法相关联;
8.onPause():当用户离开 Fragment 时调用该方法,此操作是由于所在的 Activity 被遮挡或者是在 Activity 中的另一个 Fragment 操作所引起的;
9.onStop():对用户而言,Fragment 不可见时调用该方法,此操作是由于他所在的 Activity不再可见或者是在 Activity 中的一个 Fragment 操作所引起的;
10.onDestroyView():ment 清理和它的 view 相关的资源;
11.onDestroy(): 最终清理 Fragment 的状态;
12.onDetach():Fragment 与 Activity 不再产生关联;
Fragment 加载布局 文件是在 onCreateView()方法中使 用 LayoutInflater( 布局加载 器)的
inflate( )方法加载布局文件。

管理 Fragment

通过调用 Context 的 getFragmentManager()方法或者 getSupportFragmentManager()方法(这
两个方法需要导入的包不同)来获取 FragmentManager,使用 FragmentManager 对象,主要
可以调用如下方法:
findFragmentById()/findFragmentByTag():获取 Activity 中已经存在的 Fragment;
getFragments():获取所有加入 Activity 中的 Fragment;
begainTransaction():获取一个 FragmentTransaction 对象,用来执行 Fragment 的事物;
popBackStack():从 Activity 的后退栈中弹出 Fragment;
addOnBackChagedListerner:注册一个侦听器以监视后退栈的变化;

FragmentTransaction

在 Activity 中对 Fragment 进行添加、删除、替换以及执行其他的动作将引起 Fragment 的变化,叫做一个事务,事务是通过 FragmentTransaction 来执行的,可以用 add()、remove()、replace()、show()、hide()等方法构成事务,最后使 commit()提交事务,参考代码 :
getSupportFragmentManager().beginTransaction().add(R.id.main_container, t Fragment).add(R.i
d.main_container, e Fragment).hide(e Fragment).commit();其中 R.id.main_container 为布局中容纳 Fragment 的 view 的 ID。

保存 Activity 状态

onSaveInstanceState(Bundle)会在 Activity 转入后台状态之前被调用,也就是 onStop()方法之前,onPause()方法之后被调用

Fragment 与 Fragment、Activity 通信的方式

1.EventBus
2.使用接口
3.Fragment 直接调用 Activity 中的 public 方法

Android四大组件

  • Activity:用户可操作的可视化界面,为用户提供一个完成操作指令的窗口。一个 Activity 通常是一个单独的屏幕,Activity 通过 Intent 来进行通信。Android 中会维持一个 Activity Stack,当一个新 Activity 创建时,它就会放到栈顶,这个 Activity 就处于运行状态。
  • Service:服务,运行在手机后台,适合执行不需和用户交互且还需长期运行的任务。
  • ContentProvider:内容提供者,使一个应用程序的指定数据集提供给其他应用程序,其他应用可通过 ContentResolver 类从该内容提供者中获取或存入数据。它提供了一种跨进程数据共享的方式,当数据被修改后,ContentResolver 接口的 notifyChange 函数通知那些注册监控特定 URI 的 ContentObserver 对象。如果 ContentProvider 和调用者在同一进程中,ContentProvider 的方法(query/insert/update/delete 等)和调用者在同一线程中;如果 ContentProvider和调用者不在同一进程,ContentProvider 方法会运行在它自身进程的一个 Binder 线程中。
  • BroadcastReceiver:广播接收者,运用在应用程序间传输信息,可以使用广播接收器来让应用对一个外部事件做出响应。

Activity 之间的通信方式

1.通过 Intent 方式传递参数跳转
2.借助类的静态变量或全局变量
3.借助 SharedPreference 或是外部存储,如数据库或本地文件
4.EventBus(普通事件或粘性事件)

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

  1. 切换横屏时:onSaveInstanceState -> onPause -> onStop -> onDestory -> onCreate -> o
    nStart -> onRestoreInstanceState -> onResume
  2. 切换竖屏时:会打印两次相同的 log,onSaveInstanceState -> onPause -> onStop -> onD
    estory -> onCreate -> onStart -> onRestoreInstanceState -> onResume -> onSaveInstanceSt
    ate -> onPause -> onStop -> onDestory -> onCreate -> onStart -> onRestoreInstanceState
    -> onResume
  3. 如果在 AndroidMainfest.xml 中修改该 Activity 的属性,添加 android:configChanges="orient
    ation"横竖屏切换,打印的 log 一样同 1)
  4. 如果 AndroidMainfest.xml 中该 Activity 中的 android:configChanges="orientation|keyboardH
    idden",则只会打印 onConfigurationChanged

Activity 状态保存于恢复

Activity 被主动回收时,如按下 Back 键,系统不会保存它的状态,只有被动回收时。虽然这个 Activity 实例已被销毁,但系统在新建一个 Activity 实例时,会带上先前被回收 Activity的信息。在当前 Activiy 被销毁前调用 onSaveInstanceState(onPause 和 onStop 之间保存),重新创建 Activity 后会在 onCreate 后调用 onRestoreInstanceState(onStar 和 onResume)之间被调用),它们的参数 Bundle 用来数据保存和读取的。保存 View 状态有两个前提:View 的子类必须实现了 onSaveInstanceState; 必须要设定 Id,这个 ID 作为 Bundle 的 Key

IntentService 原理及作用是什么

IntentService 是继承 Service 的一个抽象类,它在 onCreate()方法中创建了一个 HandlerThread,并启动该线程。HandlerThread 是带有自己消息队列和 Looper 的线程,根据 HandlerThread的 looper 创建一个 Handler,这样 IntentService 的 ServiceHandler 的 handleMessage()方法就运行在子线程中。handleMessage 中调用了 onHandleIntent()方法,它是一个抽象方法,继承IntentService 类需要实现该方法,把耗时操作放在 onHandleIntent()方法中,等耗时操作运行完成后,会调用 stopSelf()方法,服务会调用 onDestory()方法消毁自己。如果 onHandleIntent()中的耗时操作未运行完前就调用了 stopSelf()方法,服务调用 onDestory()方法,但耗时操作会继续运行,直至运行完毕。如果同时多次启动 IntentService,任务会放在一个队列中,onCreate()和 onDestory()方法都只会运行一次。作用:用来处理后台耗时操作,如读取数据
库或是本地文件等。

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

  • ContentProvider 实现各个应用程序间数据共享,用来提供内容给别的应用操作。如联系人应用中就使用了 ContentProvider,可以在自己应用中读取和修改联系人信息,不过需要获取相应的权限。它也只是一个中间件,真正的数据源是文件或 SQLite 等。
  • ContentResolver 内容解析者,用于获取内容提供者提供的数据,通过 ContentResolver.notifyChange(uri)发出消息。
  • ContentObserver 内容监听者,可以监听数据的改变状态,观察特定 Uri 引起的数据库变化,继而做一些相应的处理,类似于数据库中的触发器,当 ContentObserver 所观察的 Uri 发生变化时,便会触发它。

BroadcastReceiver(广播)的分类

  1. 普通广播:完全异步的,可以在同一时刻(逻辑上)被所有接收者接收到,消息传递的效率比较高,并且无法中断广播的传播。
  2. 有序广播:发送有序广播后,广播接收者将按预先声明的优先级依次接收 Broadcast。优先级高的优先接收到广播,而在其 onReceiver()执行过程中,广播不会传播到下一个接收者,此时当前的广播接收者可以 abortBroadcast()来终止广播继续向下传播,也可以将 intent中的数据进行修改设置,然后将其传播到下一个广播接收者。sendOrderedBroadcast(intent, null);//发送有序广播
  3. 粘性广播:sendStickyBroadcast()来发送该类型的广播信息,这种广播的最大特点是,当粘性广播发送后,最后的一个粘性广播会滞留在操作系统中。如果在粘性广播发送后的一段时间里,如果有新的符合广播的动态注册的广播接收者注册,将会收到这个广播消息,虽然这个广播是在广播接收者注册之前发送的,另外一点,对于静态注册的广播接收者来说,这个等同于普通广播。

本地广播和全局广播有什么差别

  1. LocalBroadcastReceiver 仅在自己的应用内发送接收广播,也就是只有自己的应用能收到,数据更加安全。广播只在这个程序里,而且效率更高。只能动态注册,在发送和注册的时候采用 LocalBroadcastManager 的 sendBroadcast 方法和 registerReceiver 方法。
  2. 全局广播:发送的广播事件可被其他应用程序获取,也能响应其他应用程序发送的广播事件(可以通过 exported–是否监听其他应用程序发送的广播在清单文件中控制)全局广播既可以动态注册,也可以静态注册。

Dialog、PopupWindow 区别

  1. PopupWindow 在显示之前一定要设置宽高,Dialog 无此限制;
  2. PopupWindow 默认不会响应物理键盘的 back,除非显示设置了 popup.setFocusable(true);而在点击 back 的时候,Dialog 会消失;
  3. PopupWindow 不会给页面其他的部分添加蒙层,而 Dialog 会;
  4. PopupWindow 没有标题,Dialog 默认有标题,可以通过 dialog.requestWindowFeature(Wi
    ndow.FEATURE_NO_TITLE);取消标题;
  5. 二者显示的时候都要设置 Gravity。如果不设置,Dialog 默认是 Gravity.CENTER;
  6. 二者都有默认的背景,都可以通过 setBackgroundDrawable(new ColorDrawable(android.R.
    color.transparent));去掉;
  7. PopupWindow 弹出后,取得了用户操作的响应处理权限,使得其他 UI 控件不被触发。而AlertDialog 弹出后,点击背景,AlertDialog 会消失;

Application 和 Activity 的 Context 对象的区别

一个应用 Context 的数量 = Activity 数量 + Service 数量 + 1(Application 数量)

你可能感兴趣的:(Android面试题-四大组件)