【Android】Intent 和 Intent Filter

一.  Intent 简介

Intent 是一个消息传递对象,您可以用来从其他应用组件请求操作。可以用于:启动 Activity、启动服务、传递广播。

https://developer.android.com/guide/components/intents-filtershttps://developer.android.com/guide/components/intents-filters(1) Intent 启动 Activity 简介

// 主 Activity
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    // 启动一个Acitivity
    public void start1(View view) {
        // 创建一个 Intent 对象
        Intent intent = new Intent(this,MyActivity.class);
        // 传入 startActiviry() 启动名字为 MyActivity 的 Activity
        startActivity(intent);
    }
}

由 Android 指导文档(https://developer.android.com/reference/android/content/Intent)可知,Intent 的构造函数有下面这些类型。

上面示例代码用了 Intent(Context packageContext, Class<?> cls) 这个构造函数。

由于 Activity 是多层继承来自 Context 类,所以上面代码直接用 this(MainActivity对象的引用)来代替 Context 传入到参数1中。然后再使用要启动的目标 Activity 的类传入到参数2中。

由于 Activity 是继承来自 Context 类,startActivity() 也是由 Context 类继承而来,所以可以直接在 Activity 中调用 startActivity() 来启动一个 Activity。

(2) Intent 启动 Service 简介

// 主 Activity
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    // 启动一个Acitivity
    public void start1(View view) {
        // 创建一个 Intent 对象
        Intent intent = new Intent(this, MyService.class);
        // 传入 startService() 启动服务
        startService(intent);
    }
}

 启动 Serivce 跟启动 Activity 的方法类似,只是将在 Intent 传入 Serivce 的类,并调用 startService() 方法。

(3) Intent 发送广播简介

// 主 Activity
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    // 启动一个Acitivity
    public void start1(View view) {
        // 创建一个 Intent 对象
        Intent intent = new Intent(this, MyReceiver.class);
        // 发送广播
        sendBroadcast(intent);
    }
}

发送广播的方法也类似。

二.  Intent 分类

1.  显示 Intent

// 显式Intent
Intent intent = new Intent(this, MyActivity.class);
startActivity(intent);

2. 隐匿 Intent

// AndroidManifest.xml中
<activity android:name=".MyActivity">
     <intent-filter>
         <action android:name="TEST1" />
         <category android:name="android.intent.category.DEFAULT" />
     </intent-filter>
 </activity>
// MainActivity 中
static final String action1 = "TEST1";
Intent intent2 = new Intent(action1);
startActivity(intent2);

三.  Intent 解析

1. action 测试

当收到隐式 Intent 以启动 Activity 时,系统会根据以下三个方面将该 Intent 与 Intent 过滤器进行比较,搜索该 Intent 的最佳 Activity:操作、数据(URI 和数据类型)、类别。

隐式 Intent 要指定接受的 Intent action,Intent-filter 既可以不声明任何 <action> 元素,也可以声明多个此类元素。比如:

<activity android:name=".MyActivity">
    <intent-filter>
        <action android:name="TEST1"/>
        <action android:name="TEST2"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>

要通过此过滤器,在 Intent 中指定的 action 必须与过滤器中列出的某一 action 匹配。如果该过滤器未列出任何 action,则 Intent 没有任何匹配项,因此所有 Intent 均无法通过测试。但是,如果 Intent 未指定 action,则只要过滤器内包含至少一项操作,就可以通过测试。

2.  category 测试

要指定接受的 Intent 类别,Intent-filter 既可以不声明任何 <category> 元素,也可以声明多个此类元素,如下例所示:

<intent-filter>
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    ...
</intent-filter>

若要使 Intent 通过 category 测试,则 Intent 中的每个 category  均必须与 filter 中的 category  匹配。Intent-filter 声明的 category  可以超出 Intent 中指定的数量,且 Intent 仍会通过测试。因此,不含 cateory 的 Intent 应当始终会通过此测试,无论 intent-filter 中声明何 category 别均是如此。

请注意:Android 会自动将 CATEGORY_DEFAULT  category 应用于传递给 startActivity() 和 startActivityForResult() 的所有隐式 Intent。如需 Activity 接收隐式 Intent,则必须将 "android.intent.category.DEFAULT"  包括在其 Intent-filter 中,不然隐式 Intent 将无法通过 category 测试找到此 Activity。

(未完待续)

猜你喜欢

转载自blog.csdn.net/xiaoyu_wu/article/details/121783345