Activtiy使用与理解

来源:互联网 发布:2016国内旅游数据 编辑:程序博客网 时间:2024/05/19 07:07

Activity的使用与理解

Activity是一个应用程序组件,它提供了一个可以和用户交互的屏幕,以便进行一些操作,比如打电话、拍照、发送电子邮件或查看地图。一个应用程序一般有一个”Main”Activity。当应用程序启动就会显示它。每个Activity都有一个窗口,用来画出它的用户界面。窗口通常会填充屏幕,但可能比屏幕小,并在其他窗口上浮动。 一个应用程序中可以包括多个Activity,他们可以通过Intent之间进行相互的启动和传递数据。

当一个Activity启动时,老的Activity就会被stop并放入到系统的一个后进先出的堆栈中,新启动的Activity就会进到栈顶并获得和用户交互的焦点,然而,当用户点击back按钮时,当前交互的Activity就会被销毁,并且堆栈中先前的Activity将会被resume并获得与用户交互的焦点。

创建一个Activity 示例代码:

public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        // 显示启动        Intent intent = new Intent(this, SignInActivity.class);        startActivity(intent);        // 隐式启动        Intent intent = new Intent(Intent.ACTION_SEND);        intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);        startActivity(intent);    }}


<activity android:name=".ExampleActivity"/>   // 显示启动


    <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>

创建一个有结果返回的Activity示例代码:


    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);    }    @Override    protected 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...            }        }    }

在使用startActvitiyForResult()方法启动Activity时,被启动的Activity可以调用setResult()方法返回结果到onActivityResult()方法上,同时,Activity被finish时结果才会返回。

可以使用finish()销毁Activity,或者在onActivityResult()方法中采用finishActivity()关闭startActivityForResult方法启动的Activity。

Activity在大多数情况下,您不应该使用这些方法显式地完成一个Activity。正如下面一节关于Activity生命周期的讨论,Android系统为您管理一个Activity的生命周期,因此您不需要完成您自己的Activity。调用这些方法可能会对预期的用户体验产生负面影响,只有当您绝对不想让用户返回到该Activity的实例时,才应该使用这些方法。


Activity的生命周期


Activity生命周期

这些生命周期方法的实现必须在执行任何工作之前调用父类的实现,如上述示例所示。

Method

Description

Killable after?

Next

onCeate()

在第一次创建Activity时调用,这是您应该执行所有常规静态设置的地方—创建视图,将数据绑定到列表,等等。该方法的参数是一个包含活动前状态的Bundle对象,如果Activity销毁前的状态被保存,就可以在这里获得。

No

onStart()

onRestart()

这个Activity已经停止,就在它再次被重新启动之前调用。

No

onStart()

onStart()

在Activity可见之前调用。

No

onResume()

onResume()

Activity开始与用户交互之前调用,此时,Activity处于Activity堆栈的顶部。

No

onPause()

onPause()

当系统即将开始恢复另一时,调用它。这种方法通常用于将未保存的更改提交到持久数据、停止动画和其他可能会消耗CPU的事情上,等等。

Yes

onStop()或onResume()

onStop()

当Activity对用户不可见时,调用它。这可能是因为它正在被destroy,或者因为另一个活动(一个已经存在的或者一个新的)已经被恢复并且正在覆盖它。

Yes

onDestroy或onRestart()

onDestroy()

在Activity被Destroy之前这是Activity接收到的最后一个调用,可以通过调用finish方法或者系统需要回收空间的时候销毁Activity。可以通用isFinish()方法判断是这两种销毁类型的哪一种。

Yes

noting


Activity的生命周期管理:

在上述表中,onPause()、onStop以及onDestroy的Killable after是Yes,表示在调用完该方法后,系统可以在紧急情况下回收内存并杀死Activity。而onPause方法是这三个回调函数的第一个,所以在onPause方法中要把一些持久化的数据进行保存,不然,后续的onStop和onDestroy方法可能不会被调用。

一个Activity在onPause调用之后到onResume方法调用之前是可以被杀的,但是当Activity正在进行交互,那必须在onPause方法之后才可以被系统回收。

根据表1中定义,不能被“杀死”的Activity可能仍然会被系统杀死,但是只有在极端情况下,当没有其他资源时,才会发生这种行为。

Activity生命周期回调顺序是很好定义的,特别是当两个Activity在同一个进程中,一个开启另一个。 以下是Acivity A启动AcivityB时发生的操作顺序:

1、Activity A's onPause();

2、Activity B's onCreate(), onStart(), andonResume()依次执行;

3、如果Activity A在屏幕上不再可见,那么它的onStop()方法就会执行。

 

保存Activity运行状态

在管理Activity生命周期的简介中,简要地提到,当一个Activity被暂停或停止时,Activity的状态将被保留。这是正确的,因为Activity对象在被暂停或停止时仍然保存在内存中——关于其成员和当前状态的所有信息仍然存在。因此,用户在Activity中所做的任何更改都被保留,以便当Activity返回到前台时(当它“恢复”)时,这些更改仍然存在。但是,当系统为了恢复内存而销毁Activity时,Activity对象被销毁,所以系统不能简单地恢复它的状态。 相反,如果用户导航到该对象,系统必须重新创建Activity对象。 然而,用户不知道系统销毁了Activity并重新创建了它,因此,可能期望Activity是完全一样的。 在这种情况下,您可以通过实现一个额外的回调方法来确保有关Activity状态的重要信息,从而可以保存有关Activity状态的信息:onSaveInstanceState()。  

1、在Activity被销毁之前,系统调用onSaveInstanceState()。 系统将此方法传递给一个Bundle,您可以使用putString()和putInt()等方法,将关于Activity的状态信息作为键-值对保存。 然后,如果系统杀死您的应用进程,并且用户导航回您的Activity,则系统将重新创建该Activity,并将Bundle传递给onCreate()和onRestoreInstanceState()。 使用这些方法之一,您可以从Bundle中提取保存的状态并恢复Activity状态。 如果没有要恢复的状态信息,则传递给您的Bundle为null(这是首次创建Activity时的情况)。

2、onSaveInstanceState()不是每次都会执行,当用户点击back按钮的时候就不会保存。这是因为用户主动退出销毁Activity的,当onSaveInstanceState()被调用时,它一般在onStop()方法之前被调用,也有可能在onPause()方法之前被调用。

3、onSaveInstanceState()在重写时一定要调用父类的该方法,即使没有重写该方法,默认的该方法也会把一些View控件,比如:编辑框中的内容和选择框的选择项进行保存。但是这个需要你为每个控件在布局文件定义的时候给它们指定一个android:id。这样Activity在重新创建的时候就会自动恢复这些控件的内容。

4、但是由于onSaveInstanceState()不一定会被调用,因此你只能在此方法中保存短暂存在的数据。可以在onPause()方法中,把一些持久化的数据保存到数据库中。

5、onSaveInstanceState()的默认实现保存了关于Activity UI的有用信息,但是仍然需要覆盖它以保存额外的信息。例如,您可能需要保存在Activity生命期间更改的成员值(这可能与UI中恢复的值相关联,但是保留那些UI值的成员在默认情况下不会恢复)。比如,通过setSaveEnabled()方法修改的enable属性。

6、在一些配置信息改变的时,比如屏幕横竖切换,键盘可用性和语言的切换都会导致Activity销毁并重新创建,这样的话就需要对Activity状态进行保存,给用户带来更好的体验。




原创粉丝点击