Intent
Intent是Android程序中各组件之间进行交互的一种重要方式,它不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据。
Intent大致可以分为两种:显式Intent和隐式Intent
1.显式Intent
Intent有多个构造函数的重载,其中一个是Intent(Context packageContext,Calss<?> cls),这个构造函数接收两个参数,第一个参数Context要求提供一个启动活动的上下文,第二个参数Class则是指定想要启动的目标活动,通过这个函数就可以构建出Intent的“意图”。Activity类中提供了一个startActivity()方法,这个方法是专门用于启动活动的,它接收一个Intent参数,我们将构建好的Intent传入就可以启动目标活动了。
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);
2.隐式Intent
相较于显示Intent,隐式Intent含蓄了许多,它并不明确的指出我们想要启动哪一个活动,而是指定了一系列更为抽象的action和category等信息,然后去交给系统去分析这个Intent,并帮我们找出合适的活动启动。
指定当前活动可以响应的action和category。
打开AndroidManifest.xml
在指定活动<activity>标签下配置<intent-filter>的内容
<activity android:name=".SecondActivity">
<intent-filter>
<action android:name="com.demo.applicationtext.ACTION_START" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
只有<action>和<category>中的内容同时能够匹配上Intent中指定的action和category时,这个活动才能响应该Intent
创建Intent
Intent intent = new Intent("com.demo.applicationtext.ACTION_START");
startActivity(intent);
PS:
(1)android:name="android.intent.category.DEFAULT"是一种默认的category,在调用startActivity()方法时会自动将其添加到Intent中
(2)每个Intent中只能指定一个action,能指定多个category。
Intent intent = new Intent("com.demo.applicationtext.ACTION_START");
intent.addCategory("com.demo.applicationtext.MY_CATEGORY");
startActivity(intent);
在想要响应的Activity中也添加自定义的category
<activity android:name=".SecondActivity">
<intent-filter>
<action android:name="com.demo.applicationtext.ACTION_START" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="com.demo.applicationtext.MY_CATEGORY" />
</intent-filter>
</activity>
3.更多隐式Intent的用法
使用隐式Intent我们不仅可以打开自己程序里的活动,还可以启动其他程序的活动
比如我们需要打开一个网页就不用我们自己去写一个浏览器,而是调用系统的浏览器
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);
setData()方法接收一个Uri对象,主要用于指定当前Intent正在操作的数据,而这些数据都是以字符串的形式传入到Uri.parse()方法中进行解析。
与此对应也可以在自己的程序中指定当前活动可以处理什么样的数据,在<intent-filter>中再配置一个<data>标签,在里面配置可以响应的数据类型。
除了intent.setData(Uri.parse("http://www.baidu.com"));中http协议外,我们还可以指定很多其他协议,比如geo表示显示地理位置,tel表示拨打电话,下面展示拨打电话的例子
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);
4.向下一个活动传递数据
Intent中提供了一系列putExtra()方法的重载,我们可以将需要传递的数据暂存在Intent中,到下一个活动中再把数据取出来即可
//以显式Intent 将需要传递的数据用putExtra()方法传入Intent中
String data = "Intent 传递数据";
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
intent.putExtra("extra_data", data);
startActivity(intent);
在目标活动中
Intent intent = getIntent();
String data = intent.getStringExtra("extra_data");
Log.i("SecondActivity", data);
用getIntent()方法获取用于启动该活动的Intent
然后取出Intent的数据打印出来
5.返回数据给上一个活动
Activity中有一个startActivityForResult()方法用于启动活动,不同的是这个方法期望在目标活动销毁时返回数据给上一个活动。
Intent intent=new Intent(MainActivity.this, SecondActivity.class);
//第一个参数为intent,第二个参数为请求码,用于在后面回调中判断数据的来源
startActivityForResult(intent,1);
在目标活动中添加返回数据的逻辑
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//创建一个Intent用于回传数据
Intent intent = new Intent();
intent.putExtra("data_return", "回传数据");
//setResult()方法专门用于向上一个活动返回数据
//第一个参数用于向上一个活动返回处理结果,一般只使用RESULT_OK和RESULT_CANCELED两个值
//第二个参数则把带有数据的Intent传递回去
setResult(RESULT_OK, intent);
//调用finish()销毁当前活动
finish();
}
});
由于是使用startActivityForResult()方法启动的目标活动,在目标活动销毁之后会回调上一个活动的onActivityResult()方法来接收数据,所以我们要在第一个活动中重写该方法来得到返回的数据:
//onActivityResult()方法带有三个参数 requestCode resultCode data
//requestCode:启动活动时传入的请求码
//resultCode:返回数据时的处理结果
//data:携带数据的Intent
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
switch (requestCode) {
case 1:
if (resultCode== RESULT_OK) {
String returnedData = data.getStringExtra("data_return");
Log.i("MainActivity", returnedData);
}
break;
default:
}
}
当用户是通过Back键返回上一活动,而并不是通过按钮返回,则在活动中重写onBackPressed()方法即可解决这个问题
@Override
public void onBackPressed() {
Intent intent = new Intent();
intent.putExtra("data_return", "回传数据");
setResult(RESULT_OK, intent);
finish();
}
这样当用户按下Back键就会执行onBackPressed()方法中的代码。