一、Intent概述
意图本身(一个 Intent 对象)是一个被动的数据结构,保存着要执行操作的抽象描述;
在 Android
不同组件间 传递数据,是Activity、Service、BroadcastReceiver之间的通信载体。
- 显式Intent:通过组件名指定启动的目标组件,比如startActivity(new Intent(A.this,B.class)); 每次启动的组件只有一个~
- 隐式Intent: 不指定组件名,而指定Intent的Action,Data,或Category,当我们启动组件时, 会去匹配AndroidManifest.xml相关组件的Intent-filter,逐一匹配出满足属性的组件,当不止一个满足时, 会弹出一个让我们选择启动哪个的对话框~
二、Intent的属性
1)ComponentName(组件名称)
2)Action(动作)
3)Category(类别)
4)Data(数据),Type(MIME类型)
5)Extras(额外)
6)Flags(标记)
参考菜鸟教程Intent使用
三、使用示例
1、显式Intent使用示例:
1) Intent不仅可以启动一个活动,还可以在启动活动的时候传递数据,传递数据的思路如下:
1、在启动页面中通过Intent提供的一系列putExtra(“键”,值)方法,将传递的数据放在Intent中;
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
// b. 通过putExtra()方法传递一个字符串到SecondActivity;
// putExtra()方法接收两个参数:第一个是键,第二个是值(代表真正要传递的数据)
intent.putExtra("data","I come from FirstActivity");
// c. 启动Activity
startActivity(intent);
2、在被启动的页面中通过getIntent()获取Intent对象,再调用getXXXExtra(“键”)方法获取值。
// a. 获取用于启动SecondActivit的Intent
Intent intent = getIntent();
// b. 调用getStringExtra(),传入相应的键名,就可得到传来的数据
// 注意数据类型 与 传入时保持一致
String data = intent.getStringExtra("data");
2)点击按钮打开百度页面:
Intent it = new Intent();
it.setAction(Intent.ACTION_VIEW);
it.setData(Uri.parse("http://www.baidu.com"));
startActivity(it);
2、隐式Intent使用示例:
1)预定义动作的隐式Intent示例:
1、点击按钮后,所有Action为VIEW的Activity被筛选出来,由用户进一步选择:
Intent it = new Intent();
it.setAction(Intent.ACTION_VIEW);
startActivity(it);
2、建立第二个Activity的布局,与对应的Activity,在第一个Activity的按钮点击事件中添加一下代码:
<activity android:name=".SecondActivity"
android:label="第二个Activity">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
2)自定义动作的隐式Intent示例:
1、使用自定义的Action与category来激活另一个Activity
Intent it = new Intent();
it.setAction("my_action");
it.addCategory("my_category");
startActivity(it);
2、建立第二个Activity的布局,与对应的Activity,在第一个Activity的按钮点击事件中添加一下代码:
<activity android:name=".SecondActivity"
android:label="第二个Activity">
<intent-filter>
<action android:name="my_action"/>
<category android:name="my_category"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
四、使用 Intent传递对象
1、 Serializable 方式
Serializable是序列化的意思,表示将一个对象转化成可储存或可传输的状态。序列化的对象可在网络上传输也可存储到本地。将一个类序列化只要去实现 Serializable 接口就可以了。
public class Person implements Serializable{
private String name;
private int age;
....Get/SetMethod
}
传递:
Person person = new Person();
person.setName("Tom");
person.setAge(20);
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("person_data", person);
startActivity(intent);
接收:
Person person = (Person) getIntent().getSerializableExtra("person_data");
2、 Parcelable 方式
除了Serializable之外,使用Parcelable也可以实现相同的效果,不过不同于将对象进行序列化,Parcelable方式的实现原理是将一个完整的对象进行分解,而分解后的每一部分都是Intent所支持的数据类型,这样也就实现传递对象的功能了。
public class Person implements Parcelable {
private String name;
private int age;
……
@Override
public int describeContents() {
return 0;
}
//将Person类中的字段一一写出,注意不同类型对应不同的方法
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name); // 写出name
dest.writeInt(age); // 写出age
}
public static final Parcelable.Creator<Person> CREATOR = new Parcelable. Creator<Person>() {
@Override
public Person createFromParcel(Parcel source) {
Person person = new Person();
person.name = source.readString(); // 读取name
person.age = source.readInt(); // 读取age
return person;
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
}
必须重写describeContents()和writeToParcel()这两个方法;还必须在Person类中提供一个名为CREATOR的常量,这里创建了Parcelable.Creator接口的一个实现,并将泛型指定为Person,需要重写createFromParcel()和newArray()这两个方法。
接收:
Person person = (Person) getIntent().getParcelableExtra("person_data");
评价两种方式:
对比一下,Serializable的方式较为简单,但由于会把整个对象进行序列化,因此效率方面会比Parcelable方式低一些,所以在通常情况下还是更加推荐使用Parcelable的方式来实现Intent传递对象的功能。