Android开发入门基础知识——Intent详解

2012年5月8日11:05:59 发表评论 12 views

一、Intent简介

在官方文档的定义中,一个intent(意图)代表一个即将进行的操作的抽象描述。它是用来连接Android的应用组件的。比如,它可以和startActivity一起启动其他的Activity,和broadcastIntent一起发送消息到BoradcastReceiver组件,和startService(Intent)或者bindService(Intent,ServiceConnection,int)一起与其他的Service通信。

意图提供了一种在不同应用之间进行任务运行绑定的工具。它最重要的应用是启动活动(Activity,Android中的Activity就是一个页面的意思)。意图是异步消息,它可以帮助一个应用组件从另一个Android组件中请求功能。

Intent是一个对象,即android.content.Intent。在Android中,复用其他应用组件称之为任务。一个应用可以访问其他组件来实现任务。比如,你的应用可以触发另一个Android系统的组件,比如管理相册,即使你的应用没有这个组件也可以。在管理相册中,你选择一个照片,然后返回使用选择的照片,如下图所示。

Android开发入门基础知识——Intent详解
下面我们将描述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()方法放入数据。如下图所示:

Android开发入门基础知识——Intent详解
如下代码是演示使用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通信

  • yiisaa
  • 这是我的微信扫一扫
  • weinxin
  • zhengweiqiangcom
  • 我的微信公众号扫一扫
  • weinxin

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: