Android API Guides---Activities

来源:互联网 发布:淘宝域名怎么填 编辑:程序博客网 时间:2024/04/30 11:58
Activity是一个应用程序组件,提供了用户可以为了做一些事情,如拨打电话,拍照,发送电子邮件,或查看地图进行交互的屏幕。每个活动都有一个窗口,在其中绘制它的用户界面。窗口典型地充满屏幕,也可以是小于屏幕和浮在其它窗口之上。


一个应用程序通常由被松散地结合到彼此的多个活动。通常情况下,在应用程序中一个活动被指定为“主”的活性,这是启动首次应用时呈现给用户。然后,每个活动可以以执行不同的操作启动另一个活动。每一个新的活动开始时间,先前的活动停止了,但该系统保持在一个叠层(“回堆叠”)的活性。当一个新的活动启动时,它被压入堆栈回来,并采取用户关注的焦点。后退堆栈遵守基本的“后进先出”的堆栈机制,这样,当用户与当前活动的完成,按后退按钮,它从栈中弹出(和销毁)和以前的活动恢复。 (背面堆栈更多的任务和返回堆栈中讨论。)


当活动停止,因为一个新的活动启动时,它被通知通过活动的生命周期回调方法这种变化的状态。有几种回调方法的活动可能会收到,由于其改变状态系统是否创造它,阻止它,恢复它,或者毁坏它和每个回调为您提供执行是合适的具体工作机会该状态更改。例如,停止时,你的活动应当释放任何大的物体,如网络或数据库连接。当活动恢复,则可以重新获取必要的资源,并恢复被中断的行动。这些状态转换是活动的生命周期的所有部分。


本文档的其余部分将讨论如何建立和使用活动,包括活动的生命周期是如何工作的完整讨论的基础知识,这样你就可以妥善管理各种活动状态之间的转换。


创建Activity


要创建活动,必须创建活动的一个子类(或它的一个子类存在的)。在子类中,你需要实现回调方法,该系统调用时,正在创建活动时,如生命周期,不同状态之间的转换活动,停止,重新开始,或销毁。两个最重要的回调方法是:


onCreate()
您必须实现此方法。创建活动时,系统调用此。在您的实现,你应该初始化活动的重要组成部分。最重要的是,这是你必须调用的setContentView()来定义该活动的用户界面的布局。
onPause()
系统调用此方法,因为该用户离开你的活动(尽管它并不总是意味着该活动被销毁)的第一个迹象。这通常是你应该犯应当超越当前用户会话被持久化(因为用户可能不会回来)的任何变化。
还有,你应该以提供活动之间的流体用户体验和处理突发interuptions导致您的活动必须停止,甚至销毁使用其他几个生命周期回调方法。所有的生命周期回调方法将在稍后讨论,在有关管理活动生命周期中的一节。


实现用户接口


为活动的用户界面是由View类派生视图对象的层次结构提供。每个视图控制活动的窗口内的特定的矩形空间,并且可以响应用户交互。例如,一个视图可以是一个按钮,当用户触摸它发起一个动作。


Android提供了多种方法,您可以用它来设计和组织布局现成的看法。 “部件”是次提供用于在屏幕的可视(和交互)元素,诸如按钮,文本字段,复选框,或者仅仅一个图像。 “布局”是如线性布局,网格布局,或相对布局从一个ViewGroup提供用于其子视图,独特的布局模型得出的意见。您还可以继承视图和类的ViewGroup(或现有的子类)来创建自己的部件和布局,并将它们应用到你的活动布局。


