Intent,意图,相信大家在学习开发中经常能看到它的身影,例如,Activity之间要用到它来进行跳转,Service要用它来进行启动、绑定以及取消绑定,BroadcastReceiver广播接收器也要用它来进行发送和注册,虽然常见,但是你真的了解它吗?下面为大家带来Intent完全解析,关于Intent你应该了解的一切!
一、Intent概述
二、Intent类型
三、Intent用法与解析
四、Intent总结
一、Intent概述
An Intent is a messaging object you can use to request an action from another app component. An Intent object carries information that the Android system uses to determine which component to start, plus information that the recipient component uses in order to properly perform the action.
Intent是一个消息对象,你可以用它来从一个应用组件请求动作,它让组件间的通信变得很方便。Intent对象携带Android系统用来决定启动哪个组件的信息,以及接收的组件用来执行动作所需要的信息。
总的来说,Intent对象主要有以下几种用途:1、启动Activity。通过传递一个Intent对象给startActivity()可以启动一个Activity实例,如果想要返回数据,可以用startActivityForResult()。2、启动服务。通过传递一个Intent对象给startService(),可以启动Service,如果要绑定Service可以传递Intent对象给bindService。3、发送广播。通过传递一个Intent对象给sendBroadcast(), sendOrderedBroadcast(), 或sendStickyBroadcast()可以发送广播消息。
二、Intent类型
- Explicit intents 显式意图
specify the component to start by name (the fully-qualified class name). You'll typically use an explicit intent to start a component in your own app, because you know the class name of the activity or service you want to start.
根据指定的名称来启动组件,在我们的应用中我们经常使用显式意图来启动组件,因为我们知道要启动的Activity或者Service的类名。
-
Implicit intents 隐式意图
do not name a specific component, but instead declare a general action to perform, which allows a component from another app to handle it. For example, if you want to show the user a location on a map, you can use an implicit intent to request that another capable app show a specified location on a map.
不明确指定组件,而是声明一个要执行的通用动作,系统可调用别的App来处理。例如,如果想要在地图上展示用户的位置,可以使用一个隐式意图来请求别的应用来处理。
三、Intent用法与解析
Intent意图主要有两种类型,用法也不尽相同,显式Intent的用法与解析,大家可以看下面的代码:
/**
* Created by JackalTsc on 2016/7/11.
*/
public class IntentActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_activity_intent);
Button btnStart = (Button) findViewById(R.id.btn_start);
btnStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent mIntent = new Intent(IntentActivity.this, TestActivity.class);
startActivity(mIntent);
}
});
}
}
逻辑很简单,就是点击按钮时,构造一个Intent对象,启动另一个Activity。
接下来,还是这段代码,我们按住ctrl,鼠标点击new后面的Intent,查看具体的逻辑。
可以看到,当我们在启动Activity前构造Intent对象时,Intent构造函数内的两个参数是包名和类名,Intent构造函数内继续调用ConponentName的构造函数来初始化属性Component。这里我们可以初步得到一个关键点,Intent对象有包括Component、Action、Category、Data、Type、Extra以及Flag等7个属性,构造Intent时传入不同的属性,Intent就包含了不同的信息,这样Android系统就能根据Intent包含的信息启动不同的组件。
一般情况下,我们在启动别的Activity时,首先实例化Intent,这里我们其实是给Intent的属性Component赋值了,再看下面的这段代码,等价于之前的代码:
Button btnStartEx2 = (Button) findViewById(R.id.btn_start_explicit2);
btnStartEx2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ComponentName componentName = new ComponentName(IntentActivity.this, TestActivity.class);
Intent intent = new Intent();
intent.setComponent(componentName);
startActivity(intent);
}
});
关于Component
Intent内包含的属性Conponent,它的名字就是要启动的具体的组件的名字,比如指定的Activity,或者指定的Service,Conponent是决定Intent是否为显式Intent的关键信息。如果没有Component名字,Intent对象就是隐式的,系统将会根据Intent的其它属性来决定哪些组件可以接收到这个Intent。
接下来,是隐式Intent的用法,代码如下:
- 首先是Activity的配置
<activity android:name=".activity.TestActivity">
<intent-filter>
<action android:name="jackaltsc.intent.action.test"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
- 启动Activity
Button btnStartIm = (Button) findViewById(R.id.btn_start_implicit1);
btnStartIm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction("jackaltsc.intent.action.test");
startActivity(intent);
}
});
这里我们可以看到,启动Activity时并没有明确指出是启动哪个Activity,只是给出了Action字符串,当然我们在清单文件里给要启动的Activity加入了两个属性,一个是action,一个是category,这样应该很明白了,即使没有明确指明是启动哪个Activity,但是系统根据意图过滤器中的属性action和category确定要启动的Activity。
- ** 关于action**
A string that specifies the generic action to perform,就是指定要执行的通用动作的字符串,它告诉该Intent要完成的抽象动作,但是具体怎么完成是系统根据其它相关信息来确定的,比如category。
- ** 关于category**
A string containing additional information about the kind of component that should handle the intent,一个包含要处理指定的Intent的组件的额外的信息,通常,category和action结合使用。 - 一般如果我们想要让一个Activity成为第一个启动的Activity时,我们会给指定的Activity配置意图过滤器intent-filter。
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
下面给大家展示几个常用的隐式Intent的例子。
1、显示拨号界面。
Button btnStartDi = (Button) findViewById(R.id.btn_start_dial);
btnStartDi.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);
}
});
2、打开图库选择(如果需要处理数据还需处理)
Button btnStartGa = (Button) findViewById(R.id.btn_start_gallery);
btnStartGa.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent gaIntent = new Intent(Intent.ACTION_GET_CONTENT);
gaIntent.setType("image/*");
// 打开图库
startActivityForResult(gaIntent, 1);
}
});
3、浏览器打开指定网址
Button btnStartWeb = (Button) findViewById(R.id.btn_start_web);
btnStartWeb.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Uri uri = Uri.parse("http://www.baidu.com");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
});
关于Data和Type
属性Data通常用于向Action属性提供操作的数据,属性Type用于指定Data属性指定的Uri的MIME类型。
关于Extra和Flag
Intent的Extra属性,我们应该都比较了解了,在Activity的跳转中通过Intent携带数据肯定要用到,Intent的Flag属性用于为Intent添加额外的控制信息,这里不作详细介绍。
四、Intent总结
显式意图很好理解,下面这张图是隐式意图的工作原理。
Activity A创建一个有动作描述的Intent并把它传递给startActivity(),Android系统搜索所有匹配指定Intent的Intent过滤器,找到Activity B后,系统通过传递Intent对象,调用找到的Activity B的onCreate()方法来启动Activity.
以上就是Intent的完全解析,主要参考了Android疯狂讲义以及自己之前的一些总结,实践出真知,更多的还是要大家在开发中逐渐探索。