Activity详解

一、Activity简述

1、概念引入


图1.1 Activity类图结构

Activity作为Android的四大组件之一,Activity在Android系统中是以界面的形式进行体现。其中Activity实现了如Window.Callback, KeyEvent.Callback等接口用于与用户进行交互。

2、源码释义

    An activity is a single, focused thing that the user can do. 

一个界面是开发者可以操作的一个重点的独立事项。

    Almost all activities interact with the user, so the Activity class takes care of creating a window for you in which you can place your UI with setContentView(View). 

几乎所有界面都可以与用户交互,所以Activity类负责为用户创建一个窗口,你可以在其中使用setContentView(View)放置UI。

    While activities are often presented to the user as full-screen windows, they can also be used in other ways: as floating windows (via a theme with windowIsFloating set) or embedded inside of another activity (using ActivityGroup). 

虽然界面通常以全屏窗口的形式呈现给用户,但它们也可以以其他方式使用:作为浮动窗口(通过具有windowIsFloating集合的主题)或嵌入另一个活动(使用ActivityGroup)内部

    There are two methods almost all subclasses of Activity will implement:

几乎所有的Activity子类都会实现两种方法:

    onCreate(Bundle) is where you initialize your activity. Most importantly, here you will usually call setContentView(int) with a layout resource defining your UI, and using findViewById(int) to retrieve the widgets in that UI that you need to interact with programmatically.

onCreate(Bundle)是初始化界面的地方。最重要的是,在这里你通常会调用setContentView(int)和一个定义你的UI的布局资源,并且使用findViewById(int)来检索你需要以编程方式进行交互的那个UI中控件。

    onPause() is where you deal with the user leaving your activity.Most importantly, any changes made by the user should at this point be committed (usually to the ContentProvider holding the data).

