Android基础-Activity

Google Doc: https://developer.android.google.cn/guide/components/activities/

一、Activity生命周期

Activity生命周期.jpg
  • 当Activity启动时,依次会调用onCreate、onStart、onResume。
  • 当Activity退居后台时(不可见,点击Home或者被新的Activity完全覆盖),onPause、onStop会依次被调用。
  • 当Activity重新回到前台(从桌面回到原Activity或者被覆盖后又回到原Activity)时,onRestart、onStart、onResume会依次被调用。
  • 当Activity退出销毁时(点击back键),onPause、onStop、onDestroy会依次被调用。
  • 退出当前Activity时–>onPause()–>onStop()–>onDestroy()依次被调用。

当一个 Activity 启动另一个 Activity 时,第一个 Activity 暂停并停止(但如果它在后台仍然可见,则不会停止)时,同时系统会创建另一个 Activity,在创建第二个 Activity 前,第一个 Activity 不会完全停止。更确切地说,启动第二个 Activity 的过程与停止第一个 Activity 的过程存在重叠。

当 Activity A 启动 Activity B 时:

  1. Activity A 的 onPause() 方法执行。
  2. Activity B 的 onCreate()onStart()onResume() 方法依次执行。(Activity B 现在具有用户焦点。)
  3. 然后,如果 Activity A 在屏幕上不再可见,则其 onStop() 方法执行。

此时在Activity B中按下Back键,则:

  1. B.onPause()->A.onRestart->A.onStart->A.onResume-> B.onStop->B.onDestroy。

二、Activity异常生命周期

1 相关系统配置改变导致Activity被杀死并重新创建(一般指横竖屏切换)

  • 竖屏调整为横屏,则onPause,onSaveInstanceState,onStop,onDestroy,onCreate,onStart,onRestoreInstanceState,onResume依次被调用;
  • onSaveInstanceState和onRestoreInstanceState只有在Activity异常终止时才会被调用的,正常情况是不会调用这两个方法的;
  • 在onSaveInstanceState方法和onRestoreInstanceState方法中,系统会自动帮我们恢复一定的数据,如当前Activity的视图结构、文本框的数据、ListView的滚动位置等,这些View相关的状态系统都会帮我们恢复,因为每个View也有onSaveInstanceState方法和onRestoreInstanceState方法
Activity restore_instance.png

2 内存不足导致低优先级的Activity被杀死

当系统内存不足的时候,系统就会按照一定的优先级去杀死目标Acitivity的进程来回收内存,并且此时Activity的onSaveInstanceState方法会被调用来存储数据,并在后续Activity恢复时调用onRestoreInstanceState方法来恢复数据


三、Activity销毁重建

当系统配置发生变化后,Activity会被重建。

如果不想Activity在屏幕旋转后导致销毁重建时,可以设置configChange=“orientation”;当SDK版本大于13时,还需额外添加一个“screenSize”的值。
设置了这两个参数后,当横竖屏切换时,Activity不会再重建并且也不会调用onSaveInstanceState方法和onRestoreInstanceState方法,而是会回调onConfigurationChanged方法。


四、Activity通信

  1. 通过将数据封装在Bundle对象中 ,然后在Intent跳转的时候携带Bundle对象
    该方法可以传递基本数据类型和String类型的数据,如果传递的是对象就需要进行序列化。

  2. 类静态变量
    通过public static定义Activity的静态变量然后在其他Activity使用类名.变量名传递。

  3. Application
    通过在Application 中的全局静态变量来实现。

  4. EventBus
    当传输的数据量较大的时候Parcelable虽然很便捷,但是会出现异常TransactionTooLargeException。此时可以用插件EventBus。

EventBus 使用的是发布-订阅者模型,发布者通过EventBus发布事件,订阅者通过EventBus订阅事件。当发布者发布事件时,订阅该事件的订阅者的事件处理方法将被调用。


五、Activity启动模式

Activity启动模式分四种:Standard 标准模式,SingleTop 栈顶复用模式、SingleTask 栈内复用模式、SingleInstance 单实例模式。

1 Standard 标准模式

每次启动一个Activity,都会又一次创建一个新的实例入栈,无论这个实例是否存在。

生命周期:

每次被创建的实例Activity的生命周期符合典型情况,它的onCreate、onStart、onResume都会被调用。

举例:

Activity栈中已有A、B、C三个Activity,C处于栈顶。若从C Acticity跳转到另一个C Activity,结果是新建一个C Activity入栈,成为栈顶。

Activity启动模式-Standard.png

