- 浏览: 297636 次
- 性别:
- 来自: 上海
最新评论
-
再_见孙悟空:
写的不错
Dialog -
a549262189:
支持下,正好在学习这块的内容!
Android Gesture Detector -
dcsff:
受教了
LayoutInflater -
庆_啊:
真厉害。
LayoutInflater -
ghj234:
学习了,哈哈
LayoutInflater
转自:http://www.blogjava.net/marshal-hird/archive/2008/07/25/217389.html
activity 展现在用户面前的经常是全屏窗口,你也可以将 activity 作为浮动窗口来使用(使用设置了 windowIsFloating 的主题),或者嵌入到其他的 activity (使用 ActivityGroup )中。 当用户离开 activity 时你可以在 onPause() 进行相应的操作 。更重要的是,用户做的任何改变都应该在该点上提交 ( 经常提交到 ContentProvide r 这里保存数据 ) 。
1. Activity 生命周期
系统中的Activity可以通过一个activity栈来进行管理。当一个新的 activity 启动的时候,它首先会被放置在 activity 栈顶部并成为 running 状态的 activity —— 之前的 activity 也在 activity 栈中,但总是被保存在它的下边,只有当这个新的 activity 退出以后之前的 activity 才能重新回到前景界面。所有的 activity 本质上有四种状态:
- activity 在屏幕的前景中( activity 栈的顶端),它是 active 或者 running 状态。
- activity 失去了焦点但是仍然可见(这个 activity 顶上遮挡了一个透明的或者非全屏的activity),它的状态是 paused 。一个 paused 状态的 activity 完全是 alive 的(它维护自己所有的状态和成员信息,而且仍然在 window manager 的管理中),但当系统内存极度贫乏时也会将其 killed 。
- activity 由于其他的 activity 而完全变暗,它就进入了 stopped 状态。它仍然保持着所有的状态和成员的信息,可是,他对于用户来说不可见,当别的地方需要内存的时候它经常会被 killed 。
- activity 是 paused 或者 stopped ,系统需要将其清理出内存的时可以命令其 finish 或者简单 kill 其进程。当它重新在用户面前显示的时候,它必须完全重新启动并且将其关闭之前的状态全部恢复回来。
下面的图表是 Activity 的状态图,直角矩形代表了 callback 方法,你可以实现这些方法从而使 Activity 在改变状态的时候执行你制定的操作。带颜色的椭圆形是 Activity 的主要状态。
这里有三个比较关键的生命周期。
- 从最初 调用onCreate(Bundle) 到最终调用onDestroy() 称为完整生命周期 。Activity 会在onCreate() 进行所有“全局”状态的设置,在onDestroy() 中释放所有持有的资源。举个例子,如果它有一个从网络上下载数据的后台线程,那他可能就会在onCreate() 中创建这个线程并在onDestroy() 中停止这个线程
- 从 activity 调用 onStart() 开始,到调用对应的onStop() 为止称为可见生命周期 。在这段时间内用户可以在屏幕上看到这个activity ,尽管并不一定是在前景也不一定可以和用户交互。在这两个方法之间你可以维护那些activity 在用户显示时所需的资源。举个例子来说,你可以在onStart() 中注册一个IntentReceiver 来监控那些可以对你的UI 产生影响的环境改变,当你的UI 不继续在用户面前显示时你可以在onStop() 中注销这个IntentReceiver 。每当activity 在用户面前显示或者隐藏时都会调用相应的方法,所以onStart() 和onStop() 方法在整个生命周期中可以多次被调用。
- 从 activity 调用 onResume() 开始,到调用对应的onPause() 为止称为前景生命周期 ,这段时间activity 处于其他所有activity 的前面,且与用户交互。一个activity 可以经常在resumed 和paused 状态之间转换——例如手机进入休眠时、activity 的结果返回时、新的intent 到来时——所以这两个方法中的代码应该非常的简短。
所有 activity 都应该实现自己的 onCreate(Bundle) 方法来进行初始化设置;大部分还应该实现 onPause() 方法提交数据的修改并且准备终止与用户的交互。尽管我们计划在系统中添加更多的工具来管理应用,现在大多 activity 仍需要实现 onFreeze() 并且在 onCreate(Bundle) 中执行对应的状态恢复。其他的方法可以在需要时进行实现,当实现这些方法的时候需要注意的是一定要调用父类中的对应方法。
一般来说 activity 的生命周期变化看起来比较象下面的表格:
方法 |
描述 |
Killable? |
下一方法 |
|
Activity 初次创建时被调用,你应该在这里进行一般的静态设置:创建 view 、将数据绑定到 list 等等。如果 activity 之前存在冻结状态,那么此状态将在 Bundle 中提供。 如果 activity 首次创建,本方法后将会调用 onStart() ,如果 activity 是停止后重新显示,则将调用 onRestart() 。 |
No |
|
||
|
当 activity 对用户即将可见的时候调用。 其后调用 onRestart() 或 onResume() ( 框架是否进行选择性调用 onResume() 仅仅是猜测 ) |
No |
|
|
当 activity 从停止状态重新启动时调用。其后调用 onResume() 。 |
No |
|
||
|
当 activity 将要与用户交互时调用此方法,此时 activity 在 activity 栈的栈顶,用户输入已经可以传递给它。 如果其他的 activity 在它的上方恢复显示,则将调用 onFreeze() 。 |
No |
|
|
当你的 activity 被暂停而其他的 activity 恢复与用户交互的时候这个方法会被调用(在其他 activity 显示之前),你可以使用这个方法保存你当前的用户状态(一般来说是当前实例的用户状态)。暂停之后,为了回收资源供给前景 activity ,系统会在需要的时间停止(或者 kill )你的应用。以后如果你的 activity 启动一个新的实例重新与用户进行交互,你保存在这里的状态都将通过 onCreate() 方法传递给新的实例。 其后总是调用 onPause() 方法。 |
No |
|
||
当系统要启动一个其他的 activity 时调用(其他的 activity 显示之前),这个方法被用来提交那些持久数据的改变、停止动画、和其他占用 CPU 资源的东西。由于下一个 activity 在这个方法返回之前不会 resumed ,所以实现这个方法时代码执行要尽可能快。 如果 activity 重新回到前景时将调用 onResume() , 如果对用户彻底不可见则会调用 onStop() 。 |
Yes |
|
||
当另外一个 activity 恢复并遮盖住此 activity, 导致其对用户不再可见时调用。一个新 activity 启动、其它 activity 被切换至前景、当前 activity 被销毁时都会发生这种场景。 当 activity 重新回到前景与用户交互时调用 onRestart() ,如果 activity 将退出则调用 onDestory() 。 |
Yes |
|
||
在你的 activity 被销毁前所调用的最后一个方法,当进程终止时会出现这种情况(对 activity 直接调用 finish() 方法或者系统为了节省空间而临时销毁此 activity 的实例,你可以通过 isFinishing() 的返回值来区分这两种情况)。 |
Yes |
nothing |
① : 这个表格本人觉得还有些值得商榷的地方,建议作为参考阅读,不管是原文还是译文。
注意上表中“Killable”这一列 —— 对于那些标记killable的方法,当这些方法结束后,activity的进程可能在任何时间被系统kill而不再执行activity中的任何代码。因此你应该利用onFreeze()(保存你当前UI的状态)和onPause()(将所有的修改写回持久存储),这样activity才能在被kill 的时候正确的保存当前的状态。如果需要了解一个进程的生命周期与他所执行的activity之间的关系 参见进程生命周期部分。
对于那些标记killable的方法,从这些方法启动开始直到返回之前,activity的进程都不回被系统kill。举个例子,一个activity在onPause()方法返回后处于killable的状态,这种状态会一直持续到onResume()方法开始执行。
2 . 配置改变
如果设备的配置(在 Resources.Configuration 中进行了定义)发生改变,那么所有用户界面上的东西都需要进行更新,以适应新的配置。因为 Activity 是与用户交互的最主要的机制,它包含了处理配置改变的专门支持。
除非你特殊指定,否则当配置发生改变(比如屏幕方向、语言、输入设备等等的改变)时你当前的 activity 都将被销毁,这销毁是通过一个正常的 activity 生命周期过程( onFreeze(Bundle) , onPause() , onStop() , 和 onDestroy() )进行的。如果 activity 之前正在前景画面,当这个实例的 onDestroy() 调用完成后将会启动这个 activity 的一个新的实例,并将前面那个实例中 onFreeze(Bundle) 所保存的内容传递给新的实例。
因为任何的应用资源(包括 layout 文件)都有可能由于任何配置值而改变。因此处理配置改变的唯一安全的方法就是重新获取所有的资源,包括 layout 、绘图资源(原文 drawables )、字符串资源。由于 activity 已经如何保存自己的状态并从这些状态中重建自身,所以 activity 重新启动自身来获得新的配置将是一个非常便利的途径。
在一些特殊的情况中,你可能希望当一种或者多种配置改变时避免重新启动你的 activity 。你可以通过在manifest中设置 android:configChanges 属性来实现这点。你可以在这里声明 activity 可以处理的任何配置改变,当这些配置改变时不会重新启动 activity ,而会调用 activity 的 onConfigurationChanged(Resources.Configuration) 方法。如果改变的配置中包含了你所无法处理的配置(在 android:configChanges 并未声明),你的 activity 仍然要被重新启动,而 onConfigurationChanged(Resources.Configuration) 将不会被调用。
3 . 启动Activity并获得结果
startActivity(Intent) 方法可以用来启动一个新的 activity ,这个 activity 将被放置在 activity 栈的栈顶。这个方法只有一个参数 Intent ,这个参数描述了将被执行的 activity 。
有时候你希望在一个 activity 结束时得到它返回的结果。举个例子,你可能启动一个 activity 来让用户从通讯簿中选择一个人;当它结束的时候将会返回这个所选择的人。为了得到这个返回的信息,你可以使用 startSubActivity(Intent, int) 这个方法来启动新的 activity ,第二个整形参数将会作为这次调用的识别标记。这个 activity 返回的结果你可以通过 onActivityResult(int, int, String, Bundle) 方法来获得,此方法的第一个参数就是之前调用所使用的识别标记。
当 activity 退出的时候,它可以调用 setResult(int) 来将数据返回给他的父进程。这个方法必须提供一个结果码,这个结果码可以使标准结果 RESULT_CANCELED, RESULT_OK ,也可以是其他任何从 RESULT_FIRST_USER 开始的自定义值。此外,它还可以返回一段字符串(经常是一段数据的 URL 地址),一个包含它所有希望值的 Bundle 。这些信息都会在父 activity 的回调函数 Activity.onActivityResult() 中出现,并连同最初提供的识别标记一起(此处有些拗口,意思其实就是子activity 返回的内容、返回码、识别标记都将作为参数,按照不同的返回情况来调用父activity 的Activity.onActivityResult() 方法,以实现出现各种返回时父activity 做出响应的处理)。
如果子activity由于某种情况发生失败(例如 crashing ),父 activity 将会收到 RESULT_CANCELED 结果码。
这里是一个例子,说明了如何启动一个新的 activity 并处理结果。
public class MyActivity extends Activity { ... static final int PICK_CONTACT_REQUEST = 0; public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { // When the user center presses, let them pick a contact. startSubActivity( new Intent(Intent.PICK_ACTION, Uri.parse("content://contacts")), PICK_CONTACT_REQUEST); return true; } return false; } protected void onActivityResult(int requestCode, int resultCode, String data, Bundle extras) { if (requestCode == PICK_CONTACT_REQUEST) { if (resultCode == RESULT_OK) { // A contact was picked. Here we will just display it // to the user. startActivity(new Intent(Intent.VIEW_ACTION, Uri.parse(data))); } } } }
当一个按键被按下时onKeyDown() 启动一个新的activity 。当新的activity 结束后onActivityResult() 会被调用。
4 . 启动保存持久状态
一般来说有两类持久状态需要activity来处理:类似于文档的共享数据(一般使用content provider存储在SQLite数据库中)和就像用户参数设定一样的内部状态。
对于content provider的数据,我们建议activity使用“编辑即发生”用户模型。就是说,用户所做的任何编辑都将立即生效而不要求任何进一步的确认。下面两条规则可以使支持这种模型成为一件简单的事情。
- 创建一个新文档的时候,立即为它创建文件或者后台数据库条目。举例来说,如果用户要写一封新邮件,当他们开始输入的时候马上创建一个新的数据库条目,所以即使他们输入以后进入别的activity,这封邮件也会在草稿箱中出现。
- 当activity的onPause()方法被调用时,它应该将任何用户所做修改向后台的content provider 或者文件提交。这可以确保即将运行的其他activity可以看到这些修改。你可能会使用更激进的方式来在你的activity生命周期中关键的时间点上提交数据:例如在启动一个新的activity之前、终止你的activity之前、当用户在输入域之间切换时,等等。(译者注:根据文档的其他部份,个人觉得启动新activity之前及终止当前activity之前进行保存的说法都值得商榷,具体位置仍可能是在onPause()中)
这个模型是为了避免用户在activity之间切换时数据丢失而设计的,同时允许系统在activity处于paused状态后任何时间都可以安全的 kill这个activity(因为其它地方可能需要系统资源)。注意这隐含着一个含义,即用户点击你activity的BACK键并不意味着“取消” ——它意味着保存他当前的内容并离开你的activity。Activity中取消编辑必须通过其他机制来提供,例如显式的提供"revert" 或 "undo"选项。
如果需要了解更多关于content providers的信息,参见content package。这是不同的activity之间如何调用和彼此之间传递数据的关键。
Activity同时提供了API来管理与activity相关联的内部持久状态。这可以用来记忆用户日历的首选初始显示(日期视图或者周视图)或者用户web浏览器的缺省主页这类信息。
Activity持久状态使用getPreferences(int)方法来管理,允许你取得和修改一系列与activity相关联的名称/取值对。如果要在应用的多个组件(activities,recivers,services,providers)之间共享参数,你可以使用底层方法 Context.getSharedPreferences()来获得存储在一个特定名称下的参数对象。(注意:在application packages之间不能共享设置数据 —— 如果要这么做的话你需要使用content provider)。
这里摘录了一段日历activity中的代码,用来在永久设定中保存用户首选的视图模式。
public class CalendarActivity extends Activity { ... static final int DAY_VIEW_MODE = 0; static final int WEEK_VIEW_MODE = 1; private SharedPreferences mPrefs; private int mCurViewMode; protected void onCreate(Bundle icicle) { super.onCreate(icicle); SharedPreferences mPrefs = getSharedPreferences(); mCurViewMode = mPrefs.getInt("view_mode" DAY_VIEW_MODE); } protected void onPause() { super.onPause(); SharedPreferences.Editor ed = mPrefs.edit(); ed.putInt("view_mode", mCurViewMode); ed.commit(); } }
5. 许可
你可以通过在 Activity 所属应用的 manifest 文件中对应的 <activity> 标签中进行声明来限制哪些应用可以启动此 Activity 。如果你进行了声明,其它应用需要在他们自己的 manifest 文件中声明对应的 <uses-permission> 元素(而且需要在安装时被授予许可:译者注 )才可以启动这个 activity 。
如果需要了解更多有关于一般安全机制和许可方面的信息可以参考 Security Model 。
6 . 进程生命周期
Android 系统会尽量久的保留应用进程。但是当内存降低时最终还是要移除旧的进程。就像Activity 生命周期 中描述的一样,移除哪个进程还是要取决于关联的用户与之交互的程度。一般来说,进程可以基于其中运行的activity 所处的生命周期而分成四种状态,下面将这些状态根据重要程度排列。系统会在kill 更重要的进程(第一个)之前首先kill 那些不那么重要的进程(最后一个)。
- 前景activity (处于屏幕最上方,用户与之交互的activity )被认为是最重要的。如果设备上的内存无法满足它的使用,Kill 此进程只能作为最后的手段。一般来说这个时候设备处于内存paging 状态,为了使用户界面保持响应才会发出这个kill 请求。
- 可见activity (一个对用户可见,但是不在前景的activity ,比如处在浮动对话框后)被认为是非常重要的,除非为了保证前景activity 运行,否则不会被kill 。
- 后台activity (一个对用户不可见,并处于paused 状态的activity )就不再重要了,所以当需要为其它前景的或者可见的activity 运行而回收内存时系统可以很安全的kill 它们。
- 空进程 是一个没有运行activity 或者其他应用组件(比如Service 或者IntentReceiver 类)的进程。当内存开始降低时系统很快就会kill 掉这些进程。因此当你要在activity 外运行任何的后台操作时,必须在IntentReceiver 或Service 的上下文环境中运行,这样系统才知道需要将你的进程保留而不是kill 。
有些时候Activity可能需要长时间运行一个操作,且它并不依赖于activity的生命周期而存在。例如一个照相机应用可能允许你将照片上传到 web站点。上传可能需要很长时间,在上传过程中应该允许用户离开这个应用。为了做到这一点,你的activity应该在上传时启动一个Service来执行此工作。这将使系统在你的进程上传数据的过程中能够恰当的区分它的优先级(认为此进程比其他不可见应用更重要),不管原来的activity的状态是 paused、stopped还是finished。
发表评论
-
如果在Eclipse中debug
2010-05-02 14:15 0最基本的操作是: 1, 首先在一个java文件中设断点,然后 ... -
How to download sourcecode of android with cygwin
2010-04-14 16:07 5107cygwin是一个在windows平台 ... -
TelephoneManager
2010-03-08 16:04 01. protected void onCreate(Bun ... -
eclipse c
2010-03-07 21:05 0Eclipse 除 了可以开发Java之外,还支持了许 ... -
android sdk安装
2010-02-02 23:37 34841.下载:http://developer.android.c ... -
google map my demo
2010-02-02 23:36 3193<uses-library android:name=& ... -
Toast
2010-02-02 23:35 14701. (1) public class ToastActi ... -
如何在MapView上画图
2010-02-02 23:34 1577http://ophone8.com/thread-4340- ... -
Service
2010-02-02 23:33 31481. Service生命周期 (1)Servic ... -
Notification
2010-02-02 23:33 19221. Notification构造器的参数 分别为: ... -
导航相关概念
2010-02-02 23:32 16951. Google Map的定位 (1)Goog ... -
PendingIntent和Intent
2010-02-02 23:28 9524Notification n = new Notificati ... -
Broadcast调用Service做的一个定时器
2010-02-02 23:28 37071. public class AlarmActivity ... -
Broadcast Receiver
2010-02-02 23:27 8690Broadcast Receiver用于接收并处理广播通知(b ... -
LayoutInflater
2010-02-02 23:27 21801一般来讲,我们用LayoutInflater做一件事:infl ... -
Android's Components 生命周期
2010-02-02 23:27 2158Android中,Component(activity、ser ... -
Intent
2010-01-20 10:51 011 public class MumActivity ex ... -
aidl
2010-01-05 11:24 30581. android进程之间如何通讯呢(在不同的进程中怎样传递 ... -
Gallery 画廊
2009-12-17 20:25 33701. images.xml <?xml ver ... -
Intent中的Flag参数
2009-12-16 18:12 6484Intent i = new Intent(B.this, C ...
相关推荐
Android 技术文档翻译项目是开源社区的一项重要贡献,它为中文用户提供了便捷访问和理解Android官方技术文档的途径。这个压缩包“android-tech-docs, Android官方技术文档翻译.zip”包含了“android-tech-docs-...
- **可见进程**:虽然没有在前台,但仍然可见,比如被另一个全屏Activity覆盖的Activity。这类进程也很少被杀死。 - **服务进程**:即使用户看不到,但执行服务的进程。系统会尽量保留,除非内存非常紧张。 - **...
- **活动管理器 (Activity Manager)**:管理应用程序的生命周期并提供公共的后台导航栈。 **3. 库文件 (Libraries)** - Android包含了大量C/C++库,供系统组件使用并通过Android应用框架向开发者开放。核心库包括...
本文将基于对Kotlin官方文档的深入理解和翻译,详细阐述Kotlin的关键语法和概念,帮助开发者快速上手并深入理解这门语言。 1. **基本语法** - **变量声明**:Kotlin支持`var`(可变)和`val`(不可变)变量,语法简洁...
这个部分翻译文档可能是对官方Android API文档的部分内容进行了中文翻译,帮助中国开发者更好地理解和使用Android API。 Android API分为多个级别,每个级别代表一个特定的Android版本,例如API级别29对应的是...
### Android中文翻译文档知识点概述 #### 一、Android简介 - **定义**:Android是一个针对移动设备设计的软件集合,主要包括操作系统、中间件以及一系列重要应用程序。它为开发者提供了使用Java语言开发Android应用...
包含翻译后的API文档:activiti-explorer-5.21.0-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.activiti:activiti-explorer:5.21.0; 标签:activiti、explorer、中文文档、jar包、java; 使用方法:解压翻译...
标题《A logical calculus of the ideas immanent in nervous activity》翻译成中文为《神经活动固有观念的逻辑演算》。这篇文章是神经网络领域的重要文献,发表于1943年,由沃伦·S·麦克卡洛克(Warren S. ...
Android官方中文翻译API文档是Android开发者的重要参考资料,它包含了Android应用程序接口(API)的详细解释,帮助开发者理解和使用Android系统提供的各种服务、组件和工具。这份离线中文版API文档对于国内开发者...
这份文档分为多个部分,其中包括了Android SDK中的关键元素,如Activity、Intent、BroadcastReceiver、Service以及各类View和Adapter等。在开发过程中,这些组件和概念构成了Android应用的基础框架。 首先,我们来...
《深入理解Android官方技术文档翻译》 Android技术文档是开发者们探索这个平台的宝贵资源,它详尽地阐述了Android系统的各个层面,包括系统架构、应用程序开发、UI设计、性能优化等多个方面。"android-tech-docs...
### API中文翻译与Android开发框架理解 #### 一、引言 随着移动互联网技术的快速发展,Android已成为全球最受欢迎的移动操作系统之一。对于开发者而言,掌握Android应用程序开发的基础知识至关重要。本文将详细介绍...
这份文档集合包含了Android 2.2(API级别8)及部分2.3(API级别9)的详细中文翻译,旨在帮助开发者理解和使用Android平台的各种功能和接口。 首先,Android API文档是开发者进行程序设计的重要参考资料,它详细地...
4. **Android中文翻译组——Android中文API合集.chm**: 这份文档可能是由热心的中文社区成员编译的API合集,可能包含了一些非官方但实用的API解释,或者是对官方文档的补充和扩展。这样的合集往往能提供一些社区...
《Android中文API合集》是为初学者提供的一份宝贵资源,由Android中文翻译组精心编译而成。这个合集旨在帮助那些对Android开发感兴趣但英语基础较弱的开发者更好地理解和应用Android API。尽管对于有一定基础的...
这份文档可能是对原版Android开发者文档的翻译或解读,旨在帮助中文开发者更好地理解和应用Android API。 Android API是Android系统的核心组成部分,它提供了丰富的接口和工具,供开发者构建各种类型的应用程序。...
而"好例子网_NFCForum-TS-NCI-2.0-170330 zh.pdf"则是该文档的中文版,由deepl翻译,为中文读者提供了便利。 Deepl是一款知名的机器翻译工具,其翻译质量相对较高,能帮助中文用户更轻松地理解NFC2.0协议的复杂概念...
所有参与翻译的人员在文档中都有列出,他们的共同努力使得这份中文版文档得以不断完善。文档遵循知识共享署名-非商业性使用-相同方式共享4.0国际许可协议,允许自由使用和分享,但需遵循相应条款。 总的来说,...
在这个文档中,你可以找到关于Activity、Intent、BroadcastReceiver、Service、ContentProvider等核心组件的详细信息,还有关于SQLite数据库、网络编程、多媒体支持、图形绘制等方面的API说明。 "AndroidAPI参考-...