Android开发入门基础知识——Intent详解
参考1:http://www.vogella.com/tutorials/AndroidIntent/article.html
参考2:https://developer.android.com/reference/android/content/Intent.html
一、Intent简介
在官方文档的定义中,一个intent(意图)代表一个即将进行的操作的抽象描述。它是用来连接Android的应用组件的。比如,它可以和startActivity
一起启动其他的Activity
,和broadcastIntent
一起发送消息到BoradcastReceiver
组件,和startService(Intent)
或者bindService(Intent,ServiceConnection,int)
一起与其他的Service通信。
意图提供了一种在不同应用之间进行任务运行绑定的工具。它最重要的应用是启动活动(Activity,Android中的Activity就是一个页面的意思)。意图是异步消息,它可以帮助一个应用组件从另一个Android组件中请求功能。
Intent是一个对象,即android.content.Intent
。在Android中,复用其他应用组件称之为任务。一个应用可以访问其他组件来实现任务。比如,你的应用可以触发另一个Android系统的组件,比如管理相册,即使你的应用没有这个组件也可以。在管理相册中,你选择一个照片,然后返回使用选择的照片,如下图所示。

下面我们将描述Intent的一些基本内容。
1.1、启动activities或者services
为了启动一个活动(Activity),我们可以使用startActivity(intent)
,这个方法定义在Context对象中,有Activity扩展。
# Start the activity connect to the
# specified class
Intent i = new Intent(this, ActivityTwo.class);
startActivity(i);
启动服务也是类似,使用 startService(Intent)
这个方法就行了。
1.2、发送显式或者隐式的Intent
Android支持显式和隐式两种intents使用方式。一个应用可以直接在intent中定义目标组件(显式),也可以通过intent数据来向系统请求评估注册的组件(隐式)。
显示intents明确定义了那些应当被系统调用的组件。它是通过java类来作为识别器的。显式intents通常在一个应用中以类的形式被应用开发者控制。比如,下面的这个语句就表示使用显示intent来让系统启动一个activity。
Intent i = new Intent(this, ActivityTwo.class);
i.putExtra("Value1", "This value one for ActivityTwo ");
i.putExtra("Value2", "This value two ActivityTwo");
隐式intents会制定那个动作被执行,那些数据要提供给这个动作。如果隐式的intents被发送给Android系统,那么它会搜寻所有组件中注册的这个动作,并适配这个数据。如果只有一个组件被发现符合要求,那就直接调用,如果有多个组件符合要求,就会弹出选择框让用户自己选择。比如,下面的代码是告诉Android系统来查看一个页面。所有已经安装的网络浏览器都应该通过intent filter被注册了。
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.datalearner.com"));
startActivity(i);
1.3、确定有效的意图接收器
有时候你需要确定某个组件是否在系统中注册。比如,你希望检查某个意图接收器是否可用,同时如果该组件可用的话,你希望调用它,并将其传给下面的方法。
public static boolean isIntentAvailable(Context ctx, Intent intent) {
final PackageManager mgr = ctx.getPackageManager();
List<ResolveInfo> list = mgr.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
return list.size() > 0;
}
根据返回的结果你可以调整你的应用,比如设置禁用或者隐藏某些菜单等。
1.4、Intent作为事件触发器使用
Intents也可以发送广播信息到Android系统中。一个广播接收器可以注册一个事件,当这个事件被发送的时候可以出现通知。我们的应用可以注册系统时间,比如新邮件到来,系统启动完毕或者接收到电话的时候发出反应动作。
二、Activityies之间使用Intent进行数据传送
2.1、将数据传送给目标组件
一个intent包含了某些头部信息,如期望产生的动作、类型等。我们也可以自己使用Bundle
类来添加一些额外的信息,在接受方一般使用getExtras()
来获取信息。
同样,我们也可以直接使用putExtras()
来添加信息。Extras是键/值对,可以添加基本类型如int/float等,也可以添加Bundle/Parcelable等。
接受组件使用getAction()
和getData()
方法接收数据。
例如,很多应用都允许你和其他人共享信息,比如Facebook、Twitter等,你可以发送数据到这些组件去。如下代码:
// this runs, for example, after a button click
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(android.content.Intent.EXTRA_TEXT, "News for you!");
startActivity(intent);
2.2、从一个子活动(sub-activity)收取结果数据
一个活动(页面)可以通过手机的返回按钮结束页面。这种活动一般通过startActivity(Intent)
调用,那么页面关闭就结束了。而有时候我们希望这个页面关闭的时候返回一些信息。那么我们就通过startActivityForResult()
这个方法调用。一旦这个子页面结束,它就会执行onActivityResult()
方法,并返回结果。
在startActivityForResult()
这个方法中,我们可以指定一个结果代码来觉得你希望启动哪个活动(页面)。这个结果代码将会返回给你。同样,在activity启动的时候也可以发送一个代码让调用者知道这个活动是否被取消。子活动可以通过使用finish()
方法创建一个新的intent,然后把数据放进去。它也可以把一些结果通过setResult()
方法放入数据。如下图所示:

如下代码是演示使用startActivityForResult()
来启用一个子页面的过程:
public void onClick(View view) {
Intent i = new Intent(this, ActivityTwo.class);
i.putExtra("Value1", "This value one for ActivityTwo ");
i.putExtra("Value2", "This value two ActivityTwo");
// set the request code to any code you like,
// you can identify the callback via this code
startActivityForResult(i, REQUEST_CODE);
}
当子页面完成之后,子页面可以通过创建Intent返回(这里可以添加一些数据),这个过程在子页面中的finish()
方法中定义:
@Override
public void finish() {
// Prepare data intent
Intent data = new Intent();
data.putExtra("returnKey1", "Swinging on a star. ");
data.putExtra("returnKey2", "You could be better then you are. ");
// Activity finished ok, return the data
setResult(RESULT_OK, data);
super.finish();
}
子页面关闭后,原来的页面将执行onActivityResult()
方法获取子页面返回的信息:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK && requestCode == REQUEST_CODE) {
if (data.hasExtra("returnKey1")) {
Toast.makeText(this, data.getExtras().getString("returnKey1"),
Toast.LENGTH_SHORT).show();
}
}
}
三、通过intent filter注册Intent
Intent通常也会发送信号给Android系统,当某个事件发生的时候应当如何做。比如,我们的应用通常会通过一个intent来为某个URL打开浏览器:
String url = "http://www.datalearner.com";
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
那么,Android系统是如何识别出某个组件对某个intent的反应呢?这就是通过intent filter向系统注册。intent filter指定了什么样的intent要对哪一种activity,service或者是broadcast接收器做出反映,这是通过定义某个组件的功能实现的。
Android系统规定,既可以通过AndroidManifest.xml也可以通过java代码来注册intent filters。
如果一个intent被发送到Android系统中,那么Android系统将会运行一个接收器决定程序。当数个组件注册了同一个intent filter,那么用户将会决定启动哪一个。
当然,我们也可以通过intent filters注册多个事件。如下代码所示,我们向系统注册,当用户打开一个网页的时候,出发一个intent:
<activity android:name=".BrowserActivitiy"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http"/>
</intent-filter>
</activity>
另外,下面的代码是注册ACTION_SEND的intent,表示分享某个文本时候,添加这个intent作为分享:
<activity
android:name=".ActivityTest"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
四、练习:activities使用Intent通信
欢迎大家关注DataLearner官方微信,接受最新的AI技术推送
