Intent在Android开发中非常重要,其封装了我们想开启其他组件的“意图”,大概意思就是:如果我们需要开启其他的组件,其他的Service,或者我们在启动其他组件的同时需要交换一些数据,这个时候就需要将我们的数据封装在Intent中,然后通过这个Intent来启动。
Android应用程序中有三个重要的组件:Activity,Service,BroadcastReceiver,这三个组件的启动,我们都是通过Intent来启动,而Intent里面就封装着我们可能要交换的数据。
Intent属性大致包含:Component,Action,Category,Data,Extra,Flag这6种属性
1、Component
通过Component来启动一个Activity(启动SecondActivity)
ComponentName componentName = new ComponentName(MainActivity.this, SecondActivity.class);
Intent intent = new Intent();
intent.setComponent(componentName);
startActivity(intent);
2、Action,Category属性以及intent-filter配置
Action指得是一个行为或者指一个操作,而Category属性可以为Action增加一些附加的信息,通常两个属性是结合一起用。
Action和Category其本质就是一个字符串,系统也有提供一些Action,比如:Intent.ACTION_VIEW,这个就表示一个查看的行为,但是谁来查看,或者查看谁,Action这个字符串并不管。
这个取决于在AndroidMainfest.xml文件里面Activity对应的Intent-filter属性,哪一个Activity里面的Intent-filter配置了ACTION_VIEW这个属性,那么这个Activity就有可能被启动。
示例一下通过Action来启动Activity:
Intent intent1 = new Intent();
intent1.setAction(Intent.ACTION_VIEW);
startActivity(intent1);
上面的代码没有像Component那样,显式的指定要启动哪一个Activity,只是给Intent指定了一个Action,那么现在哪一个Activity来响应这个启动呢?
那么就看AndroidMainfest.xml里面,哪一个Activity的Inten-filter里面配置了这个action,哪一个Activity就负责响应这个启动,
比如我现在在AndroidMainfest.xml里面设置一个ThirdActivity.xml的配置
<activity android:name=".ThirdActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
</intent-filter>
</activity>
在xml里面给ThirdActivity里面配置了同样的字段:Intent.ACTION_VIEW,此时ThirdActivity就负责我们刚才启动的响应。
上面在xml的activity里面配置了action属性,那么还有Category属性怎么使用呢?
前面我们有记录,Category属性是配合着action属性一起用的,所以,如果我们要使用Category属性的话,还是按照上面的套路,然后使用接口添加上Catrgory属性即可。
final String CRAZYIT_CATEGORY = "org.crazyit.intent.category.CRAZYIT_CATEGORY";
Intent intent1 = new Intent();
intent1.setAction(Intent.ACTION_VIEW);
intent1.addCategory(CRAZYIT_CATEGORY);
startActivity(intent1);
这个时候我们给我们要启动的Activity设置了两个要求:①有Intent.ACTION_VIEW②有“org.crazyit.intent.category.CRAZYIT_CATEGORY”这个Category。那么此时负责响应的Activity里面的<intent-filter>就需要有这两个组件。这个时候我们改一下之前的xml文件:
<activity android:name=".ThirdActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
那么这个时候,因为我们的ThirdActivity里面既有对应的action组件也有对应的category组件,所以当我们进行跳转的时候,ThirdActivity就负责响应我们这一次跳转。
3、Data、Type属性和Intent-filter配置
Data属性通常用于向Action提供数据,Data属性接收一个Uri对象。
一个Uri对象类似这种:
content://com.android.contacts/contacts/1
Tip:contacts翻译:联络人
Uri的通常就是两个部分来组成
例如上面这个Uri,
content:就代表数据类型,本次指向的是一个信息
//com.android.contacts/contacts/1:后面这个就代表具体的数据值,这个Uri具体的数据值,表示的就是联系人列表里面的第一个联系人,
除了Data属性,还有的就是Type属性。
Type属性其实就是指Data的数据类型了,但是其实如果你不设置Type属性的话,只要有Data,Android系统就会自己去解析Data的值,因为Uri里面冒号前面就代表数据类型。
所以其实当你不设置Data的时候,Type属性才生效。
我们在具体使用的时候呢就可以将Action 属性和Data属性结合起来:
<ACTION_VIEW, content://com.android.contacts/contacts/1>
ACTION_VIEW代表的就是查看操作,后面的Data就是代表查看联系人里面的第一个联系人
那在代码里面我们怎么设置Data属性呢?前面几个我们已经写过了设置Action的操作,设置Data也是有专门的接口的:
String data = "content://com.android.contacts/contacts/1"
Uri uri = Uri.parse(data);
intent.setData(uri);
4、Extra属性
Extra属性用来在 Activity之间交换数据用的。Extra其实对应的就是一个Bundle对象,而我们的Bundle对象其实就类似于一个Map,可以让我们插入,查找一些key-value之类的。
在我看来,甚至整个属性可以直接替换为:Bundle,Intent之间交换数据就是通过Bundle来封装,给Bundle里面封装好数据之后,直接将Bundle放到intent里面。
Bundle里面提供一些接口,可以让我们 将数据放进Bundle:
class Person implements Serializable{
//
}
Bundle bundle = new Bundle();
bundle.putString("One_String","This is a String in Bundle");
bundle.putInt("Two_int",10);
bundle.putSerializable("Three_Object",new Person());
我们可以使用:put***();来放进去一些int,String,long类型等等,这些标准数据类型,
也可以通过putSerializable来放进去一些我们自己的自定义类型,但是这个类型必须是可序列化的。
有坑:关于这个可序列化,如果的自定义类声明成了内部类,那你的外部类必须也是可序列化的,因为内部类会持有一份外部类的引用,所以如果你只想将传递类型的类声明为可序列化的话,就得将这个类声明为外部类。
现在我们的Bundle封装完了,然后直接使用接口将Bundle塞进Intent就可以了:
intent.putExtras(bundle);
塞进去之后,就可以启动Activity了。
当我们启动了另一个Activity之后,我们想拿到这些数据的话,应该怎么拿呢?
就是将上面的put***接口全部换成get***接口,然后参数只留第一个就ok了,返回值就是你想要的值,如果没有的话,就返回空。
这个就是Intent对象最后一个Extra属性了。