这是一篇描述 Activity 的文章

目录

大纲

Activity任务栈

Activity的4种状态

生命周期

正常情况下activity的生命周期

异常情况下activity生命周期

小总结

通信

Activity与Activity之间通信

Activity与Fragment之间通信

Activity将数据传递给Fragment

Fragment将数据传递给Activity

Activity与Service数据通信

启动模式

LaunchMode

Flags

IntentFilter的匹配规则

相关面试题


文章非完全原创,部分内容也属于摘抄整合,好好复习!~

大纲

Activity任务栈

在Android系统当中,是通过栈的方式来管理activity的, 一个Activity实例的状态又决定了它在栈中的位置,比如说,处于前台的Activity1它总是处于栈的顶端,如果处于前台的Activity1因为异常或者是内存不足而被销毁的时候,处于下方的Activity2就会被激活,一旦激活,它就会上升到栈顶位置,把Activity1给顶掉,当又有新的Activity被启动的时候,以此类推。

返回栈遵循基本的“后进先出”堆栈机制,因此,当用户完成当前 Activity 并按“返回”按钮时,系统会从堆栈中将其弹出(并销毁),然后恢复前一 Activity。通过这种栈的形式来不断的更改Activity在栈中位置的变化,而Activity在栈中位置的不断变化,又反映了它在不同状态间的切换。

Activity的4种状态

  • Active:Activity处于栈顶

(1)可见

(2)在栈顶

(3)和用户交互

  • Paused:可见但不可交互,此时Activity只是失去了和用户交互的能力,它所有的数据、状态、成员变量等都还是存在的,只有在系统内存不足的时候,才有可能会被系统回收,正常情况下不会被系统回收
  • Stopped:不可见,当一个Activity被另外一个Activity完全覆盖,它不是被透明的Activity覆盖,在内存足够的情况下它所有的数据、状态、成员变量等都还是存在的
  • Killed:系统回收掉

生命周期

  • Activity 的整个生命周期发生在 onCreate() 调用与 onDestroy() 调用之间。您的 Activity 应在 onCreate() 中执行“全局”状态设置(例如定义布局),并释放 onDestroy() 中的所有其余资源。例如,如果您的 Activity 有一个在后台运行的线程,用于从网络上下载数据,它可能会在 onCreate() 中创建该线程,然后在 onDestroy() 中停止该线程。
  • Activity 的可见生命周期发生在 onStart() 调用与 onStop() 调用之间。在这段时间,用户可以在屏幕上看到 Activity 并与其交互。 例如,当一个新 Activity 启动,并且此 Activity 不再可见时,系统会调用 onStop()。您可以在调用这两个方法之间保留向用户显示 Activity 所需的资源。 例如,您可以在 onStart() 中注册一个 BroadcastReceiver 以监控影响 UI 的变化,并在用户无法再看到您显示的内容时在 onStop() 中将其取消注册。在 Activity 的整个生命周期,当 Activity 在对用户可见和隐藏两种状态中交替变化时,系统可能会多次调用 onStart() 和 onStop()。
  • Activity 的前台生命周期发生在 onResume() 调用与 onPause() 调用之间。在这段时间,Activity 位于屏幕上的所有其他 Activity 之前,并具有用户输入焦点。 Activity 可频繁转入和转出前台 — 例如,当设备转入休眠状态或出现对话框时,系统会调用 onPause()。 由于此状态可能经常发生转变,因此这两个方法中应采用适度轻量级的代码,以避免因转变速度慢而让用户等待。
  • 上面3段话,摘自这里

正常情况下activity的生命周期

  • onCreate(),在被创建的时候回调,初始化变量或者初始化数据
  • onStart(),这个方法被回调的话就意味着Activity已经正在启动状态了,此时Activity处于可见状态,但未在前台显示,无法与用户交互
  • onResume(),这个方法被回调的话就意味着已经处在前台可见同时可以和用户交互,此时Activity进入了运行状态
  • onPause(),Activity正在停止
  • onStop(),在onPause()执行完之后,立即执行,表示这个Activity即将停止/被一个新的Activity完全覆盖,此时Activity不可见,只能在后台运行
  • onDestroy(),表示Activity正在被销毁,释放资源、回收资源
  • onReStart(),Activity正在重新启动,当Activity从onStop()变为onStart(),会回调这个方法

异常情况下activity生命周期

造成生命周期异常的两大因素:

  • 系统配置发生改变
  • 内存不足或者其他原因造成的改变

相比于正常情况下,异常情况下多了两个方法——onSaveInstanceState()和onRestoreInstanceState(),这两个方法是系统自动调用的,但是,它们是在出现异常情况下才会调用的。

onSaveInstanceState()用来保存当前Activity的状态信息,我们可以在这个方法中存储一些数据,以便被销毁的Activity被重建的时候,可以直接恢复数据。

当Activity被重新创建之后,系统会自动调用onRestoreInstanceState(),会把Activity销毁时通过onSaveInstanceState()保存的bundle对象,作为参数,传递给onRestoreInstanceState()同时传递给onCreate()。

在平时,为了防止异常情况的出现,我们可以通过onRestoreInstanceState()和onCreate()来判断Activity是否被重新创建或者是否被销毁,销毁了的话,我们就可以在这两个方法当中去选一个去进行数据的恢复。

但是二者也有一些区别:在onRestoreInstanceState()当中,一旦被系统调用了,它里面传的参数bundle一定不能为空,所以在这里不需要做bundle的非空判断,而在onCreate()种bundle的参数有可能为空,所以在这里需要进行非空判断。所以推荐使用onRestoreInstanceState()。

