《Android UI基础教程》——2.5节理解活动

简介:

本节书摘来自异步社区《Android UI基础教程》一书中的第2章,第2.5节理解活动,作者 【美】Jason Ostrander,更多章节内容可以访问云栖社区“异步社区”公众号查看

2.5 理解活动
Android UI基础教程

2.5.1 声明活动
所有的活动都必须在应用程序的清单文件中声明。如果没有声明,在应用第一次运行时会导致抛出异常。下面是时间跟踪应用的一个示例活动的清单条目:

`<activity android:name=".TimeTrackerActivity"`
` ``  `` `` android:label="@string/app`_`name">`
` ``  `` `` <intent-filter>`
` ``  `` `` `` ``  `` `` <action android:name="android.intent.action.MAIN" />`
` ``  `` `` `` ``  `` `` `` ``  `` `` <category android:name="android.intent.category.LAUNCHER" />`
` ``  `` `` </intent-filter>`
`</activity>`

该清单条目包含诸如类名称和用户标签之类的活动的基本信息。注意到名称属性里的“.”了吗?这是使用列在<application>元素里的完整包名称的一个简洁方法。这个活动同样声明了一个意图过滤器,用于响应系统发送的意图。在本例中,声明了这是应用的主要活动并且应当响应Androdi.intent.category.LAUNCHER意图,当点击主屏幕上的应用图标时,会发送这个意图。运行活动的意图应当在清单文件中被声明。

2.5.2 了解活动的生命周期
活动的生命周期很短—它们不断地被创建和销毁。开发者需要在用户使用应用程序时妥善处理这些转换。你通过继承活动类创建一个活动,并且当活动在不同状态之间跳转时需要实现一系列系统调用的回调函数。活动有3大基本状态,如表2.2所示。


91812fccd72517bca6a782a5285444363b656918

当一个活动第一次被系统实例化时会调用onCreate方法。你应该一直保持实现这个方法。在onCreate方法中你将需要执行活动的基本设置:往视图中绑定数据,为活动设置布局,初始化线程等。你同样应该实现onPause方法。当活动从前台转换到后台时onPause方法是第一个被触发的回调函数,这时应该保存用户进入应用之后所产生任何变化的数据。

提示: onPause方法里应该保存用户期望保存的任何数据。例如,如果你创建了一个电子邮件的应用程序,用户输入的任何文本内容都应该在调用onPause回调函数时保存进数据库中。

你应该始终调用所实现的活动回调函数的超类实现。如果你不这样做,活动会抛出一个异常。

作为在3个状态间跳转的活动,该Activity类会经常触发回调函数。图2.11给出了回调函数的概览以及它们何时会被触发。关于活动要记住两个重要的事情:当活动对于用户不可见时系统将会积极销毁它,回调函数都运行在主线程上,所以你不应在其中执行任何长时间运行或者大量计算的操作。


bb29183c05db20436e1e55aef190586c807263a5

时间跟踪应用将会需要重写onCreate方法。当你创建定时器逻辑时同样需要重写onDestroy方法。随后,当你要实现数据库时,你将要重写onPause方法来保存任何用户输入的数据。

1.在com.example包中,创建一个名为TimeTrackerActivity.java的文件:

