关于Intent

学习目标

学习Intent相关知识。

Intent是Android程序中各个组件之间进行交互的一种重要方式。

Intent大致可以分为两种:显式Intent隐式Intent

显式Intent

Intent有很多构造方法,其中一个是:

Intent(Context packageContext, Class<?> cls)

packageContext为启动活动的上下文,cls为想要启动的目标活动。

Activity提供了一个StartActiviy(Intent intent)方法,执行如下代码:

Intent intent = new Intent(this,Main2Activity.class);
startActivity(intent);

就可以启动一个新的Activity了,使用这种方式来启动活动,Intent的“意图”就很明显了,因此我们成为显式Intent。

隐式Intent

相较于显式Intent,隐式Intent含蓄很多,并不明确指定想要启动哪一个活动,而是指定一系列更为抽象的action和category等信息,由系统去寻找合适的活动去启动。合适的活动简单说就是可以响应这个隐式Intent的活动。

<activity>标签下配置<intent-filter>的内容,可以指定当前活动可以响应的action和category。例如:

<activity android:name=".Main2Activity">
    <intent-filter>
        <action android:name="liao.yu.test.Main2Activity.Start"/>
        <category android:name="liao.yu.test.Main2Activity.Mycate"/>
    </intent-filter>
</activity>

在action标签中指定了liao.yu.test.Main2Activity.Start这个action,而category标签中包含一些附加信息,更加明确指明了当前活动能够响应的Intent中还有可能带有的category,只用action和category同时匹配上Intent中指定的action和category时,这个活动才能响应该Intent。

Intent intent = new Intent("liao.yu.test.Main2Activity.Start");
intent.addCategory("liao.yu.test.Main2Activity.Mycate");
startActivity(intent);

更多隐式Intent

使用隐式Intent,不仅可以启动自己程序内的活动,还可以启动其他程序的活动,这样可以实现Android多个程序之间共享功能。

打开系统浏览器

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);

Intent.ACTION_VIEW为Android系统的内置动作。

我们还能在<intent-filter>再配置一个<data>标签,用于更加精确的指定当前活动能够响应什么类型的数据。标签中主要可以配置下面这些内容:

  • android:scheme。用于指定数据的协议部分,如上例中的http 部分。
  • android:host。用于指定数据的主机名部分,如上例中的www.baidu.com部分。
  • android:port。用于指定数据的端口部分,一般紧随在主机名之后。
  • android:path。用于指定主机名和端口后面的部分,如一段网址中跟在域名后面的内容。
  • android:mimeType。用于指定可以处理的数据类型,允许使用通配符的方式进行指定。

只有<data>标签中内容和Intent中携带的Data完全一致的时候,当前活动才能够响应该Intent。不过<data>标签中不会指定太多的内容。上例中只需要指定android:scheme为http,就可以响应http协议的Intent了。

<activity android:name=".Main2Activity">
    <intent-filter>
        <action android:name="liao.yu.test.Main2Activity.Start"/>
        <category android:name="liao.yu.test.Main2Activity.Mycate"/>
        <data android:scheme="http"/>
    </intent-filter>
</activity>

除了http协议外,还可以指定其他协议,geo表示地理位置,tel表示打电话等。

Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);

向下一个活动传递数据

在启动活动时传递数据的思路很简单,Intent提供了一系列putExtra()方法可以重载,将数据暂存在Intent中,启动另一个活动后取出

在上一个活动中:

String data = "test";
Intent intent = new Intent(this,Main2Activity.class);
intent.putExtra("data",data);
startActivity(intent);

在第二个活动中:

Intent intent = getIntent();
String data = intent.getStringExtra("data");
Log.i("data",data);

不同的数据类型调用不同的get方法。

返回数据给上一个活

Activity有startActivityForResult(Intent intent, int requestCode)方法用于期望返回值的启动活动。

requestCode为请求码,用于回调中判断数据来源。

第一个活动中:

Intent intent = new Intent(this,Main2Activity.class);
startActivityForResult(intent,11);

第二个活动中:

Intent intent = new Intent();
intent.putExtra("data","data");
setResult(RESULT_OK,intent);
finish();

返回第一个活动时,会调用onActivityResult(int requestCode, int resultCode, Intent data)方法:

protected void onActivityResult(int requestCode, int resultCode,Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(resultCode == RESULT_OK){
        switch (requestCode){
            case 11:
                String str = data.getStringExtra("data");
                Log.i("data",str);
                break;
        }
    }
}

requestCode为请求码,resultCode为结果码,data为返回的数据。