定义使用视图布局最常用的方法是保存在您的应用程序资源的XML布局文件。通过这种方式,可以从定义活动行为的源代码分开维护你的用户界面的设计。您可以设置布局的UI您使用的setContentView)活动(,传递的资源ID布局。不过,你也可以创建你的活动代码的新意见,并插入新浏览到一个ViewGroup中建立一个视图层次,然后通过将根ViewGroup中来的setContentView使用布局()。


有关创建用户界面的信息,请参阅用户界面文档。


声明的Activity清单


您必须声明清单文件中的活动,以便它是对系统进行访问。要声明你的活动,打开你的manifest文件并添加<活动>元素作为<application>元素的子项。例如:


<manifest ... >  <application ... >      <activity android:name=".ExampleActivity" />      ...  </application ... >  ...</manifest >

还有一些其他的属性,这些属性可以对这个元素来定义,如标签的活动,为活动的图标,或者一个主题样式活动的UI特性。 Android的:name属性是唯一必需的属性,它指定活动的类名。一旦你发布你的应用程序时,你不应该改变这个名字,因为如果你这样做,你可能会打破一些功能,如应用程序快捷方式(阅读博客文章,事情可以不改变)。


请参阅有关清单声明你的活动的更多信息<activity>
元素引用。


使用意图过滤器


一个<Activity>元素还可以指定元素为如何申报其他应用程序组件可以激活它的各种意图过滤器,使用<意图过滤器>。


当您创建使用Android SDK工具新的应用程序,这是为您创建存根活动自动包括声明该活动的意图过滤器响应“主”的行动,应放在“启动”的范畴。这样做的目的过滤器看起来是这样的:


<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>元素指定此活动应该在系统中的应用程序启动上市(允许用户推出这项活动)。


如果您打算让您的应用程序是自包含的,而不是允许其他应用程序来激活它的活动,那么你不需要任何其他的意图过滤器。只有一个活动应该有“主”行动和“发射”的范畴,如前面的示例所示。你不想提供给其他应用程序的活动应该没有意图过滤器,您可以使用显式意图自己启动它们(如在下一节讨论)。


不过,如果你希望你的活动,以响应从其他应用程序(和你自己)提供隐含的意图,那么你必须为你的活动定义额外的意图过滤器。对于每种类型要回应的意图,你必须包括<意图过滤器>,其中包括一个<action>元素和可选,一个<category>元素和/或<data>元素。这些元素指定意图,你的活动可以响应的类型。


有关你的活动如何为响应意图的更多信息,请参阅意图和意图过滤器的文件。


启动一个Activity


你可以通过调用startActivity(),传递给它描述要启动该活动的意图开始另一个活动。这样做的目的不是指定要启动的具体活动或描述要执行的操作类型(和系统为您选择合适的活动,甚至可以从不同的应用程序)。意图还可以携带少量的数据由该开始的活动中使用。


当自己的应用程序中工作,你会经常需要简单地启动一个已知的活动。您可以通过创建一个明确定义要启动该活动,使用类名的意图这样做。例如,这里有一个活动是如何启动另一个名为活动SignInActivity:


ntent intent = new Intent(this, SignInActivity.class);startActivity(intent);

然而,你的应用程序也可能需要执行一些动作,如发送电子邮件,短信或状态更新,使用从你的活动数据。在这种情况下,您的应用程序可能没有自己的活动来执行这样的动作,这样你就可以利用,而不是由设备上的其他应用程序,它可以为您执行的操作提供的活动。这是意图是真正有价值的,你可以创建一个描述要执行的操作,系统从另一个应用程序启动相应的活动的意图。如果有,可以处理的意图多个活动,则用户可以选择使用哪一个。例如,如果你想允许用户发送电子邮件,您可以创建以下目的:


Intent intent = new Intent(Intent.ACTION_SEND);intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);startActivity(intent);

该EXTRA_EMAIL额外添加到意图是该电子邮件应该发送电子邮件地址的字符串数组。当电子邮件应用程序响应这个意图,它读取额外提供的字符串数组,并把它们在电子邮件撰写表格的“到”字段中。在这种情况下,电子邮件应用程序的活动开始,并在用户完成时,你的活动恢复。


启动一个活动结果


有时候,你可能需要从你开始活动收到结果。在这种情况下,启动通过调用startActivityForResult(活性)(代替startActivity())。要再从后续活动得到的结果,实现的onActivityResult()回调方法。当随后的活动完成后,它的意图,你的onActivityResult()方法返回一个结果。


例如,也许你希望用户来接他们的联系人之一,因此你的活动可以做一些与该联系人的信息。这里是你如何能创建这样的意图和处理的结果:


