Android学习--Activity

    一个Activity就是一个用户可与之交互的应用程序界面。一个应用程序通常由多个activity组成,通常会有一个activity被指定为"main"activity,用于展示应用第一次被启动时的界面。一个activity可以启动另一个activity,当新的activity被启动时,前一个activity会被系统放进"返回栈"中;返回栈遵循"后进先出"的原则,当用户按返回键时,当前activity会从堆栈中取出并销毁,之前的activity变得可见。

一、创建Activity

    *继承Activity
    要创建一个activity,必须继承Activity,并在其中实现Activity的一些生命周期方法,具体见下面"管理Activity生命周期"的部分。
    *定义用户界面
    Activity提供的用户界面,其实就是一个包含各种View的图层,每一个View在activity窗口中控制一个矩形区域。View主要包括两种:一种为"Widget",用于提供可见的View元素,如Button、TextView、CheckBox等;另一种为"Layout",用于提供界面布局模型,如LinearLayout、RelativeLayout等。Android提供了很多现成的View可供使用,当然也可以创建自己的Widget或Layout。
    定义Activity的UI有两种方法:1、在XML文件中定义,然后在setContentView()中传入此XML文件的ID进行使用;2、在代码中定义一个ViewGroup,然后在setContentView()传入此ViewGroup进行使用。
    *在manifest文件中声明此activity
    格式如下:

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

    在<activity>标签中还可以包含其他的属相,但只有android:name这个属性是必须有的。

    当创建新的工程时,Android SDK会自动生成一个如下格式的"根"activity:

<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>标签指示该activity是程序的主要入口,<category>标签指示此activity会被列入系统的应用程序启动器中。

二、启动Activity

    在Activity中启动另一个Activity,可以调用startActivity(),向该函数传入一个Intent,用于描述要启动什么样的activity。有两种情况:
    *在Intent中明确指出要启动的activity的名称,如:

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

    *在Intent中仅描述要启动的activity的action,没有具体指定哪一个activity
    在这种情况下,系统会为你选择合适的activity(该activity甚至可能来自另一个应用程序)。如果此时有多个activity满足要求,用户可以进行选择。例如,如果想让用户发送一条email消息,可以创建以下的Intent:


Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
startActivity(intent);
  在这种情形下,发送email的应用程序的相应的activity会被启动;当用户完成发送以后,你的activity会再次变得可见。


    需要接受返回结果时启动Activity
    这时,需要父activity调用startActivityForResult()来启动子activity(不再是调用startActivity())。为了得到返回的结果,还必须:1.在父activity中实现onActivityResult(),用来接受返回的结果;2.在子activity中实现setResult()方法,用于发送要返回的结果。
    例如,你可能想要用户选择一个联系人,然后对该联系人信息进行一些操作,示例代码如下:

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

三、关闭Activity

    注意:一般情况下,不需要显式的结束一个activity,Android系统负责管理activity的生命周期。当需要显式关闭一个activity时,可以调用如下两个方法:
    当需要显式关闭当前activity时,可以调用它的finish()方法;当需要显式的关闭之前开启的activity,可以调用finishActivity()方法。

四、管理Activity的生命周期

    实现生命周期方法
    一个activity本质上讲有三种存在状态:
    *Resumed
    activity位于屏幕前端并拥有用户焦点。
    *Paused
    被paused的activity没有用户焦点但仍然可见,也就是说,位于其上的另一个获得用户焦点的activity是透明的或是没有覆盖整个屏幕。位于paused状态的activity在内存极低时会被系统杀死。
    *Stopped
    被stopped的activity完全被另一个activity覆盖,变得不可见;但并没有被销毁,当系统需要回收内存时才可能把它销毁。

    当一个activity在不同的状态间转化时,会调用不同的生命周期方法。以下的代码展示了Activity所有的生命周期方法:

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

    注意:如上面的代码所示,在实现这些方法时,必须先调用父类的实现,然后才能进行其他的操作。
    通过实现以上的方法,可以监管Activity的三种类型的生命周期:
    *entire lifetime:oncreate()--->onDestroy()
    通常在onCreate()中设置全局状态(如定义layout),在onDestroy()中释放所有的资源。例如,如果activity在后台运行了一个线程用于从网络上下载数据,这个线程应该在onCreate()中创建,在onDestroy()销毁。
    *visible lifetime:onStart()--->onStop()
    在这段时间内,用户能够看到该activity;因此在这两个方法之间,程序应当一直持有向用户展示此activity所需的资源。例如,可以在onStart()注册一个BroadcastReceiver,用于监管可能会引起当前UI发生变化的一些因素;在onStop()中注销该BroadcastReceiver。
    *foreground lifetime:onResume()--->onPause()
    在这段时间内,该activity拥有用户焦点。在整个生命周期中,这两个方法可能会被频繁的调用,因此不应该在这两个方法中进行繁重的操作。

                                                    Figure 1. The activity lifecycle.
    下表是对各个生命周期方法的详细描述:
    Table 1. A summary of the activity lifecycle's callback methods.

