Intent对象详解(一)
最后更新于:2022-04-01 16:14:50
Intent的定义:
Android中提供了Intent机制来协助应用间的交互与通讯,或者采用更准确的说法是,Intent不仅可用于应用程序之间,也可用于应用程序内部的activity, service和broadcast receiver之间的交互。Intent这个英语单词的本意是“目的、意向、意图”。
使用Intent启动系统组件:
三种应用程序基本组件——activity, service和broadcast receiver——是使用称为intent的消息来激活的。Intent消息传递是一种组件间运行时绑定的机制. intent是Intent对象, 它包含了需要做的操作的描述, 或者, 对于广播来说, 包含了正在通知的消息内容. 对于向这三种组件发送intent有不同的机制:
使用Context.startActivity() 或 Activity.startActivityForResult(), 传入一个intent来启动一个activity. 使用 Activity.setResult(), 传入一个intent来从activity中返回结果.
将intent对象传给Context.startService()来启动一个service或者传消息给一个运行的service. 将intent对象传给 Context.bindService()来绑定一个service.
将intent对象传给 Context.sendBroadcast(), Context.sendOrderedBroadcast(),或者Context.sendStickyBroadcast()等广播方法,则它们被 传给 broadcast receiver.
在上述三种情况下, android系统会自己找到合适的activity, service, 或者 broadcast receivers来响应intent. 三者的intent相互独立互不干扰.
Intent的属性:
component(组件):目的组件
action(动作):用来表现意图的行动
category(类别):用来表现动作的类别
data(数据):表示与动作要操纵的数据
type(数据类型):对于data范例的描写
extras(扩展信息):扩展信息
Flags(标志位):期望这个意图的运行模式
**1,component(组件):目的组件**
Component属性明确指定Intent的目标组件的类名称。(属于直接Intent)
ComponentName对象包含的构造器:
ComponentName(String pkg,String cls)创建在pkg所在报下的cls类所对应的组件
ComponentName(Context pkg,String cls)创建在pkg所在报下的cls类所对应的组件
ComponentName(Context pkg,Class cls)创建在pkg所在报下的cls类所对应的组件
一个ComponentName需要指定包名和类名--这就可以唯一确定一个组件类
另外Intent可以根据给定的组件类去启动特定的组件,Intent有下面的方法:
setClass(Context packageContext,Class cls):设置该Intent将要启动的组件对应的类
setClassName(Context packageContext,String className):设置该Intent将要启动的组件对应的类
setClassName(String packageContext,String className):设置该Intent将要启动的组件对应的类
**以上方法中的两个参数其实就确定了一个Component组件**
Intent类型分为显式Intent(直接类型)、隐式Intent(间接类型)。官方建议使用隐式Intent。上述属性中,component属性为直接类型,其他均为间接类型。
启动第二个Activity时:
~~~
// 为bn按钮绑定事件监听器
bn.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View arg0)
{
// 创建一个ComponentName对象
ComponentName comp = new ComponentName(ComponentAttr.this,
SecondActivity.class);
Intent intent = new Intent();
// 为Intent设置Component属性
intent.setComponent(comp);
// Intent intent = new Intent(ComponentAttr.this,
// SecondActivity.class);
startActivity(intent);
}
});
~~~
可以这样写:
~~~
Intent intent = new Intent();
//setClass函数的第一个参数是一个Context对象
//Context是一个类,Activity是Context类的子类,也就是说,所有的Activity对象,都可以向上转型为Context对象
//setClass函数的第二个参数是一个Class对象,在当前场景下,应该传入需要被启动的Activity类的class对象
intent.setClass(MainActivity.this, SecondActivity.class);
startActivity(intent);
~~~
还可以这样写:
~~~
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
startActivity(intent);
~~~
**2、Action(动作):用来表现意图的行动**
Action 是一个用户定义的普通字符串,代表该Intent索要完成的一个抽象“动作”。用于描述一个 Android 应用程序组件,一个 Intent Filter 可以包含多个 Action。在 AndroidManifest.xml 的Activity 定义时,可以在其 节点指定一个 Action列表用于标识 Activity 所能接受的“动作”
Action要完成的知识一个抽象的动作,这个动作具体由哪个组件(Activity,Service,BroadcastReceiver)来完成,Action这个字符不管。比如Android提供的标准Action:Intent.ACTION_VIEW,它值表示一个抽象的查看动作,但具体什么,启动哪个Activity来看,Intent.ACTION_VIEW并不知道---这取决于Activity的配置,只要某个Activity的配置中包含了该ACTION_VIEW,该Activity就有可能被启动。
一句话总就是说,哪个Activity的intent-filter...>配置中有Intent设置的Action属性,就可能被启动。
MainActivity .java
~~~
public class MainActivity extends Activity {
public final static String ACTION="com.hust.actiontest";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn=(Button) findViewById(R.id.button1);
btn.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent=new Intent();
intent.setAction(MainActivity.ACTION);
startActivity(intent);
}
});
}
~~~
~~~
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.hust.actionattrtest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="20"
android:targetSdkVersion="22" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
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=".SeclondActivity"
android:label="@string/title_activity_seclond" >
<intent-filter>
<!-- 指定该Activity能响应Action为指定字符串的Intent -->
<action android:name="com.hust.actiontest" />
<!-- 指定该Action能响应Category属性为指定字符串的Intent -->
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
~~~
SecondActivity.java
~~~
public class SeclondActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_seclond);
TextView show = (TextView) findViewById(R.id.show);
// 获取该Activity对应的Intent的Action属性
String action = getIntent().getAction();
// 显示Action属性
show.setText("Action为:" + action);
}
~~~
因为SeclondActivity的的action有com.hust.actiontest所以就可能被MainActivity启动
使用Intent的Action属性启动组件的过程大概是:主Activity的Intent的Action属性设置为一个字符串str比如“com.hust.edu”,然后再去Manifest.xml中查找各个Activity组件的的action是否有这个字符串str=com.hust.edu,如果有,这个Activity可能被启动。