Android中Intent详解(一)

时间:2022-07-06 22:39:50

Intent是一种消息传递机制,它可以在应用程序内使用,也可以在应用程序间使用,主要用途分为:

1.使用类名显示的启动一个特定的Activity或Service

  2.启动Activity或Service来执行一个动作的Intent,通常需要使用特定的数据,或者对特定的数据执行动作

  3.广播某个事件已经发生

Intent最常见的一个用法是显示的(通过指定要装载的类)或隐式的(通过请求对一条数据执行某个动作)启动新的activity,在后一种情况下,动作不一定由调用应用程序中的Activty执行。

Intent也可以在系统范围内发送广播消息。应用程序可以注册一个Broadcast Receiver来监听相应这些广播的Intent。Android就是通过广播Intent来公布系统事件,比如网络连接状态或者电池电量的改变。

1.使用Intent来启动activity

Intent最常见的用途就是绑定应用程序组件,并在应用程序之间进行通信。

1.1 显示启动新Activity

要显示的选择要启动的Activity类,可以创建一个新的Intent来指定当前Activity的上下文以及要启动的Activity的类,然后把这个Intent传递给startActivity,代码如下:

<span style="white-space:pre"></span>Intent intent = new Intent(getApplicationContext(), Activity1.class);
startActivity(intent);
在调用startActivity之后,新的Activity将会被创建 启动和恢复运行,他会移动到Activity栈的顶部。

调用新的Activity的finish或按下设备的返回按钮将关闭该Activity,并把它从栈中移除。

1.2 隐式的Intent和运行时迟绑定

隐式的Intent提供了一种机制,可以让匿名的应用程序组件相应请求动作,也就是说,可以要求系统启动一个可执行给定动作的Activity,而不必知道需要那启动哪个应用程序或Activity。

假如在我们的应用程序中,可以让用户点击某个按钮实现拨打电话的操作,那么可以使用隐式的Intent来完成,代码如下:

<span style="font-size:14px;"><span style="white-space:pre"></span>intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:010-123456"));
startActivity(intent);</span>
Android会解析这个Intent,并启动一个新的Activity,该Activity会提供对这个电话号码进行拨号的动作。

当构建一个隐式的Intent时,需要指定一个要执行的动作,另外,也可以提供执行那个动作需要的uri数据,还可以通过向Intent添加extra来向目标Intent发送额外的数据。

Extra是一种想Intent附加基本类型值得机制。

如果多个Activity都能执行指定的动作,则会向用户呈现各种选项。Intent Resolution解析过程是通过分析注册的Broadcast Receiver来完成的。

许多本地应用程序都提供了能够对特定数据执行动作的Activity,第三方应用程序可以通过注册来支持新的动作,也可以提供本地动作的替换提供器。

1.3 确定Intent能否解析

在自己的应用程序中,利用第三方应用程序的Activity和Service是十分方便的,但是我们无法保证用户设备上安装了特定的某个应用程序或者设备上有能够处理我们的请求的应用程序。因此,在调用startActivity之前,确定调用是否可以解析为一个Activity是一种很好的选择。

通过调用Intent的resolveActivity方法,并向该方法传入包管理器,可以对包管理器进行查询,确定是否有Activity能够启动以响应该Intent。代码如下:

<span style="font-size:14px;"><span style="white-space:pre"></span>Intent intent = new Intent(getApplicationContext(), Activity1.class);
PackageManager pm = getPackageManager();
ComponentName cn = intent.resolveActivity(pm);
if (cn == null) {</span>
<span style="font-size:14px;">//没有activity可以处理这个动作,检查google play是否可以Uri marketUri = Uri.parse("market://search?q=pname:com.happy.demo");Intent marketIntent = new Intent(Intent.ACTION_VIEW).setData(marketUri);if(marketIntent.resolveActivity(pm)!=null){startActivity(marketIntent);}else{Log.i(TAG, "sorry,无法解析");}<span style="white-space:pre"></span>} else {startActivity(intent);}</span>
如果没有找到相应的Activity,可以选择禁用相关的功能,也可以引导用户去应用市场中找合适的应用程序。

1.4 从Activity返回结果

通过startActivity启动的Activity独立于父Activity,并且在关闭时不会提供任何反馈。

当需要反馈时,可以启动一个Activity作为另一个Activity的子Activity,用它向父Activity传递结果,子Activity只是以一种不同的方式启动的Activity。

当子Activity结束时,它会出发调用Activity内的事件处理程序onActivityResult。对于一个Activity为另一个Activity提供数据输入的情况,子Activity特别适用。

startActivityForResult的工作形式和startActivity相似,但是有一个重要的区别,除了传入显示或隐式Intent外,还需要传入一个请求码,这个值将在后面用户唯一标识返回了结果的子Activity。代码如下:

<span style="white-space:pre"></span>private static final String TAG = "MainActivity";
private static final int SHOW_ACTIVITY_01 = 1;
@Override
<span style="white-space:pre"></span>protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Intent intent = new Intent(getApplicationContext(), Activity1.class);startActivityForResult(intent, SHOW_ACTIVITY_01);
<span style="white-space:pre"></span>}
当准备好返回子Activity时,可以在调用finish以前调用setResult,以便向调用Activty返回一个结果。

setResult方法有两个参数:结果码和表示为Intent的结果数据本身。

结果码是运行子Activity的结果----通常是Activity.RESULT_OK或者Activity.RESULT_CANCELED。当这两个值不能满足我们需求时,可以使用自己的响应码,setResult支持任意的整数值。

作为结果返回的Intent通常包含某段内容(比如选择的联系人 电话号码)的URI和用户返回附加信息的一组extra。代码如下:

<span style="font-size:14px;"><span style="white-space:pre"></span>long selectedItemId = listView.getSelectedItemId();
Uri selectedHorse = Uri.parse("content://horses/"+selectedItemId);
intent = new Intent(Intent.ACTION_PICK, selectedHorse);</span>
<span style="font-size:14px;">setResult(Activity.RESULT_OK, intent);finish();</span>
如果用户通过按下硬件返回键关闭Activity,或者在调用finish之前没有调用setResult,那么结果码将被设置为Result_CANCELED,结果Intent将被设置为null。

当子Activity关闭的时候,将会触发其调用Activity的onActivityResult事件处理程序,可以对其进行重写来处理返回结果,其方法接收三个参数,分别为:

请求码:在启动正在返回的Activity时使用的请求码

结果码:子Activity设置的结果码,用于说明其结果。

数据:Intent用来包装所有返回的数据,可能包含代表指定内容的uri,也可能是子Activity设置的Intent内以extra形式返回的数据。

代码如下:

<span style="font-size:14px;"><span style="white-space:pre"></span>@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case SHOW_ACTIVITY_01:
if (requestCode == Activity.RESULT_OK) {
//TODO
}
break;

case SHOW_ACTIVITY_02:
if (requestCode == Activity.RESULT_OK) {
//TODO
}
break;
}

}</span>
好了,Intent第一篇就简单写到这了,目测没什么难的,都是基础性的东西。