一句话说透Android里面的显示Intent与隐式Intent的区别

282 阅读2分钟

一句话总结:

显示 Intent 是“精准快递”(指定具体门牌号),隐式 Intent 是“群发通知”(只写要求,谁符合条件谁接单)——前者直接找目标,后者靠系统匹配。


核心区别对比表

对比项显示 Intent隐式 Intent
指定目标方式明确指定组件类名(如 MyActivity::class.java通过 actiondatacategory 等条件匹配
灵活性低(必须知道具体目标)高(无需知道具体实现者)
安全性高(不会被其他应用拦截)低(可能被恶意应用劫持)
典型场景启动应用内固定页面跨应用功能调用(如分享、打开链接)

详细解释(附代码示例)

1. 显示 Intent —— “精准快递”

  • 特点:直接指定目标组件的类名,系统无需匹配,直达目标。

  • 代码示例

    // 启动本应用的 SecondActivity  
    val intent = Intent(this, SecondActivity::class.java)  
    startActivity(intent)  
    
  • 适用场景

    • 应用内部页面跳转(如主页 → 详情页)。
    • 启动服务或广播接收器(需明确类名)。

2. 隐式 Intent —— “群发通知”

  • 特点:通过条件描述需求,由系统匹配合适的组件(可能有多个应用响应)。

  • 代码示例

    // 发送一个“查看网页”的隐式 Intent  
    val intent = Intent(Intent.ACTION_VIEW).apply {  
        data = Uri.parse("https://www.example.com")  
    }  
    // 检查是否有应用能处理此 Intent  
    if (intent.resolveActivity(packageManager) != null) {  
        startActivity(intent)  
    } else {  
        Toast.makeText(this, "没有可用浏览器", Toast.LENGTH_SHORT).show()  
    }  
    
  • 适用场景

    • 调用系统功能(如拍照、拨号、分享)。
    • 跨应用协作(如打开 PDF 文件,由用户选择阅读器)。

隐式 Intent 的匹配规则(如何群发通知?)

1. 组件声明过滤器(AndroidManifest.xml)

接收方需在 AndroidManifest.xml 中声明 <intent-filter>

<activity android:name=".MyBrowserActivity">  
    <intent-filter>  
        <action android:name="android.intent.action.VIEW" />  
        <category android:name="android.intent.category.DEFAULT" />  
        <data android:scheme="http" />  
        <data android:scheme="https" />  
    </intent-filter>  
</activity>  

2. 匹配优先级

  • 如果多个组件符合条件,系统会弹出选择器让用户挑选。

  • 强制弹出选择器

    val chooser = Intent.createChooser(intent, "选择浏览器")  
    startActivity(chooser)  
    

注意事项(避坑指南)

1. 隐式 Intent 的安全风险

  • 恶意应用劫持:如果未验证接收方,可能被钓鱼应用窃取数据。

  • 防御措施

    // 仅允许信任的应用响应(如白名单)  
    intent.setPackage("com.example.trustedapp")  
    

2. Android 11+ 的包可见性限制

  • 问题:Android 11 及以上版本默认禁止应用查看其他应用的组件列表。

  • 解决:在 AndroidManifest.xml 中声明需要查询的包名:

    <queries>  
        <intent>  
            <action android:name="android.intent.action.VIEW" />  
            <data android:scheme="https" />  
        </intent>  
    </queries>  
    

3. 显示 Intent 的灵活性不足

  • 问题:直接指定类名会导致代码耦合(如模块化开发时无法直接引用其他模块的类)。
  • 解决:使用隐式 Intent 或依赖注入解耦。

总结口诀

“显示 Intent 精准达,类名在手不偏差,
隐式 Intent 靠匹配,跨应用协作全靠它。
安全风险需警惕,恶意拦截要防诈,
灵活搭配按需选,开发规范不抓瞎!”