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 数量)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,165评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,720评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,849评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,245评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,596评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,747评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,977评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,708评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,448评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,657评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,141评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,493评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,153评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,890评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,799评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,685评论 2 272

推荐阅读更多精彩内容