android intent过滤器,Android- Intent与Intent过滤器

Intent

Intent是一种对准备进行的操作的抽象描述,它是一个消息传递对象,用来从其他应用组件请求操作。通常用于启动Activity,启动Service,传递Broadcast。

Intent类型

Intent分为两种类型:显式和隐式。

显式Intent

通过提供目标应用的软件包名称或完全限定的组件类名来指定可处理 Intent 的应用。代码示例如下:

public static final String EXTRA_MESSAGE = "com.example.exercise.MESSAGE";

public void startSecond(View view) {

// 在布局xml中注册onclick事件触发

Intent intent = new Intent(this, SecondActivity.class);

String dateStr = new Date().toString();

intent.putExtra(EXTRA_MESSAGE, dateStr);

startActivity(intent);

}

Intent(Context, Class)构造函数的第一个参数要求提供一个启动Activity的上下文,第二个参数则是指定想要启动的Activity。在被启动的Activity中,可以通过getIntent()获取到传递的Intent对象。

隐式Intent

不会指定特定的组件,而是声明要执行的常规操作,从而允许其他应用中的组件来处理。一般需要在AndroidManifest.xml中为Activity添加,从而指定当前Activity能响应的Intent以及可能带有的category。

可以通过以下元素指定要接受的Intent类型:

:在 name 属性中,声明接受的 Intent 操作。该值必须是操作的文本字符串值,而不是类常量。

:使用一个或多个指定数据 URI(scheme、host、port、path)各个方面和 MIME 类型的属性,声明接受的数据类型。

:在 name 属性中,声明接受的 Intent 类别。该值必须是操作的文本字符串值,而不是类常量。

代码示例如下:

定义

隐式调用

public void startAction(View view) {

Intent intent = new Intent("com.example.activitytest.ACTION_START"); // 指定action

intent.addCategory("com.example.activitytest.MY_CATEGORY"); // 为Intent添加category

startActivity(intent);

}

每个Intent中只能指定一个,但是可以指定多个。

解析Intent

当系统收到Intent时,会从action,category和data三方面将该Intent和Intent过滤器进行对比,寻找最佳的Activity。

过滤action

Intent过滤器可以声明多个,也可以不声明。

如果要通过筛选,Intent中指定的action必须和过滤器中某一项匹配。

过滤器没有指定action:所有Intent都无法被筛选到

Intent没有指定action:只要过滤器有一项action就可以筛选到

过滤category

和action一样,过滤器可以声明多个,也可以不声明。

若要通过筛选,Intent中的每个类别都要和过滤器中声明的匹配,若有一项category在过滤器中匹配不到,则不通过。

过滤器没有指定category:所有Intent都可以通过筛选

过滤器的category数量超过Intent添加的:只要Intent中的category是过滤器声明category的子集就可以通过

过滤data

过滤器可以不声明,也可以声明多个。

URI的每个部分在中都是单独的属性。一个URI的结构如下:://:/。

若这个URI的值为:content://com.example.project:200/folder/subfolder/etc,则在过滤器中声明类似:

android:scheme="http"

android:host="com.example.project"

android:port="200"

android:path="folder/subfolder/etc" />

元素中,上述属性均为可选,但存在依赖关系:

如果未指定scheme,则会忽略host。

如果未指定host,则会忽略host。

如果未指定scheme和host,则会忽略path。

path 可以包含通配符*

Intent 的URI和过滤器中的URI比较时,仅会和部分URI比较:

若过滤器仅指定了scheme,则相同scheme的都会通过

如果过滤器指定scheme和权限,但未指定path,则具有相同scheme和权限的所有 URI 都会通过过滤器,无论其path如何均是如此。

如果过滤器指定scheme、权限和path,则仅具有相同scheme、权限和path的 URI 才会通过。

data过滤器匹配规则如下:

仅当过滤器未指定任何 URI 或 MIME 类型时,不含 URI 和 MIME 类型的 Intent 才会通过测试。

仅当过滤器未指定MIME 类型,但指定了URI时,包含URI且匹配,且不含 MIME 类型(既未显式声明,也无法通过 URI 推断得出)的 Intent,才会通过测试。

仅当过滤器列出 MIME 类型且未指定 URI 格式时,包含过滤器列出的 MIME 类型但不含 URI的 Intent 才会通过测试。

仅当 MIME 类型与过滤器中列出的类型匹配时,同时包含 URI 类型和 MIME 类型(通过显式声明,或可以通过 URI 推断得出)的 Intent 才会通过测试的 MIME 类型部分。

如果 Intent 的 URI 与过滤器中的 URI 匹配,或者如果 Intent 具有 content: 或 file: URI 且过滤器未指定 URI,则 Intent 会通过测试的 URI 部分。换言之,如果过滤器只是列出 MIME 类型,则假定组件支持 content: 和 file: 数据。

使用Intent传递对象

Intent中可以附加数据传递给其他Activity,最常见的是putExtra()的一系列重载方法,但是支持的数据类型有限,因此需要通过传递对象来增加灵活性。

传递基础类型数据

Bundle以键值对形式保存数据,在系统打包Intent后,通过在另一个Activity中接受Intent并拆包,可以获取到Bundle中的数据。

传递对象

使用Intent来传递对象有两种方法:Serializable和Parcelable。

Serializable:

实现Serializable接口即可,之后类的实例直接用putExtra()写入Intent。示例代码如下:

实现Serializable的类

public class Person implements Serializable{

int age;

String name;

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

传入Intent

Person someone = new Person();

someone.setAge(20);

someone.setName("Alice");

Intent intent = new Intent(this, SecondActivity.class);

intent.putExtra("someone_person", someone);

startActivity(intent);

在另一个Activity中提取对象

Person someone = (Person) getIntent().getSerializableExtra("someone_person");

Parcelable:

传递对象的类需要实现Parcelable接口。原理是将一个完整的对象进行分解,分解后每一部分都是Intent所支持的数据类型。Parcelable的方法相比较Serializable效率更高。一般数据大小限制为1MB。代码示例如下:

实现Parcelable

public class Person implements Serializable{

int age;

String name;

/* 此处省略 getter 和 setter */

@Override

public void writeToParcel(Parcel dest, int flags) {

// 此处需要将所有成员变量一一写入

dest.writeInt(age);

dest.writeString(name);

}

@Override

public int describeContents() {

return 0;

}

public static final Creator CREATOR = new Creator() {

@Override

public Person createFromParcel(Parcel in) {

Person person = new Person(); // 在此处创建对象而不是重写构造方法

// 此处读取顺序需要和之前的写入顺序保持一致

person.age = in.readInt();

person.name = in.readString();

return person;

}

@Override

public Person[] newArray(int size) {

return new Person[size];

}

};

}

传递对象

Person someone = new Person();

someone.setAge(20);

someone.setName("Alice");

Intent intent = new Intent(this, SecondActivity.class);

intent.putExtra("someone_person", someone);

startActivity(intent);

此处代码与使用Serializable相同。

提取对象

Person person = (Person) getIntent().getParcelableExtra("someone_person")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值