Intent 是Android程序中各组件之间进行交互的一种方式,它不仅可以指明当前组件想要的动作,还可以在不同组件之间传递数据,Intent一般可被用于启动活动,启动服务,以及发送广播等场景。
Intent的用法大致分为两种:显示Intent 和隐式Intent.
显式Intent:
Intent有多个构造函数的重载,
其中一个是
Intent(Context packageContext, Class<?> cls)
。
这个构造函数接收两个参数,第一个参数
Context
要求提供一个启动活动的上下文,第二个
参数
Class
则是指定想要启动的目标活动,通过这个构造函数就可以构建出
Intent
的“意图”.
//Intent,传入FirstActivity.this 作为上下文,传入SecondActivity.class作为目标活动
Intent intent = new Intent(FirstActivity. this ,SecondActivity. class );
Intent intent = new Intent(FirstActivity. this ,SecondActivity. class );
startActivity(intent);
startActivity()
方法来执行这个
Intent
。
可以看到,我们已经成功启动
SecondActivity
这个活动了。如果你想要回到上一个活动
怎么办呢?很简单,按下
Back
键就可以销毁当前活动,从而回到上一个活动了。
使用这种方式来启动活动,
Intent
的“意图”非常明显,因此我们称之为显式
Intent
。
隐式Intent
相比于显式
Intent
,隐式
Intent
则含蓄了许多,它并不明确指出我们想要启动哪一个活
动,而是指定了一系列更为抽象的
action
和
category
等信息,然后交由系统去分析这个
Intent
,
并帮我们找出合适的活动去启动。
第一,在AndroidManifest.xml中,添加如下代码:
<activity android:name=".SecondActivity" >
<intent-filter>
<action android:name="com.example.activitytest.ACTION_START" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
在
<action>
标签中我们指明了当前活动可以响应
com.example.activitytest.ACTION_
START
这个
action
,而
<category>
标签则包含了一些附加信息,更精确地指明了当前的活动
能够响应的
Intent
中还可能带有的
category.
只有
<action>
和
<category>
中的内容同时能够匹
配上
Intent
中指定的
action
和
category
时,这个活动才能响应该
Intent
。
修改
FirstActivity
中按钮的点击事件,代码如下所示:
button1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.activitytest.ACTION_START");
startActivity(intent);
}
});
使用了
Intent
的另一个构造函数,直接将
action
的字符串传了进去,表
明我们想要启动能够响应
com.example.activitytest.ACTION_START
这个
action
的活动。那前
面不是说要
<action>
和
<category>
同时匹配上才能响应的吗? 怎么没看到哪里有指定
category
呢? 这是因为
android.intent.category.DEFAULT
是一种默认的
category
, 在调用
startActivity()
方法的时候会自动将这个
category
添加到
Intent
中。
Intent 中可以通过
addCategory()
方法来添加一个
category
更多隐式Intent的用法
用隐式
Intent
,我们不仅可以启动自己程序内的活动,还可以启动其他程序的活动,
这使得
Android
多个应用程序之间的功能共享成为了可能
button1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);
}
});
这里我们首先指定了
Intent
的
action
是
Intent.ACTION_VIEW
,这是一个
Android
系统内
置的动作,其常量值为
android.intent.action.VIEW
。然后通过
Uri.parse()
方法,将一个网址字
符串解析成一个
Uri
对象,再调用
Intent
的
setData()
方法将这个
Uri
对象传递进去。
intent.setData(Uri.parse("tel:10086"));
首先指定了
Intent
的
action
是
Intent.ACTION_DIAL
,这又是一个
Android
系统的内置动
作。然后在
data
部分指定了协议是
tel
,号码是
10086
//显式Intent的使用方法
//Intent intent =new Intent(FirstActivity.this,SecondActivity.class);
//隐式Intent的使用方法
// Intent intent=new Intent("com.example.activitytest.ACTION_START");
// intent.addCategory("com.example.activitytest.MY_CATEGORY");
//链接到浏览器
// Intent intent = new Intent(Intent.ACTION_VIEW);
// intent.setData(Uri.parse("http://www.baidu.com"));
//链接到电话10086电话
Intent intent=
new
Intent(Intent.
ACTION_DIAL
);
intent.setData(Uri.parse(
"tel:10086"
));
startActivity(intent);
利用Intent传递数据
Intent
中提供了一系列 putExtra()方法的重载
,可
以把我们想要传递的数据暂存在 Intent 中,启动了另一个活动后,只需要把这些数据再从
Intent 中取出就可以了。
注意这里putExtra()方法接收两个参数,第一个参数是键,用于后面从Intent
中取值,第二个参数才是真正要传递的数据。
在第一个FirstActivity.java中存入putExtra:
String data=
"Hello SecondActivity"
;
Intent intent= new Intent(FirstActivity. this ,SecondActivity. class );
intent.putExtra( "extra_data" ,data);
Intent intent= new Intent(FirstActivity. this ,SecondActivity. class );
intent.putExtra( "extra_data" ,data);
startActivity(intent);
在第二个SecondActivity.java中取出:
Intent intent=getIntent();
String data=intent.getStringExtra( "extra_data" );
String data=intent.getStringExtra( "extra_data" );
Log.d("SecondActivity",data);
在第二个SecondActivity.java中取出:
Intent intent=getIntent();
String data=intent.getStringExtra( "extra_data" );
String data=intent.getStringExtra( "extra_data" );
Log.d("SecondActivity",data);
, 然后调用
getStringExtra()
方法,传入相应的键值,就可以得到传递的数据了。这里由于我们传递的是
字符串,所以使用
getStringExtra()
方法来获取传递的数据,如果传递的是整型数据,则使用
getIntExtra()
方法,传递的是布尔型数据,则使用
getBooleanExtra()
方法,以此类推。
返回数据给上一个活动
返回上一个活动只需要按一下Back键就可以了,没有一个用于启动活动Intent来传递数据。Activity 中还有一个startActivityForResult()方法启动活动的,但这个方法期望在活动销毁的手能够返回一个结果给上一个活动。
StartActivityForResult()方法接收两个参数,第一个参数是Intent,第二个参数是请求码,用于在之后的回调中判断数据的来源。
在FirstActivity中:
button1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivityForResult(intent, 1);
}
});
在SecondActivity中给按钮注册点击事件,并在点击事件中添加返回数据的逻辑:
public class SecondActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.second_layout);
Button button2 = (Button) findViewById(R.id.button_2);
button2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.putExtra("data_return", "Hello FirstActivity");
setResult(RESULT_OK, intent);
finish();
}
});
}
}
构建了一个 Intent,只不过这个Intent 仅仅是用于传递数据而已,它没有指定任何的“意图”。紧接着把要传递的数据存放在 Intent 中,然后调用了setResult()方法。这个方法非常重要,是专门用于向上一个活动返回数据的。setResult()方法接收两个参数, 第一个参数用于向上一个活动返回处理结果, 一般只使用 RESULT_OK 或RESULT_CANCELED 这两个值,第二个参数则是把带有数据的 Intent 传递回去,然后调用
了finish()方法来销毁当前活动。由于我们是使用 startActivityForResult()方法来启动SecondActivity 的,在SecondActivity被销毁之后会回调上一个活动的 onActivityResult()方法,因此我们需要在FirstActivity 中重
写这个方法来得到返回的数据
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case 1:
if (resultCode == RESULT_OK) {
String returnedData = data.getStringExtra("data_return");
Log.d("FirstActivity", returnedData);
}
break;
default:
}
}
onActivityResult()方法带有三个参数,第一个参数requestCode,即我们在启动活动时传
入的请求码。第二个参数resultCode,即我们在返回数据时传入的处理结果。第三个参数data,
即携带着返回数据的 Intent。由于在一个活动中有可能调用 startActivityForResult()方法去启
动很多不同的活动,每一个活动返回的数据都会回调到 onActivityResult()这个方法中,因此
我们首先要做的就是通过检查 requestCode 的值来判断数据来源。确定数据是从
SecondActivity 返回的之后,我们再通过 resultCode 的值来判断处理结果是否成功。最后从
data 中取值并打印出来,这样就完成了向上一个活动返回数据的工作。
如果用户在
SecondActivity
中并不是通过点击按钮,而是通过按下
Back
键回到
FirstActivity
,这样数据不就没法返回了吗?没错,不过这种情况还是很好处理
的,我们可以通过重写
onBackPressed()
方法来解决这个问题,代码如下所示:
@Override
public void onBackPressed() {
Intent intent = new Intent();
intent.putExtra("data_return", "Hello FirstActivity");
setResult(RESULT_OK, intent);
finish();
}