:由于无法保证系统会调用 onSaveInstanceState(),因此您只应利用它来记录 Activity 的瞬态(UI 的状态)—— 切勿使用它来存储持久性数据,而应使用 onPause() 在用户离开 Activity 后存储持久性数据(例如应保存到数据库的数据)。

小总结

  • Activity是与用户交互的接口
  • Android系统是通过Activity栈的形式来管理的
  • Activity的四种形态:Active/Pause/Stopped/Killed
  • Activity正常启动:onCreate()-onStart()-onResume()
  • 点击back回退:onPause()-onStop()-onDestroy()
  • 在原来的Activity打开一个新的Activity:

可以看到,原来的Activity(后称之为:MainActivity)在点击跳转按钮打开一个新的Activity(后称之为:NextActivity)的时候,MainActivity会先执行onPause()进入暂停的状态,紧接着NextActivity会走onCreate()-onStart()-onResume(),当NextActivity处于onResume()的可见可交互状态了,MainActivity才会走onStop()

那么如果此时,在新的Activity(NextActivity)按下返回按钮,又会是怎么样的一个生命周期呢?:

可以看到,NextActivity先执行了onPause()进入暂停的状态,紧接着MainActivity执行了onRestart()-onStart()-onResume(),当MainActivity处于可见可交互的状态之后,NextActivity才执行onStop()-onDestroy()

所以可以有这么个小规律,当多个Activity交互跳转的时候,一定会先执行当前页面的onPause()进入暂停的状态,然后执行目的页面的onCreate()/onRestart()-onStart()-onResume(),当目的页面处于onResume()的可见可交互状态了,原先的页面才会走onStop()

  • Activity异常:用onSaveInstanceState()保存数据

通信

Activity与Activity之间通信

  • Intent/Bundle

Bundle类是一个key-value类

对于第一个Activity而言——

  1. 建立bundle对象

  2. 在bundle对象中传入key-value

  3. 建立intent对象

  4. 将bundle作为参数,传递到intent中

  5. startActivity()

对于第二个Activity而言——

  1. 用getIntent()获取第一个Activity当中的intent
  2. 调用intent.getxxxxxxx()获取内容,根据key获取value
  • 类静态变量

通过借助类的静态变量时,接收到这个Activity的静态信息

  • 全局变量

重新声明一个类,在这个类中定义一些全局变量

Activity与Fragment之间通信

Activity将数据传递给Fragment

  • bundle
  • 直接在Activity中定义方法
  1. Fragment获取到对应的Activity

  2. 获取到对应的方法

Fragment将数据传递给Activity

  • 接口回调
  1. 在Fragment中定义一个内部回调接口,用于和Activity交互
  2. 让包含这个Fragment的activity实现这个回调接口
  3. 在Fragment的方法onAttach()获取Activity
  4. Fragment就可以调用这个接口当中的方法将数据传递给Activity
  5. 调用onDetach方法,这个时候要把传递进来的Activity对象释放掉,否则会影响Activity销毁,产生泄露
  • 第三方框架
  • 广播

Activity与Service数据通信

  • 绑定服务,利用ServiceConnection类

对Service——

  1. 实现一个Binder类,在里面定义方法

  2. 在Service中重写onBind(),返回new Binder()对象给Activity

对Activity——

  1. 实现ServiceConnection类,有两个方法需要重写

  2. 在Activity中定义一个binder对象

  3. 重写的onServiceConnected()中获取这个binder对象

  4. 在合适的位置,就可以实现Service中binder类定义的方法了

  • 简单通信,利用Intent进行传值
  • 定义一个callback接口来监听服务中进程的变化

对Service——

  1. 给Service添加一个公开的接口Callback
  2. 在Callback内部定义一个方法
  3. 在Service中实现一个Binder类,返回当前的Service对象

对Activity——

  1. 需要实现ServiceConnection类,在onServiceConnected()中获取这个binder对象,调用callback接口当中的方法
  2. 由于在callback接口当中的方法是运行在子线程的,如果我们需要更新界面,就需要同时发送消息,让主线程刷新界面

启动模式

由于文章篇幅过长,启动模式的内容就另起文章描述 .. 待我慢慢填坑吧 

这是一篇描述 Activity启动模式 的文章

IntentFilter的匹配规则

以下内容摘自:使用 Intent 过滤器

<activity> 元素还可指定各种 Intent 过滤器 —— 使用 <intent-filter> 元素以声明其他应用组件激活它的方法。

当您使用 Android SDK 工具创建新应用时,系统自动为您创建的存根 Activity 包含一个 Intent 过滤器,其中声明了该 Activity 响应“主”操作且应置于“launcher”类别内。 Intent 过滤器的内容如下所示:

<activity android:name=".ExampleActivity" android:icon="@drawable/app_icon">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<action> 元素指定这是应用的“主”入口点。

<category> 元素指定此 Activity 应列入系统的应用启动器内(以便用户启动该 Activity)。

如果您打算让应用成为独立应用,不允许其他应用激活其 Activity,则您不需要任何其他 Intent 过滤器。 正如前例所示,只应有一个 Activity 具有“主”操作和“launcher”类别。 您不想提供给Activity 任何 Intent 过滤器,您可以利用显式 Intent 自行启动Activity 。

不过,如果您想让 Activity 进行隐式 Intent 作出响应,则必须为 Activity 定义其他 Intent 过滤器。 对于您想要作出响应的每一个 Intent 类型,您都必须加入相应的 <intent-filter>,其中包括一个<action> 元素,还可选择性地包括一个 <category> 元素和/或一个 <data> 元素。这些元素指定您的 Activity 可以响应的 Intent 类型。

更多的描述也可见这是一篇描述 Intent 和 Intent 过滤器 的文章

相关面试题

200斤牌面试必备:Activity面试题 请安利(不停更)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值