onPause()是你对于用户离开界面的处理。最重要的是,此时用户所做的任何更改都应该提交(通常发送给持有数据的ContentProvider。

    To be of use with Context.startActivity(), all activity classes must have a corresponding declaration in their package's AndroidManifest.xml.

要使用Context.startActivity(),所有界面类必须在其包下的AndroidManifest.xml中具有相应的声明。


二、Activity的生命周期

1、Activity的生命周期图

2、生命周期详解

2.1、OnCreate()方法

    Called when the activity is first created. This is where you should do all of your normal static set up:
    create views, bind data to lists, etc. 

在第一次创建活动时调用。 这是你应该完成所有常规静态设置的位置:创建视图,将数据绑定到列表等。

    This method also provides you with a Bundle containing the activity's previously frozen state, if there was one.Always followed by onStart().

此方法还会为你提供一个包含Activity先前保存页面状态的Bundle对象(如果有的话)。总是跟着onStart()方法。

2.2、OnRestart()方法

    Called after your activity has been stopped, prior to it being started again.

在你的界面停止后调用,然后再次启动。

    Always followed by onStart()

总是跟着onStart()

2.3、OnStart()方法

    Called when the activity is becoming visible to the user.

当界面对用户变得可见时调用。

    Followed by onResume() if the activity comes to the foreground, or onStop() if it becomes hidden.

如果活动进入前台,则跟随执行onResume()方法,如果隐藏,则执行onStop()。
此时,Activity实际上就已经可见了,但是还没有出现在前台,无法和用户进行交互。

2.4、onResume()方法

    Called when the activity will start interacting with the user.

当界面对用户变得可见时调用。

    At this point your activity is at the top of the activity stack, with user input going to it.Always followed by onPause().

如果界面进入前台,则跟随onResume()方法,如果隐藏,则执行onStop()方法。
此时,Activity已经可见,并且出现在前台并开始活动。要注意的是onStart()被执行时Activity显示在后台,只有当OnResume()被执行时Activity才显示到前台。

2.5、onPause()方法

    Called when the system is about to start resuming a previous activity. This is typically used to commit unsaved changes to persistent data, stop animations and other things that may be consuming CPU, etc. Implementations of this method must be very quick because the next activity will not be resumed until this method returns.

onPause()方法在系统即将开始显示之前的界面时调用。 这通常用于将未保存的更改进行保存,并保存为持久化数据,并且会执行例如停止动画和其他可能消耗CPU的内容等。此方法的实现必须非常快速,因为在此方法返回之前,下一个界面不会显示。

    Followed by either onResume() if the activity returns back to the front, or onStop() if it becomes invisible to the user.

如果界面返回到前台,则跟随onResume();如果对用户不可见,则使用onStop()。

  • onPause()方法执行后,Activity界面切换为后台程序

2.6、onStop()方法

    Called when the activity is no longer visible to the user, because another activity has been resumed and is covering this one. This may happen either because a new activity is being started, an existing one is being brought in front of this one, or this one is being destroyed.

onStop()方法会在当界面对用户不再可见时调用,因为另一项界面正在显示并要去覆盖这个界面。 这可能是因为一项新的界面正在开始,其他的界面会被显示为前台界面,或者这个界面正在被摧毁。

    Followed by either onRestart() if this activity is coming back to interact with the user, or onDestroy() if this activity is going away.

如果这个界面快速的回显与用户交互紧接着onRestart()会被执行,否则,这个界面回销毁onDestroy()方法会被执行。

2.6、onDestroy()方法

    The final call you receive before your activity is destroyed. This can happen either because the activity is finishing (someone called finish() on it, or because the system is temporarily destroying this instance of the activity to save space. You can distinguish between these two scenarios with the isFinishing() method.)

在你的界面被销毁前被最后调用的方法。 这可能是因为界面正在结束(有人在其中调用finish()方法因为系统会暂时销毁此Activity界面的实例以节省空间,你可以使用isFinishing()方法区分内存空间是否节省资源的这两种情况)。



3、异常情况下生命周期详解

3.1、横竖屏切换时Activity的生命周期

此时的生命周期跟清单文件里的配置有关系。
不设置 Activity 的 android:configChanges 时,横竖屏切换会重新调用各个生命周期,销毁当前 activity,然后重新加载,跟系统配置有关。
onSaveInstanceState()方法会在当前页面销毁前被调用存储数据onRestoreInstanceState()方法会被执行去取出保存的Bundle对象中的内容,进行一次横竖屏切换时Activity所执行的生命周期方法以及在onSaveInstanceState与onRestoreInstanceState打印相应日志,如下图所示:

③对于onRestoreInstanceState()方法,源码中的注释如下:

      This method is called after onStart when the activity is being re-initialized from a previously saved state, given here in savedInstanceState.  

当这个界面从之前保存的状态重新初始化时,这个方法在onStart之后被调用,这里在savedInstanceState中给出。

      Most implementations will simply use onCreate to restore their state, but it is sometimes convenient to do it here after all of the initialization has been done or to allow subclasses to decide whether to use your default implementation.  The default implementation of this method performs a restore of any view state that had previously been frozen by onSaveInstanceState.

大多数时,可以直接从onCreate()方法中的Bundle对象从中获取内容来恢复之前的页面状态,但有时在完成所有初始化或允许子类决定使用默认实现之后,在此处执行重新获取已存储数据的操作很方便。 此方法的默认实现会还原之前由onSaveInstanceState保存的任何视图状态。
根据源码可以得知onRestoreInstanceState 方法的默认实现会还原之前由onSaveInstanceState保存的任何视图状态。

三、Activity任务与任务管理栈

1、任务与任务栈概述

任务是指在执行特定作业时与用户交互的一系列 Activity。 这些 Activity 按照各自的打开顺序排列在堆栈(即任务栈)中。

  • 设备主屏幕是大多数任务的起点。当用户触摸应用启动器中的图标(或主屏幕上的快捷方式)时,该应用的任务将出现在前台。 如果应用不存在任务(应用最近未曾使用),则会创建一个新任务,并且该应用的“主”Activity 将作为堆栈中的根 Activity 打开。

当前 Activity 启动另一个 Activity 时,该新 Activity 会被推送到堆栈顶部,成为焦点所在。 前一个 Activity 仍保留在堆栈中,但是处于停止状态。Activity 停止时,系统会保持其用户界面的当前状态。 用户按“返回”按钮时,当前 Activity 会从堆栈顶部弹出(Activity 被销毁),而前一个 Activity 恢复执行(恢复其 UI 的前一状态)。 堆栈中的 Activity 永远不会重新排列,仅推入和弹出堆栈:由当前 Activity 启动时推入堆栈;用户使用“返回”按钮退出时弹出堆栈。 因此,返回栈以“后进先出”对象结构运行。 下图 通过时间线显示 Activity 之间的进度以及每个时间点的当前返回栈,直观呈现了这种行为。



作者:cc丶文乐
链接:https://www.jianshu.com/p/1c7f851608b7#comments
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2、任务栈关联

关联指 Activity 优先属于哪个任务。默认情况下,同一应用中的所有 Activity 彼此关联。 因此,默认情况下,同一应用中的所有 Activity 优先位于相同任务中。 不过,可以修改 Activity 的默认关联。 在不同应用中定义的 Activity 可以共享关联,或者可为在同一应用中定义的 Activity 分配不同的任务关联。

  • 可以使用activity元素的 taskAffinity属性修改任何给定 Activity 的关联。

taskAffinity 属性取字符串值,该值必须不同于在AndroidManifest.xml文件中声明的默认软件包名称,因为系统使用该名称标识应用的默认任务关联。

在两种情况下,关联会起作用:

  1. 启动 Activity 的 Intent 包含 FLAG_ACTIVITY_NEW_TASK标志。

  2. Activity 将其allowTaskReparenting 属性设置为 true。

    在这种情况下,Activity 可以从其启动的任务移动到与其具有关联的任务(如果该任务出现在前台)。

3、清理任务栈

如果用户长时间离开应用,则系统会清除应用下所有除 Activity 的所有 Activity 。 当用户再次返回到任务时,仅恢复根 Activity。系统这样做的原因是,经过很长一段时间后,用户可能已经放弃之前执行的操作,返回到任务是要开始执行新的操作。
可以使用下列几个 Activity 属性修改此行为:

  • alwaysRetainTaskState
    如果在任务的根 Activity 中将此属性设置为 true`,则不会发生刚才所述的默认行为。即使在很长一段时间后,任务仍将所有 Activity 保留在其堆栈中。

  • clearTaskOnLaunch
    如果在任务的根 Activity 中将此属性设置为 "true",则每当用户离开任务然后返回时,系统都会将堆栈清除到只剩下根 Activity。 换而言之,它与 alwaysRetainTaskState 正好相反。 即使只离开任务片刻时间,用户也始终会返回到任务的初始状态。

  • finishOnTaskLaunch
    此属性类似于 clearTaskOnLaunch,但它对单个 Activity 起作用,而非整个任务。 此外,它还有可能会导致任何 Activity 停止,包括根 Activity。 设置为 true 时,Activity 仍是任务的一部分,但是仅限于当前会话。如果用户离开然后返回任务,则任务将不复存在。


四、Activity的启动模式

在AndroidManifest.xml文件中为Activity配置相应的launchMode属性可以设置Activity的启动模式,共如下四种模式:

  • standard
  • singleTask
  • singleTop
  • singleInstance
    接下来对四种启动模式进行详细分析。

1、standard模式

标准启动模式:
该模式下每次启动Activity都会重新创建Activity实例,在这种模式下谁启动了这个Actvitiy,那么这个Activity与被启动的Activity位于启动它的Activity的栈中。

但是在代码中采用ApplicationContext去开启Activity时(例如执行如下代码时):

getApplication().startActivity(new Intent(HomeActivity.this,MainActivity.class));

会报如下所示的错误



作者:cc丶文乐
链接:https://www.jianshu.com/p/1c7f851608b7#comments
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 分析:非Activity类型的Context(如ApplicationContext)并没有任务栈。
  • 解决方案:为待启动的Activity指定FLAG_ACTIVITY_NEW_TASK标记,那么通过这种方式启动的Activity就会新开启一个任务栈。

2、singleTop模式

栈顶复用模式:
该模式下如果Activity已经位于栈顶,那么该Activity不会重新创建,同时它的OnNewIntent方法会被调用,通过方法的参数可以取出其中的信息,并且在这种模式如果这个Actvitiy不位于栈顶,那么这个Activity依然会被重新创建。

图4.2 OnNewIntent方法

3、singleTask模式

栈内复用模式:
只要Activity实例在一个栈中存在,那么再次启动该Activity时不会重新创建实例,并且系统也会回调其OnNewIntent方法,并且该模式下有清除栈顶实例的效果,即会将与singleTask模式下的该Activity同一个栈中的栈顶的所有Activity实例全部出栈。

4、singleInstance模式

单实例模式:
单实例模式具备singleTask模式的所有的特性,此外具有此模式的Activity只能单独位于一个任务栈中。

在这里,我们以HomeActivity、MainActivity、DetailActivity三个Activity演示singleInstance模式下的页面跳转,其中MainActivity为singleInstance模式,其他两个页面为standard模式。




作者:cc丶文乐
链接:https://www.jianshu.com/p/1c7f851608b7
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Java 中,Activity 是 Android 应用程序的核心组件之一。它代表了用户与应用程序交互的一个屏幕,似于 Windows 中的窗口。Activity 提供了一个用户界面,用于显示应用程序的内容,并处理用户输入。在本文中,我们将详细介绍 Java 中的 Activity。 1. Activity 的生命周期 Activity 的生命周期是指从创建到销毁的整个过程。Activity 的生命周期可以分为以下几个部分: 1.1. 创建阶段 在创建阶段,Activity 将完成以下几个步骤: 1.1.1. onCreate():当 Activity 被创建时,系统会调用 onCreate() 方法。在此方法中,开发者可以初始化 Activity 的布局、绑定事件等。 1.1.2. onStart():当 Activity 准备好与用户进行交互时,系统会调用 onStart() 方法。在此方法中,开发者可以完成一些初始化工作,例如开始动画。 1.1.3. onResume():当 Activity 成为用户焦点并可以与用户进行交互时,系统会调用 onResume() 方法。在此方法中,开发者可以开始处理用户输入事件。 1.2. 运行阶段 在运行阶段,Activity 将完成以下几个步骤: 1.2.1. onPause():当 Activity 失去焦点并不再与用户进行交互时,系统会调用 onPause() 方法。在此方法中,开发者可以停止处理用户输入事件。 1.2.2. onStop():当 Activity 不再可见时,系统会调用 onStop() 方法。在此方法中,开发者可以完成一些清理工作,例如停止动画。 1.3. 销毁阶段 在销毁阶段,Activity 将完成以下几个步骤: 1.3.1. onDestroy():当 Activity 被销毁时,系统会调用 onDestroy() 方法。在此方法中,开发者可以完成一些清理工作,例如释放资源。 2. Activity 的启动方式 在 Java 中,可以通过以下方式启动一个 Activity: 2.1. 显式启动 显式启动是指通过明确指定要启动的 Activity名来启动 Activity。例如: ```java Intent intent = new Intent(this, AnotherActivity.class); startActivity(intent); ``` 2.2. 隐式启动 隐式启动是指通过指定 Action、Category、Data 等信息来启动 Activity,系统将根据这些信息匹配合适的 Activity。例如: ```java Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setData(Uri.parse("http://www.example.com")); startActivity(intent); ``` 3. Activity 的传值 在 Java 中,可以通过 Intent 对象来传递数据到另一个 Activity。具体步骤如下: 3.1. 在发送 Intent 时,通过 putExtra() 方法来添加数据: ```java Intent intent = new Intent(this, AnotherActivity.class); intent.putExtra("name", "张三"); intent.putExtra("age", 18); startActivity(intent); ``` 3.2. 在接收 Intent 时,通过 getIntent() 方法获取 Intent 对象,并通过 getXXXExtra() 方法获取数据: ```java Intent intent = getIntent(); String name = intent.getStringExtra("name"); int age = intent.getIntExtra("age", 0); ``` 4. Activity 的返回值 在 Java 中,可以通过 startActivityForResult() 方法启动一个 Activity,并在该 Activity 中设置 setResult() 方法来返回数据。具体步骤如下: 4.1. 在发送 Intent 时,通过 startActivityForResult() 方法启动另一个 Activity: ```java Intent intent = new Intent(this, AnotherActivity.class); startActivityForResult(intent, REQUEST_CODE); ``` 4.2. 在接收 Intent 时,通过 onActivityResult() 方法获取返回的数据: ```java @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) { String result = data.getStringExtra("result"); } } ``` 4.3. 在被返回的 Activity 中,通过 setResult() 方法设置返回的数据: ```java Intent intent = new Intent(); intent.putExtra("result", "返回数据"); setResult(RESULT_OK, intent); finish(); ``` 以上就是 Java 中 Activity详解,希望对你有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值