2 SingleTop 栈顶复用模式

  • 情况1:若需要创建的Activity已处于栈顶,此时会直接复用栈顶的Activity,不会再创建新的Activity;
  • 情况2:若需要创建的Activity不处于栈顶,此时会又一次新建一个新Activity入栈,同Standard模式。
生命周期:

情况1下,栈顶Activity直接被复用,它的onCreate、onStart不会被调用,因为它并没有发生改变,但onNewIntent会被调用(Activity被正常创建时不会回调此方法)。

举例:

Activity栈中已有A、B、C三个Activity,C处于栈顶。情况一:从C跳转到另一个C,结果是直接复用栈顶的C,不再新建;情况二:从C跳转到A,结果是新建一个A入栈,成为栈顶。

Activity启动模式-SingleTop.png
使用场景:

假设在当前的Activity中要启动同类型的Activity,此时建议将该Activity指定为SingleTop模式,能够降低Activity的创建,节省内存。

3 SingleTask 栈内复用模式

若需要创建的Activity已处于栈中,不会再新建Activity,而是将存在栈中的Activity上面的其他所有Activity销毁,使它成为栈顶。

生命周期:

同SingleTop情况一同样,仅会回调Activity的onNewIntent方法。

举例:

Activity栈中已有A、B、C三个Activity,C处于栈顶。情况一:从C跳转到C,则直接复用栈顶的C;情况二:从C跳转到A,则将A上面的B、C销毁,使A成为栈顶。

Activity启动模式-SingleTask.png
使用场景:

最常见的应用场景就是保持应用开启后仅仅有一个Activity的实例。
比如:应用中展示的主页,假设用户在主页跳转到其他页面,多次操作后想返回到主页,假设不使用SingleTask模式,在点击返回的过程中会多次看到主页,不合理。

4 SingleInstance 单实例模式

全局单例模式,加强的SingleTask。具有此模式的Activity仅仅能单独位于一个任务栈中。经常适用于系统中的应用,比如Launch、锁屏键的应用等,整个系统中仅有一个。

举例:

A Activity是该模式,启动A后,系统会为它创建一个单独的任务栈,由于栈内复用的特性,新的请求均不会创建新的Activity,除非这个独特的任务栈被系统销毁。

六、使用方式

使用方法有两种:

  1. AndroidManifest.xml中为Activity指定launchMode。
  2. 动态指定,通过Intent的addFlags方法动态指定启动模式。
优先级:

第2种比第1种优先级高,若两者同时存在,以2为准

限定范围:

第1种无法为Activity直接指定FLAG_ACTIVITY_CLEAR_TOP标识;
第2种无法为Activity指定SingleInstance模式。

注意:须考虑Activity跳转时携带页面参数的问题

当一个Activity设置了SingleTop或者SingleTask模式后,跳转此Activity出现复用原有Activity的情况时,此Activity的onCreate方法将不会再调用。onCreate方法仅会在第一次创建Activity时被调用。
而一般onCreate方法中会进行该页面的数据初始化、UI初始化,假设页面的展示数据无关页面跳转传递的參数,则不必操心此问题;若页面展示的数据就是通过getIntent() 方法来获取,那么问题就会出现:getIntent()获取的一直都是老数据,根本无法接收跳转时传送的新数据!
这时我们需要另外一个回调 onNewIntent(Intent intent)方法。此方法会传入最新的intent,这样我们就能够解决上述问题。这里建议的方法是再次调用setIntent。然后重新初始化数据和UI。

七、相关Flags

1 FLAG_ACTIVITY_NEW_TASK

为Activity指定SingleTask启动模式,与AndroidManifest.xml指定效果相同。

2 FLAG_ACTIVITY_SINGLE_TOP

为Activity指定SingleTop启动模式,与AndroidManifest.xml指定效果相同。

3 FLAG_ACTIVITY_CLEAN_TOP

具有此标记的Activity,启动时会将与其同栈的其他Activity出栈。一般与SingleTask启动模式一起出现。它会完毕SingleTask的作用,但事实上SingleTask启动模式默认具有此标记的作用。

4 FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

具有此标记的Activity不会出现在Activity列表中。
使用场景:某些情况下不希望用户通过历史列表回到某个Activity时,此标记便可以实现该效果。
等同于AndroidManifest.xml中指定Activity属性:android:excludeFromRecents="true"


八、监听Activity生命周期

在Application中调用 registerActivityLifecycleCallbacks(),通过 ActivityLifecycleCallbacks 接口的实现,完成对Activity各个生命周期信息的采集。
比如哪个Activity在什么时间处于onCreate、onStop等等,进而统计出Activity的使用时间和使用次数。

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