android体系复习---Activity

一、什么是Activity

Activity是与用户交互的入口点。它表示拥有界面的单个屏幕。例如,电子邮件应用可能有一个显示新电子邮件列表的 Activity、一个用于撰写电子邮件的 Activity 以及一个用于阅读电子邮件的 Activity。尽管这些 Activity 通过协作在电子邮件应用中形成一种紧密结合的用户体验,但每个 Activity 都独立于其他 Activity 而存在。因此,其他应用可以启动其中任何一个 Activity(如果电子邮件应用允许)。例如,相机应用可以启动电子邮件应用内用于撰写新电子邮件的 Activity,以便用户共享图片。

二、 生命周期

image

OnCreate:您必须实现此回调,它会在系统首次创建 Activity 时触发。Activity 会在创建后进入“已创建”状态。在 onCreate()方法中,您需执行基本应用启动逻辑,该逻辑在 Activity 的整个生命周期中只应发生一次。

onStart: 当 Activity 进入“已开始”状态时,系统会调用此回调。onStart()调用使 Activity 对用户可见,因为应用会为 Activity 进入前台并支持互动做准备。例如,应用通过此方法来初始化维护界面的代码。

onResume: Activity 会在进入“已恢复”状态时来到前台,然后系统调用 onResume回调。这是应用与用户互动的状态。应用会一直保持这种状态,直到某些事件发生,让焦点远离应用。此类事件包括接到来电、用户导航到另一个 Activity,或设备屏幕关闭。

onPause: 系统将此方法视为用户将要离开您的 Activity 的第一个标志(尽管这并不总是意味着 Activity 会被销毁);此方法表示 Activity 不再位于前台(尽管在用户处于多窗口模式时 Activity 仍然可见)。

onStop: 如果您的 Activity 不再对用户可见,说明其已进入“已停止”状态,因此系统将调用 onStop() 回调

onDestory: Activity即将被销毁,可以做一些工作和资源的回收(Service、BroadCastReceiver、Map、Bitmap回收等)

onRestart: Activity正在重新启动,一般时当前Activity从不可见到可见状态时会执行这个方法,例如:用户按下Home键(锁屏)或者打开新Activity再返回这个Activity

状态保持相关生命周期

onSaveInstanceState: onSaveInstanceState方法在Activity可能被销毁之前执行,保存状态信息,异常销毁后可以利用这些信息进行恢复。【这里的可能被销毁的操作比如,按下home键,或者打开一个新的Activity,都会被执行,因为这些操作如果放置时间过长,则之前的Activity则有可能被销毁。另外屏幕切换时也会调用该方法】

onRestoreInstanceState: 只有在activity确实是被系统回收,重新创建activity的情况下才会被调用,此时参数savedInstanceState一定不为null,在onStart方法之后执行

配置改变触发的生命周期

onConfigurationChanged: 当在清单文件中配置了configChanges时,如果设备发生一些配置变化,则会触发改变。
常见的配置改变:

  • orientation:方向变化
  • screenSize:屏幕尺寸变化
  • keyboardHidden:键盘隐藏
生命周期相关面试题:
  1. A Activity 打开 B Activity 时都有哪些生命周期回调?
    A.onPause -> B.onCreate ->B.onStart -> B.onResume -> A.onStop
  2. 界面旋转的生命周期
    onPause -> onStop -> onSaveInstanceState -> onDestroy -> onCreate ->onStart -> onRestoreInstanceState -> onResume

三、 启动模式

启动默认分四种,我们在清单文件中设置launchMode属性配置即可,具体默认如下:

Standard模式: Android的默认启动模式,你不在配置文件中做任何设置,那么这个Activity就是standard模式,这种模式下,Activity可以有多个实例,每次启动Activity,无论任务栈中是否已经有这个Activity的实例,系统都会创建一个新的Activity实例

singleTop: 栈顶复用模式,如果要开启的activity在任务栈的顶部已经存在,就不会创建新的实例,而是调用 onNewIntent() 方法;
应用场景:在通知栏点击收到的通知,然后需要启动一个Activity,这个Activity就可以用singleTop,否则每次点击都会新建一个Activity