Method Description Killable after? Next
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, and so on. This method is passed a Bundle object containing the activity's previous state, if that state was captured (see Saving Activity State, later).

Always followed by onStart().

No onStart()
  onRestart() Called after the activity has been stopped, just prior to it being started again.

Always followed by onStart()

No onStart()
onStart() Called just before the activity becomes visible to the user.

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

No onResume() 
or
onStop()
  onResume() Called just before the activity starts interacting with the user. At this point the activity is at the top of the activity stack, with user input going to it.

Always followed by onPause().

No onPause()
onPause() Called when the system is about to start resuming another activity. This method is typically used to commit unsaved changes to persistent data, stop animations and other things that may be consuming CPU, and so on. It should do whatever it does very quickly, because the next activity will not be resumed until it returns.

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

Yes onResume() 
or
onStop()
onStop() Called when the activity is no longer visible to the user. This may happen because it is being destroyed, or because another activity (either an existing one or a new one) has been resumed and is covering it.

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

Yes onRestart()
or
onDestroy()
onDestroy() Called before the activity is destroyed. This is the final call that the activity will receive. It could be called 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 theisFinishing() method. Yes nothing
    第三列是指当周期方法返回后,该activity是否可能被系统杀死;onPause()、onStop()、onDestroy()三个方法被标记为"yes"。一旦activity被创建,这三个方法中,onPause()是第一个会被调用的方法;如果在onPause()返回后,系统在紧急状态下要回收内存,该activity可能会被直接销毁,此时onStop()和onDestroy()两个方法有可能不会被调用,因此对于一些关键性数据,应该在onPause()中进行保存。(但是,因为在activity整个生命周期中onPause()方法会被频繁的调用,应该尽量减少在其中进行的保存操作,以免影响用户体验。)

    保存Activity的状态
    当Activity被paused或stoped时,该Activity对象仍存在于内存中,它的状态和所有成员的信息被保存了起来,因此当此Activity回到前台时可以恢复原貌。然而,如果此时系统为了回收内存将该Activity销毁,当用户再试图返回此Activity时,系统会重新生成一个该Activity的对象,此时如果想让用户看到的还是原来的Activity的样子,就需要实现回调方法onSaveInstanceState(),在此方法中保存被销毁前的Activity的信息。
    系统会在Activity将要被销毁时调用onSaveInstanceState()方法(在onStop之前、甚至可能在onPause()之前调用)。系统向该方法传入一个Bundle;当前Activity被销毁后、当用户再次试图返回此Activity时,该Bundle对象会被同时传入此Activity的onCreate()和onRestoreInstanceState()两个方法中。因此,可以在此Bundle对象中保存Activity的状态信息,然后在onCreate()或onRestoreInstanceState()提取出来,以恢复原来Activity的状态。(当Activity第一次被创建时,Bundle中没有任何信息,是null。)
    注意:onSaveInstanceState()并不是每次Activity被销毁前都会被调用,因为有些情况下是不需要保存Activity的状态的(如,当用户按Back按钮离开当前Activity时,此时用户明确要关闭当前Activity,不想再返回到该Activity)。
    另外,Activity类有对onSaveInstanceState()的默认实现,即使你没有实现自己的onSaveInstanceState(),Activity中的一些状态也会被该默认实现保存。典型的,默认实现会调用布局中的每一个View对应的onSaveInstanceState(),各个View自己的onSaveInstanceState()会提供他们需要保存的信息。Android中的几乎每个widget(可见的View)都恰当的实现了onSaveInstanceState()方法,因此在UI中任何可见可改变都会被自动保存,在Activity被再次创建时被恢复。例如,EditText保存用户输入的任何文字,CheckBox保存它是否被选择。但是,要让系统自动保存widget的状态,必须完成一项工作:为每一个widget提供一个ID(系统是不会保存没有ID的widget的状态)。因为该方法的默认实现保存了UI的状态信息,因此,如果要复写该方法以保存额外的信息,应该先调用父类对该方法的实现,然后再进行保存额外的信息的操作(实现onRestoreInstanceState()同样如此,也要先调用父类实现,再进行其他工作)。
    注意:因为onSaveInstanceState()的调用是没有保障的,应该只用它来保存一些临时的状态信息;如果要保存永久型数据(比如要保存在数据库中的数据),应该在onPause()方法中进行。
   
                         Figure 2. The two ways in which an activity returns to user focus with its state intact


    当配置变化时如何处理
    详见官方文档App Resources中关于"Handling Runtime Changes"的部分。


    其他
    Activity A 启动Activity B 时,它们的生命周期方法调用顺序如下:
    1、A 的onPause()方法被执行;
    2、B 的onCreate()、onStart()、onResume()依次被执行(现在B拥有用户焦点);
    3、如果此时A不可见,它的onStop()方法会被执行。
    这种可预见的调用顺序,对于从一个Activity向另一个Activity传递信息是有帮助的。例如,如果想让第一个Activity向数据库中存储某些数据、以便第二个Activity能够读取这些数据,应该在第一个Activity的onPause()方法中将数据写入数据库(而不是在onStop()中)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值