Android 学习笔记 —— Intent 的使用
Intent 的使用
显式 Intent
使用 Intent(Context packageContext, Class<?> cls) 构造函数创建 Intent 对象,第一个参数为上下文 Context,第二个参数指定想要启动的 Class。最后将 Intent 传入 startActivity() 方法中即可。
Intent intent = new Intent(CurrentActivity.this, TargetActivity.class);
startActivity(intent);
隐式 Intent
在清单文件 AndroidManifest.xml 中,通过在对应 <activity> 标签下配置 <intent-filter> 可以指定当前 Activity 能够响应的 action 和 category。
<activity
android:name=".CurrentActivity"
<intent-filter>
<action android:name="ACTION_DIY" />
<category android:name="CATEGORY_DIY" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<action> 标签指定当前 Activity 可以响应 ACTION_DIY 这个 action,<category> 标签则指定可以响应 CATEGORY_DIY 这个 category。
Intent intent = new Intent("ACTION_DIY");
intent.addCategory("CATEGORY_DIY");
startActivity(intent);
android.intent.category.DEFAULT 是一种默认的 category,在调用 startActivity() 方法时会自动将这个 category 添加到 Intent 中 .
注意:在使用隐式 Intent 启动时清单文件下对应 <activity> 中必须存在该默认 category,否则会匹配失败然后报错。
隐式 Intent 的更多用法 —— 调用系统浏览器打开指定网页
先指定 Android 系统内置的 action Intent.ACTION_VIEW,其常量值为 android.intent.action.VIEW。然后通过 Uri.parse() 方法将一个网址字符串解析成一个 Uri 对象,并将其传入 Intent 的 setData() 方法中.
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("https://www.baidu.com"));
startActivity(intent);
与此对应,<intent-filter> 下的 <data> 标签可以更精确地指定当前 Activity 能够响应的数据。<data> 标签下的主要配置内容如下:
- android:scheme。用于指定数据的协议部分,如
http。 - android:host。用于指定数据的主机名部分,如
www.baidu.com。 - android:port。用于指定数据的端口部分,一般紧随在主机名之后。
- android:path。用于指定主机名和端口之后的部分,如一段网址中跟在域名之后的内容。
- android:mineType。用于指定可以处理的数据类型,允许使用通配符的方式进行指定。
<activity
android:name=".CurrentActivity"
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
</intent-filter>
</activity>
如上指定 <data android:scheme="http" />,就可以响应所有的 http 协议的 Intent。除了 http 协议外,还可以指定很多其他协议,如 geo 表示显示地理位置、tel 表示拨打电话。
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);
向下一个 Activity 传递数据
使用 Intent 提供的 putExtra() 方法可以把数据暂存到 Intent 中,调用 startActivity() 方法后即可将 Intent 中附带的数据传递给下一个 Activity。
// CurrentActivity.java
Intent intent = new Intent(CurrentActivity.this, TargetActivity.class);
intent.putExtra("hello", "Hello!");
intent.putExtra("amie", "I am Amie.");
startActivity(intent);
目标 Activity 启动后使用 getIntent() 方法获取到用于启动它的 Intent 对象,这样就可以获取传递过来的数据了。使用 Intent 提供的 getExtras() 方法可以获取所有附带数据并返回一个 Bundle 对象,也可以使用 getStringExtra() 直接获取对应的字符串数据。此外 getIntExtra(),getBooleanExtra() 等方法可以获取对应数据类型的数据。
// TargetActivity.java
Intent intent = getIntent();
Bundle bundle = intent.getExtras();
String extra = intent.getStringExtra("amie");
返回数据给上一个 Activity
已经过时,推荐使用 Activity Result API 中的 startActivityForResult()registerForActivityResult(ActivityResultContract, ActivityResultCallback) 方法。
ActivityResultLauncher<I> registerForActivityResult(ActivityResultContract<I, O> contract, ActivityResultCallback<O> callback) 方法的官方文档:
Register a request to start an activity for result, designated by the given contract. This creates a record in the registry associated wit this caller, managing request code, as well as conversions to/from Intent under the hood. This must be called unconditionally, as part of initialization path, typically as a field initializer of an Activity or Fragment.
Params:
contract – the contract, specifying conversions to/from Intents
callback – the callback to be called on the main thread when activity result is available
Type parameters:
<I> – the type of the input(if any) required to call the activity
<O> – the type of output returned as an activity result
Returns:
the launcher that can be used to start the activity or dispose of the prepared call.
翻译:
通过指定的合约,注册一个用于启动 Activity 并获取返回结果的请求。这会在与该调用者关联的注册表中创建一条记录,管理请求码以及与 Intent 之间的转换。这必须作为初始化路径中的一部分,被无条件调用,通常作为 Activity 或 Fragment 的字段初始化器。
参数:
contract - 合约,指定与 Intent 之间的转换
callback - 当活动结果可用时在主线程上调用的回调
参数类型:
<I> – 调用 Activity 所需的输入类型(如果有)
<O> – 作为 Activity 返回结果的输出类型
返回:
可用于启动 Activity 或处理准备好的调用的启动器。
在 Activity Result API 中想要执行 Intent,需要将该 Intent 对象传入 ActivityResultLauncher 对象的 launch() 方法中。
注意:文档中强调这必须作为初始化路径中的一部分,也就是说 ActivityResultLauncher 必须在 Activity 的 onCreate() 方法或 Fragment 的 onCreate()、onAttach() 方法调用前注册,然后在需要使用的地方调用其 launch() 方法。
public class CurrentActivity extends AppCompatActivity implements View.OnClickListener {
// 在 onCreate() 方法前注册
ActivityResultLauncher<Intent> launcher =
registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == RESULT_OK) {
// TODO
}
}
});
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
}
@Override
public void onClick(View v) {
// ...
Intent intent = new Intent(ContextActivity.this, TargetActivity.class);
intent.putExtra("amie", "Hello! I am Amie.");
launcher.launch(intent);
}
}
在 TargetActivity 中,只需调用 setResult() 方法,并将处理结果码和带有数据的 Intent 传入其中,最后调用 finish() 方法即可销毁当前 Activity 并返回数据给上一个 Activity。
注意:当且仅当调用 finish() 方法后才可以回调成功,使用其他方式(如 startActivity() 启动等)回到上一个 Activity 都无法回调成功。
public class TargetActivity extends AppCompatActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
}
@Override
public void onClick(View v) {
// ...
Intent intent = new Intent();
intent.putExtra("vastness", "Hi! I am Vastness.");
setResult(RESULT_OK, intent);
finish();
}
}
本文介绍了Android中Intent的基本概念,包括显式Intent和隐式Intent的使用方法,如何通过Intent在不同Activity间传递数据,以及如何返回数据给上一个Activity。还详细解释了使用ActivityResultAPI进行回调的过程。
2831

被折叠的 条评论
为什么被折叠?



