Android 浅谈 Activity

在正文开始之前,我给大家来个段子:
乌龟正在河里洗澡被癞蛤蟆看见了,
乌龟:没见过像我这样的美女吗?看你眼珠子都快要蹦出来了。
癞蛤蟆:妹,你就别逗我了,没有看见我身上已经起鸡皮疙瘩了吗?
只是想让大家放松下,作为一名程序猿不要一直紧绷着大脑。

相信大家对 Activity都不陌生,或多或少都有自己的理解,我会从什么是 Activity,创建一个 Activity,实现一个用户界面,如何在清单文件声明,启动一个新的 Activity,关闭一个 Activity 以及 Activity的生命周期,Activity的状态保存.

一、什么是Activity
一个活动是一个应用程序组件,它提供了一个屏幕,用户可以交互为了做某件事,如拨电话,拍照,发送电子邮件,或查看地图。每个活动都将画它的用户界面的一个窗口。窗户通常充斥屏幕,但可能比屏幕小,浮在其他窗口的顶部。
二、创建一个Activity
你创建的类必须继承Activity或者继承Activity的子类,你需要实现回调方法。系统调用时,其生命周期的不同状态之间的转换,如停止,恢复或销毁。最重要的两个回调方法:
onCreate()
Activity被创建时调用,调用setContentView()来定义用户界面的布局。通常setContentView(R.layout.activity_main);当然你也可以setContentView(View view)来展示你的界面。
onPause()
用户离开Activity时被调用,任何的修改都应该被提交(通常用于ContentProvider保存数据)。
三、实现一个用户界面
用户界面提供了一个试图,每个视图就是一个窗口,可以响应用户交互。例如,一个视图可能是一个按钮,当用户触摸它启动一个动作。  
Android提供了许多现成的视图,您可以使用它们来设计和组织你的布局。比如一个按钮,文本框,复选框,或者只是一张图片。“布局”视图来自ViewGroup提供一个独特的子视图的布局模型,如线性布局,网格布局,或相对布局。你也可以继承View和ViewGroup类来自定义布局或控件将它们应用到你的Activity中。
四、清单文件声明
你创建的Activity必须在清单文件中声明:

<activity android:name=".MainActivity"> //全名是包名+类名
<intent-filter>                         //意图过滤器
<action android:name="android.intent.action.MAIN" />//动作
<category android:name="android.intent.category.LAUNCHER" />                                                 //类别
</intent-filter>
</activity>

以下声明表示该Activity为程序入口,并且action 和category 的值不能被改变。

<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"/> 
//决定应用程序是否显示在程序列表里

如果声明的Activity并不是程序入口,action 的name的值可以随意改变,规范写法(包名+类名),category 的name的值为.DEFAULT或.LAUNCHER,在后面我会具体讲解下它们的区别。

<action android:name="com.github.wens.LoginActivity" />
<category android:name="android.intent.category.DEFAULT" />

五、启动一个新的Activity
通过一个Intent意图,来启动一个新的Activity.
1、显示意图

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

2、隐示意图

 Intent intent=new Intent();
 intent.setAction("com.github.wens.IndexActivity");
 startActivity(intent);

这里setAction就是AndroidManifest.xml清单文件下 action 的name值.注意:如果使用隐示意图启动Activity,在清单文件中category的类别为.DEFAULT,不然会导致匹配失败。

然而,你的应用程序可能也要执行一些操作,如发送短信、发送邮箱、拨打电话等,使用上面的方法是不能够实现的,怎么办呢?下面我以发送邮箱为例:

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

当然你除了发送邮箱,还可以发送文本EXTRA_TEXT,发送图片EXTRA_STREAM等。

有些时候你需要接收启动新界面返回的结果。这个时候你就要使用startActivityForResult() (代替 startActivity()),下面我举个例子来说明:

A界面图

如上图所示,界面A需求界面B返回的数据,在界面A:

 bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(A.this, B.class);
                startActivityForResult(intent, 1); //requestCode                                                            
            }
        });

并且我们在onActivityResult()处理返回结果:

@Override
    protected void onActivityResult(int requestCode, int  resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode,  data);
        if (requestCode == 1) { 
            if (resultCode == 2) {
                String text = data.getStringExtra("data");
                tv.setText(text);
            }
        }
    }

在B界面:

@Override
    public void onBackPressed() {
        //super.onBackPressed();
        Intent intent = new Intent();
        intent.putExtra("data", et.getText().toString());
        setResult(2, intent);   //resultCode
        finish();
    }

六、关闭一个Activity
调用finish(),你也可以调用finishActivity()。
七、Activity的生命周期

生命周期图

下面我对每个方法具体讲解下:

onCreate()
第一次被创建时调用。我们可以在这个方法里面创建视图,绑定组件ID,等等。总是跟着onStart()。

onRestart()
在onStop()方法后被调用,总是跟着onStart()。

onStart()
总是跟着onResume()。

onResume()
用户交互,处于栈顶,总是跟着onPause()。

onPause()
当程序启动新的Activity,该方法通常用于提交持久化数据,保存数据,停止动画和其他消耗的CPU的操作等等。不适合做耗时的操作,否则会引起界面卡顿。总是跟着onStop()。

onStop()
用户不可见,因为一个新的Activity已经覆盖它,总是跟着onDestroy()或者onRestart()。

onDestroy()
消亡时被调用。

八、状态保存
一般来说, 调用onPause()和onStop()方法后的activity实例仍然存在于内存中, activity的所有信息和状态数据不会消失, 当activity重新回到前台之后, 所有的改变都会得到保留.

但是当系统内存不足时, 调用onPause()和onStop()方法后的activity可能会被系统摧毁, 此时内存中就不会存有该activity的实例对象了. 如果之后这个activity重新回到前台, 之前所作的改变就会消失. 为了避免此种情况的发生, 我们可以覆写onSaveInstanceState()方法. onSaveInstanceState()方法接受一个Bundle类型的参数, 我们可以将状态数据存储到这个Bundle对象中, 这样即使activity被系统摧毁, 当用户重新启动这个activity而调用它的onCreate()方法时, 上述的Bundle对象会作为实参传递给onCreate()方法, 我们可以从Bundle对象中取出保存的数据, 然后利用这些数据将activity恢复到被摧毁之前的状态.
说了这么多,我们还是来看代码:
在onCreate()

if (savedInstanceState != null) {
          String   data = savedInstanceState.getString("data");
        }
 @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("data", "test");
    }

注意:onSaveInstanceState()方法并不是一定会被调用的, 因为有些场景是不需要保存状态数据的. 比如用户按下BACK键退出activity时, 用户显然想要关闭该activity, 此时是没有必要保存数据以供下次恢复的, 也就是onSaveInstanceState()方法不会被调用. 如果调用onSaveInstanceState()方法, 调用将发生在onPause()或onStop()方法之前.

onSaveInstanceState()默认实现保存UI控件的状态数据,我们需要额外的数据时,就需要重写onSaveInstanceState().注意:在onSaveInstanceState()不适合做持久化数据的保存,适合保存UI控件状态,和成员变量等。

引发activity摧毁和重建情形
除了系统处于内存不足的原因会摧毁activity之外, 某些系统设置的改变也会导致activity的摧毁和重建. 例如改变屏幕方向, 改变设备语言设定, 键盘弹出等.

如果文中有什么不对的地方,还请大家给于指出,谢谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值