public class TimeTrackerActivity extends Activity {
2.重写onCreate方法并用下面的代码设置视图:

`@Override`
` `` ``   ``public void onCreate(Bundle savedInstanceState) {`
` `` ``    `` ``   ``super.onCreate(savedInstanceState);`
` `` ``    `` ``   ``setContentView(R.layout.main);`
` `` ``    `` ``   ``// Initialize the timer`
` `` ``    `` ``   ``TextView counter = (TextView) findViewById(R.id.counter);`
` `` ``    `` ``   ``counter.setText(DateUtils.formatElapsedTime(0));`
` `` ``   ``if (mTimeListAdapter == null)`
` `` ``    `` ``    `` ``   ``mTimeListAdapter = new TimeListAdapter(this, 0);`
` `` ``    `` ``   ``ListView list = (ListView) findViewById(R.id.time`_`list);`
` `` ``    `` ``   ``list.setAdapter(mTimeListAdapter);`
` `` ``   ``}`
`}`

此代码通过调用setContentView方法为你的活动设置XML布局文件。SetContentView方法扩展了XML布局并将其添加到活动的视图层次。接下来,findViewById方法检索保存当前时间的TextView的引用。它使用DateUtils格式设置默认时间。最后,会在ListView实例上创建并设置ListAdapter,你会用其往ListView中加载数据。

你应当在活动的onCreate方法中调用setContentView。在onCreate中你可能会多次调用它,但是只会执行最近的调用。一旦视图层次被加载,你就不能再调用setContentView了。然而,你仍然可以自由使用Java API来更新布局。

2.5.3 了解任务和返回堆栈
Android应用通常由一系列的活动构成。系统将这些活动按照任务进行分组。每一个任务都是一个堆栈,代表了一组活动,当用户使用时活动入栈,用户离开时活动出栈(图2.12)。这被叫做返回堆栈。当用户


02b9f1d865dee77662c86b68c4fca93e8e8772bc

打开一个和当前活动没有联系的新活动时,新的任务会被创建。每一个任务都有自己的返回堆栈。

关于主线程的一个注解

一个Android应用程序的主线程或者UI线程是触发所有UI事件的地方。每一个你按下的按钮都会产生一个通过主线程派遣的事件。出于这个原因,使用工作者线程来处理长时间的操作就很重要。尝试从工作者线程中更新UI将会导致异常。Android提供了很多处理这个问题的API: Activity.runOnUiThread方法 View.post,View.postDelayed以及View.postInvalidate方法 AsyncTask类 消息处理程序 如果你需要更新应用程序的UI,需要确保是从UI线程更新或者使用上面的API。在本章后面你将学到更多关于AsyncTask的知识。

用一个简单的例子来展示(图2.13)。


c50805254152c485052405dcbc037121c47aaa0b

1.用户打开一个应用程序。这会创建一个新任务。例子中是ListView。

2.用户通过点击一个列表项进入到一个新的活动。

3.用户点击主页,然后打开一个新的应用。这又会创建一个任务。

4.用户进入到这个任务的一个新的活动,再次按下列表项。

现在有两个任务以及两个返回堆栈。用户可以通过点击主页并点击运行其中的一个应用在两个任务之间切换。另外,在Android 4.0以及之后的版本中,用户可以点击任务切换按钮来切换任务。返回按钮会操作活动的堆栈并从任务中弹出用户正在看的活动。

在返回堆栈中同一个活动出现多次是可能的。当相同的活动能够从不同的地方开始时这就会发生。你应当注意到这些情况,因为存储相同活动的拷贝会很容易就耗费大量的内存空间。对于用户来说这同样是恼人的事情,因为他们不得不一遍遍地按返回按钮以退出应用。

2.5.4 处理配置更改
Android应用常常会面临处理设备配置更改的情况。什么是设备配置更改?最基本的一种就是当旋转设备时朝向的改变。这会把屏幕从竖屏变到横屏。这个设置更改会导致当前活动被摧毁并重新创建。记住活动的生命周期很短,像转动设备这样简单的操作都会导致一个新的活动被创建。

当活动被销毁并重新创建时如何保持输入数据和应用的状态呢?通常你会在活动的onPause方法里保存数据。然而,这仅用于对于用户来说重要的数据。在本例中,你想要保存只和现有存在的活动实例有关的数据。要做到这一点,你可以在onSaveInstanceState回调函数中保存活动的当前状态。与onPause不同,onSaveInstance State并不经常被系统调用。它仅仅在活动被销毁并且可能会被重新建立时被调用。你应当在活动被销毁之前就使用onSaveInstanceState来重建状态。一个好用的方法就是保存当前列表的滚动位置,这样一来你就可以在朝向改变时保存列表位置。下面是一个保存当前列表位置的例子:

`@Override`
`protected void onSaveInstanceState(Bundle outState) {`
`    ListView list = (ListView) findViewById(R.id.time`_`list);`
`    int pos = list.getFirstVisiblePosition();`
`    outState.putInt("first`_`position", pos);`
`    super.onSaveInstanceState(outState);`

`}`

当onCreate被创建时,从输入束中检索列表并重新滚动列表。处理像这样的细节会让应用更加用户友好。

相关文章
|
1天前
|
搜索推荐 Android开发 开发者
探索安卓开发中的自定义视图:打造个性化UI组件
【10月更文挑战第39天】在安卓开发的世界中,自定义视图是实现独特界面设计的关键。本文将引导你理解自定义视图的概念、创建流程,以及如何通过它们增强应用的用户体验。我们将从基础出发,逐步深入,最终让你能够自信地设计和实现专属的UI组件。
|
2月前
|
XML Android开发 UED
💥Android UI设计新风尚!掌握Material Design精髓,让你的界面颜值爆表!🎨
随着移动应用市场的蓬勃发展,用户对界面设计的要求日益提高。为此,掌握由Google推出的Material Design设计语言成为提升应用颜值和用户体验的关键。本文将带你深入了解Material Design的核心原则,如真实感、统一性和创新性,并通过丰富的组件库及示例代码,助你轻松打造美观且一致的应用界面。无论是色彩搭配还是动画效果,Material Design都能为你的Android应用增添无限魅力。
61 1
|
3月前
|
存储 搜索推荐 Java
探索安卓开发中的自定义视图:打造个性化UI组件Java中的异常处理:从基础到高级
【8月更文挑战第29天】在安卓应用的海洋中,一个独特的用户界面(UI)能让应用脱颖而出。自定义视图是实现这一目标的强大工具。本文将通过一个简单的自定义计数器视图示例,展示如何从零开始创建一个具有独特风格和功能的安卓UI组件,并讨论在此过程中涉及的设计原则、性能优化和兼容性问题。准备好让你的应用与众不同了吗?让我们开始吧!
|
3月前
|
编解码 Android开发
【Android Studio】使用UI工具绘制,ConstraintLayout 限制性布局,快速上手
本文介绍了Android Studio中使用ConstraintLayout布局的方法,通过创建布局文件、设置控件约束等步骤,快速上手UI设计,并提供了一个TV Launcher界面布局的绘制示例。
55 1
|
3月前
|
API Android开发
Android项目架构设计问题之选择和使用合适的UI库如何解决
Android项目架构设计问题之选择和使用合适的UI库如何解决
47 0
|
4月前
|
XML Android开发 UED
💥Android UI设计新风尚!掌握Material Design精髓,让你的界面颜值爆表!🎨
【7月更文挑战第28天】随着移动应用市场的发展,用户对界面设计的要求不断提高。Material Design是由Google推出的设计语言,强调真实感、统一性和创新性,通过模拟纸张和墨水的物理属性创造沉浸式体验。它注重色彩、排版、图标和布局的一致性,确保跨设备的统一视觉风格。Android Studio提供了丰富的Material Design组件库,如按钮、卡片等,易于使用且美观。
133 1
|
5月前
|
XML IDE 开发工具
【Android UI】自定义带按钮的标题栏
【Android UI】自定义带按钮的标题栏
59 7
【Android UI】自定义带按钮的标题栏
|
5月前
|
Android开发 开发者
Android UI设计中,Theme定义了Activity的视觉风格,包括颜色、字体、窗口样式等,定义在`styles.xml`。
【6月更文挑战第26天】Android UI设计中,Theme定义了Activity的视觉风格,包括颜色、字体、窗口样式等,定义在`styles.xml`。要更改主题,首先在该文件中创建新主题,如`MyAppTheme`,覆盖所需属性。然后,在`AndroidManifest.xml`中应用主题至应用或特定Activity。运行时切换主题可通过重新设置并重启Activity实现,或使用`setTheme`和`recreate()`方法。这允许开发者定制界面并与品牌指南匹配,或提供多主题选项。
78 6
|
5月前
|
开发工具 Android开发 开发者
Android `.9.png` 图像是用于UI的可拉伸格式,保持元素清晰度和比例
【6月更文挑战第26天】Android `.9.png` 图像是用于UI的可拉伸格式,保持元素清晰度和比例。通过边上的黑线定义拉伸区域,右下角黑点标识内容区域,适应文本或组件大小变化。常用于按钮、背景等,确保跨屏幕尺寸显示质量。Android SDK 提供`draw9patch.bat`工具来创建和编辑。**
251 6
|
5月前
|
API Android开发 开发者
`RecyclerView`是Android API 21引入的UI组件,用于替代ListView和GridView
【6月更文挑战第26天】`RecyclerView`是Android API 21引入的UI组件,用于替代ListView和GridView。它提供高效的数据视图复用,优化的布局管理,支持多种布局(如线性、网格),并解耦数据、适配器和视图。RecyclerView的灵活性、性能(如局部刷新和动画支持)和扩展性使其成为现代Android开发的首选,特别是在处理大规模数据集时。
62 2