Activity 初步(大部分翻译自SDK)

(内容:如何创建、使用activity; activity生命周期。)

Activity

Activity 是一个为用户提供交互接口的组件,每个activity都会有一个window来显示自己的界面。 应用可以由多个互相“弱关联”的activity组成,activity可以启动另外一个activity, 有activity启动的时候,当前的就会被暂停,系统把被暂停的activity存储在一个FILO(先进后出)的栈中,当用户点击“back”时,位于栈顶的activity就会重新被显示出来。

Activity 提供一系列的接口,在生命周期运行到特定的阶段时会通知相应的接口,用户在这些回调接口中做当前阶段的处理。例如,在create时初始化应用的资源,stop时作资源的释放。

1 创建Activity

创建一个activity必须继承为Activity的子类,并覆盖所需要生命周期的回调方法。比较重要的2个方法:

onCreate(): 系统在创建activity时会调用,必须要覆盖的方法。应该在此阶段做初始化工作,layout一定要在这里被初始化:调用setContentView() 设置activity的界面。

onPause(): 用户离开这个activity时系统调用的第一个方法,鉴于用户不一定会再返回这个activity,应该做数据持久化的处理。

生命周期的其他部分会在后面继续讨论。


1.1 建立用户界面

用户界面由含有层级关系的一个或多个View组成,每一个View控制屏幕的一个矩形区域,且可以相应用户的操作。术语Widgets表示用户可见或可交互的View,Layout 则是ViewGroup,它包含的view提供布局的规则。

android已经提供了一系列的组件如button、textview等,我们可以直接使用,也可以继承View 或 ViewGroup,实现特定功能的控件。

将布局传递给activity一般的做法是在xml中定义自己的界面,然后使用setContentView()布局。


1.2 在Manifest中声明activity

Activity必须在所属应用的Manifest.xml中声明,不然系统会找不到,最简单的声明可以按照以下格式:

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

android:name对应这个activity的路径,包名和java名。还有其他可选的属性如label,theme等。

在声明之后,还可以为activity加上其他属性,如果这个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>


2 启动Activity

        在一个activity中,使用startActivity()启动另外一个activity,为了注明要跳转到哪里activity,需要使用Intent: 

//从当前的activity跳到“YourActivity”
    Intent intent = new Intent(this, YourActivity.class); 
    startActivity(intent);

        除了直接指定class名,android提供了另外一种特殊的方式:

       你的应用可能需要别的程序为你完成一些特定操作,只要为Intent指定一个Action,系统就会为你找到接收这个action的activity。(Intent的最精华的作用在于此,实现松耦合)

       例如你的程序需要发送一封邮件给指定的收件人,intent需要一个action和 收件人的列表作为data,Email编辑界面会为你加载这些数据,这里的recipientArray会被读取并显示在Email的收件人编辑框中:

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


2.1 启动带有返回结果的activity

     startActivity()只是告诉系统要启动一个activity, 但有些情况下,我们还需要启动的activity为我们完成一项工作后返回结果和数据,可以用以下方法:

startActivityForResult(Intent i, int requestCode); //requestCode 标记这个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...
        }
    }
}

3 关闭activity

finish() 和 finishActivity()都可以关闭一个activity,但google建议:除了必须时,不要直接调用这些接口,应该交由系统统一管理生命周期。


4 管理生命周期

一个activity的生命周期直接受到其他activity、当前任务或back stack的影响,通过生命周期的接口对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 生命周期的3个阶段(但实际上某些时候只需要其中几个),在不同阶段应该做相应级别的处理:


  • 从onCreate() 到 onDestroy()是一个完整的周期 。 应该在onCreate()做初始化(layout等),在onDestroy()中释放所有占用的资源(如正在工作的线程、bitmap等)。
  • 从onStart()到 onPause()被调用前 属于可见的周期。用户可以看见activity的界面并与之交互。如果当前界面不再可见,onStop()将会被调用。在这2个方法之间,应该管理和UI显示相关的数据资源。如:onStart()注册一个receiver监听数据的变化,在onStop()时应注销它,因为界面已经不可见,不需要再更新。
  • 从onResume()到 onPause()被调用,属于前台(foreground)的周期。activity处于所有其他activity之前,并能接收用户输入。因为activity经常被高频率的切换,前台activity被转入后台(如弹出一个非全屏的dialog),这2个方法应用于处理一些轻量级的操作,防止界面切换出现卡顿。


生命周期的经典图示:


生命周期方法的总结:

onCreate: activity被创建时调用。初始化静态数据的操作:创建view,为list绑定数据等。它有一个Bundle作为参数,存放 着这个activtiy之前的状态(onSaveInstanceState())。之后调用的一定是onStart()。

    onRestart: activity被stop后,还原时调用。之后调用的一定是onStart()。

    onStart: 在activity显示在屏幕之前调用。如果activity转到前台会调用onResume(),如果界面被遮挡则进入onStop()。

        onResume(): 在可以和用户交互之前调用。 activity已经被置于栈顶。 onPause()在其后调用。

        onPause(): 在另一个activity即将resume时被调用。一般用来保存数据和停止一些消耗CPU的操作等。鉴于界面正             在跳转,为了不阻塞,这里的操作应该越快完成越好。 activtiy若回到显示状态将会调onResume(), 否则                       随后调用onStop()让它消失在屏幕上。

    onStop(): 在界面完全被遮挡住前调用。 这时,可能activity即将被destroy,或者其他activity resume并遮住了它。           activtiy若将重新显示则调用onRestart(), 否则进入onDestroy() 将其毁灭。

onDestroy(): activity即将被灭掉了。这是最后一个被调用的周期方法。 导致destroy的可能是用户指定finish(), 或者系统 为了节省空间。 isFinishing()可以区分这两种情况。

注意:onPause()方法其实是系统一定会调用的最后一个生命周期方法,onStop(), onDestroy()都不保证一定能调到,所以重要的事情应该在onPause()里面完成(保存数据等),且选择必须保留的数据,避免阻塞下一个activity。


5 保存activity状态

activity 的回调方法 onSaveInstanceState() 可以用于保存activity状态,方法提供Bundle参数给我们保存数据,如果系统kill掉了这个activity,用户return回去的时候,我们可以通过onCreate()(或者onRestoreInstanceState())的Bundle参数提取出这些数据。

onSaveInstanceState()默认保留各种View的显示状态(checkbox是否勾上等),我们需要做的是保存与界面绑定的一些变量值,如记录checkbox值的数组,并且确保layout中的重要view都有自己的id,否则它的状态无法保存。如果覆盖此方法,应该在开始便调用super.onSaveInstanceState(),因为它默认会帮组我们记录view的状态。





转载于:https://my.oschina.net/wilsonchan/blog/91341

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值