singleTask: 栈内复用模式,activity只会在任务栈里面存在一个实例。如果要激活的activity,在任务栈里面已经存在,就不会创建新的activity,而是复用这个已经存在的activity,调用 onNewIntent()方法,并且清空这个activity任务栈上面所有的activity。
应用场景:应用场景:App的主页。

singleInstance:在一个新栈中创建该 Activity 的实例,并让多个应用共享该栈中的该 Activity 实例。一旦该模式的 Activity 实例已经存在于某个栈中,任何应用再激活该 Activity 时都会重用该栈中的实例,是的,依然是调用 onNewIntent() 方法。其效果相当于多个应用共享一个应用,不管是谁激活,该 Activity 都会进入同一个应用中。但值得引起注意的是:singleInstance 不要用于中间页面,如果用户中间页面,跳转会出现很难受的问题。 这个在实际开发中我暂未遇到过,不过 Android 系统的来电页面,多次来电均是使用的同一个 Activity 。

除了在清单文件中配置,我们还可以在代码中设置,且优先级比清单文件中要高
通过设置 Intent.setFlags(int flags) 来设置启动的 Activity 的启动模式。

  • FLAG_ACTIVITY_NEW_TASK
    这个标识会使新启动的 Activity 独立创建一个 Task。

  • FLAG_ACTIVITY_CLEAR_TOP
    这个标识会使新启动的 Activity 检查是否存在于 Task 中,如果存在则清除其之上的 Activity,使它获得焦点,并不重新实例化一个 Activity,一般结合 FLAG_ACTIVITY_NEW_TASK 一起使用。

  • FLAG_ACTIVITY_SINGLE_TOP
    等同于在 launcherMode 属性设置为 singleTop。

四、启动Activity的其他方式

1. 隐式action调用: 在清单文件配置action(必须具有一个DEFAULT的Category)的名字,然后创建intent设置action即可,代码如下:
配置

 <intent-filter>
       <action android:name="customActionName"/>
       <category android:name="android.intent.category.DEFAULT" />
 </intent-filter>

跳转

val intent = Intent()
 intent.action = "customActionName"
 context.startActivity(intent)

注意:隐式调用如果找不到action会发生崩溃,在开发中我们可以通过PackageManager的ResolveActivity方法来进行判断,若找不到匹配的Activity会返回一个null。

2. scheme协议:
URL Schema协议格式:

  • Scheme:代表该Schema 协议名称
  • host:代表Schema作用于哪个地址域
  • path: 代表Schema指定的页面,注意要有斜杠

配置

<activity
    android:name=".ui.activity.WebViewActivity">
    <intent-filter>
        <category android:name="android.intent.category.DEFAULT" />
        <action android:name="android.intent.action.VIEW"/>
        <data android:scheme="custom"/>
        <data android:host="www.custom.test"/>
        <data android:path="/page1"/>
    </intent-filter>
</activity>

跳转: 跳转时可以传递参数,跟get请求格式一样即可

val intent = Intent(Intent.ACTION_VIEW,Uri.parse("custom://www.custom.test/page1?arg=yangxiaoliu"))
context.startActivity(intent)

获取参数

val queryParameter = intent.data?.getQueryParameter("arg")
toast(queryParameter!!)

五、Activity启动流程

用户在launch程序里点击应用图标,会通知ActivityManageService启动应用入口的Activity,ActivityManageService发现这个应用还未启动,则会通知Zygote进程孵化出应用进程,然后这个dalvik应用进程里执行ActivityThread的main方法。应用进程接下来通知ActivityManageService应用进程已启动,AMS保存应用进程的一个代理对象,这样AMS可以通过这个代理对象控制应用进程,然后AMS通知应用进程创建入口Activity的实例,并执行它的生命周期方法。

详细启动流程可参考该博客
http://www.cloudchou.com/android/post-788.html

六、Activity与window、View之间的关系

我们可以追踪Activity的setContentView方法来了解他们三个的关系,源码比较简单,这里只用文字梳理下流程。
每个Activity中都持有一个Window对象,我们在onCreate中setContentView其实最终会调用Window的setContentView方法,而Window对象则是在Activity的onAttach方法中进行的实例化,实例化对象是PhoneWindow。PhoneWindow的setContentView方法则把View添加到了DecorView中的id为R.id.content的mContentParent中。
下面这张图可以简单反应出他们的关系


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