Android有四大组件,分别是:Activity,BroadCastReceiver,Service,ContentProvider,本篇博客介绍的是其中的Activity。先来看下内容摘要
- 什么是Activity
- Activity的跳转
- Activity的生命周期
- Activity的启动模式
- 获取其他Activity 销毁时设置的数据
1. Activity 的创建
Activity 是Android 四大组件之一,用于展示界面。Activity 中所有操作都与用户密切相关,是一个负责与用户交互的组件,它上面可以显示一些控件也可以监听并处理用户的事件。一个Activity 通常就是一个单独的屏幕,Activity 之间通过Intent 进行通信。
1.1 如何创建自定义的Activity
1.1.1 自定义类继承Activity
新建一个Android 工程,在src 目录下新建一个类,不妨起名MainActivity,让该类继承Android SDK提供的Activity。
1.1.2 在MyActivity 中覆写onCreate()方法
onCreate() 方法是在当前Activity 被系统创建的时候调用的, 在该方法中一般要通过setContentView(R.layout.myactivity)方法给当前Activity 绑定布局文件或视图。因此为了让我们的MyActivity 能够展示界面需要在工程目录的res/layout/目录下创建一个布局文件。比如我创建的布局文件名(注意:Android 的资源文件名中是不允许有大写字母的,必须全小写,如果有多个单词可以用下划线分开)为myactivity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="这是MyActivityA"/>
</LinearLayout>
必须要注意的就是在该方法中必须先调用父类的onCreate() 方法, 也就是super.onCreate(savedInstanceState);该句代码必须被调用一次。这是为什么呢?我们看看父类的onCreate()方法里面都干了些啥就知道了。如图1-1 所示,在父类的方法中执行了一堆业务逻辑,而且在最后一行用了一个成员变量mCalled 记录了当前方法是否被调用了。虽然我们现在还不看不同这些代码,但是我们已经知道既然父类帮我们实现了这么功能,那么我们子类就一定必须调用一次父类的该方法。
1.1.3在AndroidManifest.xml 中进行Activity 的注册
Android 中共有四大组件,除了BroadCastReceiver 之外,其他三个组件如果要使用那么必须在AndroidManifest.xml 中进行注册(也叫声明)。
我们在上面创建的MyActivity 如何注册呢?其实如果你不会的话完全可以将eclipse 自动生成的MainActivity 的注册代码给拷贝过来,然后将android:name 的属性值修改成我们的类。
<activity
android:name="com.itheima.android.activity.MyActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
上面用到的标签以及属性含义如下表
图1-2 Activity 的Label 属性
在【文件1-2】中,我将MainActivity 的所有东西都拷贝过来了,只不过是替换了类名。对于MainActivity来说正是配置了特定(action 为android:name=”android.intent.action.MAIN”,category 为
android:name=”android.intent.category.LAUNCHER”)的intent-filter,那么当应用安装好以后,才会在桌面创建一个图标,点击该图标打开MainActivity。现在我自定义的MyActivity 也配置了一模一样的intent-filter,那么系统也会为我的MyActivity 创建一个图标(如图1-3),如果用户点击了该图标,那么也可以直接打开我的MyActivity 界面。也就是说一个Android 工程可以创建多个图标,不过通常情况下一个Android 应用只要给一个入口的Activity 配置为入口Activity 即可。
图1-3 一个应用多个图标
2. Activity 的跳转
一个Android 应用通常有多个界面,也就说有多个Activity,那么如何从一个Activity 跳转到另外一个Activity 呢?以及跳转的时候如何携带数据呢?
Activity 之间的跳转分为2 种:
显式跳转:在可以引用到另外一个Activity 的字节码,或者包名和类名的时候,通过字节码,或者包名+类名的方法实现的跳转叫做显示跳转。显示跳转多用于自己工程内部多个Activity 之间的跳转,因为在
自己工程内部可以很方便地获取到另外一个Activity 的字节码。
隐式跳转:隐式跳转不需要引用到另外一个Activity 的字节码,或者包名+类名,只需要知道另外一个Activity 在AndroidManifest.xml 中配置的intent-filter 中的action 和category 即可。言外之意,如果你想让
你的Activity 可以被隐式意图的形式启动起来,那么就必须为该Activity 配置intent-filter。
Activity 之间的跳转都是通过Intent 进行的。Intent 即意图,不仅用于描述一个的Activity 信息,同时也是一个数据的载体。
2.1 显式跳转
为了方便演示,我们创建一个新的Android 工程《Activity 的跳转》。然后创建两个Activity 类,分别为FirstActivity,和SecondActivity,并在Android 工程的清单文件中声明这两个Activity 类。工程清单中添加Activity 配置如下所示。
<activity
android:name="com.itheima.activitySkip.FirstActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.itheima.activitySkip.SecondActivity"/>
在上面的清单文件中,我们将FirstActivity 配置成了主Activity,SecondActivity 则为普通Activity。这样FirstActivity 就是我们应用的入口Activity 了。FirstActivity 和SecondActivity 代码清单如下所示。
package com.itheima.activitySkip;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class FirstActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
}
//绑定界面的Button 控件的点击事件,点击后实现跳转到SecondActivity
public void skip2Second(View view){
//创建一个Intent 对象,并传递当前对象(Context 对象)和要跳转的Activity 类字节码
Intent intent = new Intent(this, SecondActivity.class);
//Intent 同时也是数据的载体,在跳转的时候可以携带数据
//通过intent 的putExtra(key,value)方法可以设置数据
//Intent 支持所有基本数据类型及其数组形式
intent.putExtra("name", "张三");
//启动第二个Activity
startActivity(intent);
}
}
public class SecondActivity extends Activity {
protected void onCreate(android.os.Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
/**
* 获取Intent 对象,该对象是启动了当前Activity 的对象
*/
Intent intent = getIntent();
if (intent != null) {
// 从Intent 中获取设置的数据,如果获取不到返回null
//获取FirstActivity 中设置的数据
String name = intent.getStringExtra("name");
if (name!=null) {
Toast.makeText(this, "name="+name, Toas