private void pickContact() {    // Create an intent to "pick" a contact, as defined by the content provider URI    Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);    startActivityForResult(intent, PICK_CONTACT_REQUEST);}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {    // If the request went well (OK) and the request was PICK_CONTACT_REQUEST    if (resultCode == Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST) {        // Perform a query to the contact's content provider for the contact's name        Cursor cursor = getContentResolver().query(data.getData(),        new String[] {Contacts.DISPLAY_NAME}, null, null, null);        if (cursor.moveToFirst()) { // True if the cursor is not empty            int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME);            String name = cursor.getString(columnIndex);            // Do something with the selected contact's name...        }    }}

这个例子显示,你应该在你的onActivityResult()方法以处理活动的结果使用的基本逻辑。第一个条件检查该请求是否成功-如果是,则发送resultCode将是请求向其中已知在这种情况下,requestCode()与startActivityForResult发送的第二参数相匹配这一结果是响应RESULT_OK和是否。从那里,将码处理通过查询一个Intent(数据参数)返回的数据的活动的结果。


什么情况是,一个ContentResolver的执行对内容提供商,它返回一个游标,允许读取查询数据的查询。欲了解更多信息,请参阅内容提供商的文档。


有关使用意图的更多信息,请参阅意图和意图过滤器的文件。


关闭一个活动


你可以通过调用其完成()方法关闭的活动。您也可以关闭您以前通过调用finishActivity开始独立的活动()。


注:在大多数情况下,你应该没有明确结束使用这些方法的活动。如同在活动周期下一节讨论的,Android系统为您管理活动的生活,所以你不需要来完成自己的活动。调用这些方法可以在预期的用户体验产生不利影响,应仅用于当你绝对不希望用户返回到活动的此实例。


管理活动的生命周期


通过实施回调方法管理你的活动的生命周期是发展强大和灵活的应用至关重要。活动的生命周期直接影响到它与其他的活动,它的任务和回堆栈关联。


活性可以在基本上三种状态存在:


恢复
活性是在屏幕的前景中,并具有用户集中。 (该状态也有时被称为“运行”)。
已暂停
另一项活动是在前台和具有焦点,但是这一次仍是可见的。即,另一个活动是在这一个的顶部可见和活动是部分透明或不覆盖整个屏幕。一个暂停的activity是完全活着(Activity对象保留在内存中,它保持所有的状态和成员信息,并保持连接到窗口管理器),但可以通过该系统在非常低内存情况下被杀死。
已停止
活动完全是由另一活动遮蔽(即现在的活动是在“背景”)。停止的活动也仍然活着(Activity对象保留在内存中,它保持所有的状态和成员信息,但没有连接到窗口管理器)。然而,它不再对用户可见,它可以由系统时别处需要存储器被杀死。
如果活动被暂停或停止,该系统可以通过要求它结束(调用finish()方法)从内存中删除它,或者干脆杀死它的进程。当活动再次打开(被完成或死亡后),它必须创建全部结束。


实施生命周期回调


当一个活动的转换进入和离开的不同状态的以上描述,但是通过各种回调方法通知。所有的回调方法是可以重写做适当的工作,当你的活动状态变化挂钩。下面的骨骼活动包括每个基本生命周期方法:


public class ExampleActivity extends Activity {    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        // The activity is being created.    }    @Override    protected void onStart() {        super.onStart();        // The activity is about to become visible.    }    @Override    protected void onResume() {        super.onResume();        // The activity has become visible (it is now "resumed").    }    @Override    protected void onPause() {        super.onPause();        // Another activity is taking focus (this activity is about to be "paused").    }    @Override    protected void onStop() {        super.onStop();        // The activity is no longer visible (it is now "stopped")    }    @Override    protected void onDestroy() {        super.onDestroy();        // The activity is about to be destroyed.    }}

注意:您执行这些生命周期方法必须始终调用父类的实现做任何工作之前,如上面的例子中。


两者合计,这些方法定义了一个活动的整个生命周期。通过实施这些方法,你可以监视活动的生命周期三个嵌套循环:


活动的整个生命周期发生在调用的onCreate()和调用的onDestroy()之间。您的活动应该执行的onCreate(的“全局”状态设置(如定义布局)),并释放所有剩余资源的onDestroy()。例如,如果你的活动在后台从网络下载数据运行一个线程,这也许可以在OnCreate()中的线程,然后在停止的onDestroy()线程。
活动的可视生命周期发生在呼叫在onStart()和调用的onStop()之间。在此期间,用户可在屏幕上看到的活性和与它进行交互。例如,的onStop()当一个新的活动开始和这一个不再可见被调用。这两种方法之间,可以保持所需要以显示活动给用户的资源。例如,您可以注册在onStart一个BroadcastReceiver()来监视影响您的用户界面的变化,并注销它的onStop()当用户不再能看到你什么显示。该活动的整个生命周期期间,系统可能调用调用onStart()和的onStop()多次,作为是可见和隐藏到用户之间的活动交替。
一个活动的前景生命周期发生在调用onResume()和调用的onPause()之间。在此期间,该活动是在屏幕上的所有其他活动的前面,并具有用户输入的焦点。一个活动可以频繁转换进出前景,例如,在onPause()被调用时,该设备进入睡眠状态或将出现一个对话框时。因为该状态通常可以转换,在这两种方法中的代码应以避免慢过渡,使用户的等待相当轻巧。

图1说明了这些环和一个活动可能采取状态之间的路径。矩形代表可以实现在活动状态之间的转换来执行操作的回调方法。








图1.活动的生命周期。


同样的生命周期回调方法列于表1,其中描述了各自的回调方法的细节,并找到活动的整体生命周期中的每个人,包括回调方法完成后系统是否能杀死活动。


表1的活性生命周期的回调方法的摘要。
方法说明后Killable?下一个
OnCreate()中第一次创建活动时调用。这是你应该做的所有的正常静态设置的 - 创建视图,数据绑定到列表,等等。这种方法是通过包含活动的以前的状态一个Bundle对象,如果那个状态被抓获(见保存活动状态,更高版本)。
总是跟随在onStart()。
没有调用onStart()
    onRestart()调用该活动已停止后,只是在它之前被再次启动。
总是跟随在onStart()
没有调用onStart()
在onStart()只在活动之前调用变得对用户可见。
其次是onResume()如果活动来到前台,或的onStop(),如果它被隐藏。
否onResume()
要么
的onStop()
    onResume()只在活动之前调用开始与用户交互。在这一点上的活动是在活动堆栈的顶部,与用户输入要它。
总是跟着的onPause()。
没有的onPause()
的onPause()当系统要开始恢复另一个活动时调用。此方法通常用于提交到持久性数据未保存的更改,停止动画和可消耗CPU等其他东西。它应该尽一切可能很快确实,因为接下来的活动将不会被恢复,直到它返回。
接着或者通过onResume()如果活动返回到前面,或通过的onStop()如果它变得对用户不可见。
是onResume()
要么
的onStop()
的onStop()当活动不再对用户可见调用。这种情况可能发生,因为它被销毁,或者是因为其他活动(无论是现有的或新的)已经恢复并且覆盖它。
其次无论是onRestart()如果活动是回来与用户交互,或通过的onDestroy()如果​​此活动是要离开。
是onRestart()
要么
的onDestroy()
的onDestroy()在activity被销毁之前调用。这是该活动将获得最后的通话。它可以被称为是因为活性被整理(有人称为光洁度()在其上),或者是因为该系统暂时破坏活性的此实例以节省空间。你可以这两个方案与isFinishing()方法区分。是什么
列标有“后Killable?”指示系统是否能杀死托管在方法返回后任何时间的活动的过程中,不执行活动的代码的另一行。三种方法被标记为“是”:(的onPause(),的onStop(),和的onDestroy())。因为的onPause()是第三,一旦被创建的活性,的onPause()是有保证被调用的过程可以被杀死,如果之前,系统必须在紧急恢复存储器,然后的onStop最后()的方法和的onDestroy()可能不被调用。因此,你应该使用的onPause()写关键的持久性数据(如用户编辑)到存储。然而,你应该是有选择性的什么信息必须在onPause()过程中被保留,因为这种方法阻止任何封锁程序过渡到下一个活动并降低用户体验。


被标记方法“否”,在Killable柱保护托管从它们被称为瞬间被杀死活性的过程。因此,一个活动是killable从时间的onPause()返回到时间onResume()被调用。它不会再次killable到的onPause()再次调用并返回。


注意:这不是技术上“killable”通过这个定义在表1所述的活动可能仍然被杀死的系统,但在没有其他办法,将只发生在极端的情况下。当可能被杀死的活动的进程和线程文件中详细讨论。


节能活动状态


引入到管理活动的生命周期短暂地提到,当活动被暂停或停止,该活动的状态被保留。因为活动对象仍然在内存或持有时暂停停所有关于其成员和当前状态的信息还活着这是真的。因此,在活动范围内所做的任何修改,用户被保留,这样,当活动返回到前景(当它“恢复”)时,这些更改仍然存在。


然而,当系统破坏以回收存储器的活动,活动对象被破坏,所以其状态不变系统不能简单地恢复它。相反,如果用户导航回到它的系统必须重新创建活动对象。然而,用户不知道该系统破坏了活性和重新创建它,并且因此,可能是期望的活性是完全原样。在这种情况下,可以确保通过实施额外的回调方法,可以让您保存您的活动状态的信息保留有关的活动状态的重要信息:的onSaveInstanceState()。


该系统的onSaveInstanceState调用()使活动容易受到破坏之前。该系统通过这种方法一个Bundle中,你可以节省约活动的名称 - 值对的状态信息,使用方法,如putString()和putInt()。然后,如果系统杀死你的应用程序和用户导航回到您活动,该系统重新创建活动,并传递捆绑两者的onCreate()和onRestoreInstanceState()。使用这两种方法,您可以从中提取包你保存的状态并恢复活动状态。如果没有状态信息来恢复,则包传递给你为空(这是当在第一次创建活动的情况下)。




图2.两种方式的活动返回给用户关注的焦点,其状态完好:要么活性被破坏,然后重新创建活动必须恢复以前保存的状态,或活动停止,然后重新开始,活动状态保持完整。


注意:有没有保证的onSaveInstanceState()您的活动被销毁之前会被调用,因为在它没有必要保存状态(当用户离开使用后退按钮,您的活动,如情况下,由于用户被显式关闭活动)。如果系统的onSaveInstanceState调用(),它这样做的onStop()之前和可能的onPause()之前。


但是,即使你什么也不做,没有实现的onSaveInstanceState(),一些活动状态是由Activity类的的的onSaveInstanceState默认实现()恢复。具体来说,默认的实现要求布局,它允许每个视图提供其自身应保存的信息,每次查看相应的onSaveInstanceState()方法。几乎是在Android框架部件的每实现此方法,适当的,这样的UI任何可见的更改会自动保存,当你的活动重新恢复。例如,小部件的EditText节省用户输入的任何文字和复选框控件节省不管是检查还是不行。你所需要的唯一工作是提供一个唯一的ID(用android:id属性),您要保存其状态每个插件。如果一个部件没有一个ID,则系统无法保存其状态。


saveEnabled属性为“假”,或通过调用setSaveEnabled()方法:您还可以明确的通过设置了android保存其状态停在你的布局视图。通常情况下,你不应该禁用此,但你可能,如果你想以不同的恢复活动UI的状态。
的onSaveInstanceState虽然()的默认实现节省您的活动的UI有用的信息,你可能仍然需要重写,以节省更多的信息。例如,您可能需要保存活动的生命过程中更改成员值(这可能关联到UI中恢复的价值,但持有这些UI值的成员不会被恢复,默认情况下)。


的onSaveInstanceState因为()的默认实现有助于保存UI的状态,如果你覆盖的方法,以节省额外的状态信息,您可以随时拨打)做任何工作之前超类实现的的onSaveInstanceState(。同样的,你也应该调用超类实现onRestoreInstanceState(),如果你覆盖它,所以默认的实现可以恢复视图状态。


注意:由于的onSaveInstanceState()不能保证被调用,你应该只用它来记录活动(用户界面)的状态 - 你永远不应该用它来存储持久性数据的临时状态。相反,你应该使用的onPause()来存储持久性数据(如应保存到数据库中的数据),当用户离开该活动。


测试你的应用程序,以恢复其状态的能力的一个好方法是简单地旋转装置,使屏幕的方向变化。当屏幕方向改变时,系统会破坏并重新创建,以便应用替代资源,可能是可用于新的屏幕配置的活动。仅仅出于这个原因,这是非常重要的,你的活动完全恢复其状态,当它被重建,因为用户在使用应用程序定期旋转屏幕。


处理配置更改


有些设备配置可以在运行时改变(如屏幕方向,键盘可用性,和语言)。当这种变化发生时,Android的再现了运行的活动(系统调用的onDestroy(),然后立即调用的onCreate())。此行为旨在帮助您的应用程序自动重新加载与您所提供(如不同的屏幕方向和大小不同的布局)的替代资源,您的应用程序适应新的配置。


如果你正确地设计您的活动来处理重新启动由于屏幕方向变化和恢复上述的活动状态,应用程序将更加适应在活动周期等突发事件。


处理这样一个重启的最好方法是保存和恢复您的活动的onSaveInstanceState使用()和onRestoreInstanceState()状态(或的onCreate()),在上一节中讨论。


有关发生在运行时,你如何处理它们的配置更改的更多信息,请阅读指导,以处理运行时更改。


活动协调


当一个活动启动另一个,他们都经历了生命周期的转变。第一项活动暂停和停止(不过,如果它仍然在后台可见它不会停止),而创建其他活动。如果这些活动分享保存在光盘上的数据或其他地方,了解所创建的第二个之前的第一个活动是没有完全停止是很重要的。相反,开始第二个的方法与停止第一一个的过程重叠。


生命周期回调的顺序被很好地定义,特别是当这两种活动都在同一个过程,一个在开始其他。这里的操作时,活动A开始Acivity乙发生的顺序:


活动A的的onPause()方法执行。
活动B的onCreate(),在onStart()和onResume()方法执行顺序。 (活动B现在用户关注的焦点。)
然后,如果活动A在屏幕上不再可见,它的onStop()方法执行。
这种可预见的生命周期回调的顺序可以让你从一个活动到另一个管理信息的转变。例如,如果在第一个活动停止,这样下面的活动可以读取它必须写入到数据库中,那么你应该在onPause期间写入数据库(),而不是过程的onStop()。
0 0
原创粉丝点击