news 2026/6/10 1:12:37

两个独立 App如何相互唤起

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
两个独立 App如何相互唤起

这两种方法(Intent直接唤起 和 DeepLink)的核心区别在于:它们不需要把代码合并在一起,而是保持两个独立的 APK(App A 和 App B),通过 Android 系统的通信机制让它们互相“对话”。

假设场景:

  • App A (主控端):想要打开另一个 App。
  • App B (被控端):拥有你想要展示的功能页面。

以下是详细教程:


方法一:通过包名/类名直接唤起 (Intent ComponentName)

这种方法最简单直接,适合App B 是你自己的,且你知道它的确切包名和类名的情况。

第一步:配置 App B (被唤起方)

在 App B 的AndroidManifest.xml中,找到你想要让外部启动的那个 Activity(比如MainActivity或者FunctionActivity)。

关键点:必须添加android:exported="true"

<!-- App B 的 AndroidManifest.xml --><manifestpackage="com.ebike.intercept"><!-- 假设这是 App B 的包名 --><application...><!-- 这里的 exported="true" 允许外部 App 启动它 --><activityandroid:name=".MainActivity"android:exported="true"><intent-filter><actionandroid:name="android.intent.action.MAIN"/><categoryandroid:name="android.intent.category.LAUNCHER"/></intent-filter></activity></application></manifest>
第二步:配置 App A (发起方) - 适配 Android 11+

从 Android 11 (API 30) 开始,为了隐私安全,App A 默认看不见App B 是否安装。你需要添加<queries>标签声明“我需要查询 App B”。

在 App A 的AndroidManifest.xml中:

<!-- App A 的 AndroidManifest.xml --><manifestpackage="com.example.appa"><!-- 必须添加这个,否则检测不到 App B 是否安装 --><queries><packageandroid:name="com.ebike.intercept"/><!-- 填 App B 的包名 --></queries><application...>...</manifest>
第三步:在 App A 的 Java 代码中编写跳转逻辑
// 在 App A 的点击事件中publicvoidjumpToAppB(){// 1. 定义 App B 的包名和类名StringpackageName="com.ebike.intercept";StringclassName="com.ebike.intercept.MainActivity";// 必须是完整路径// 2. 检查 App B 是否安装(为了防止 Crash)if(isAppInstalled(context,packageName)){Intentintent=newIntent();// 3. 设置 ComponentNameComponentNamecomponentName=newComponentName(packageName,className);intent.setComponent(componentName);// 4. (可选) 传递数据intent.putExtra("key_from_a","Hello from App A");// 5. 必须加 NEW_TASK 标记(如果在非 Activity 环境下启动)intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);startActivity(intent);}else{Toast.makeText(context,"请先安装 App B",Toast.LENGTH_SHORT).show();}}// 辅助方法:检查 App 是否安装privatebooleanisAppInstalled(Contextcontext,StringpackageName){try{context.getPackageManager().getPackageInfo(packageName,0);returntrue;}catch(PackageManager.NameNotFoundExceptione){returnfalse;}}

方法二:使用 DeepLink (自定义 URL Scheme)

这是更推荐的现代做法,它的耦合度更低。App A 不需要知道 App B 的具体类名,只需要像打开网页一样打开一个 URL(例如ebike://home),系统会自动找到 App B。

第一步:配置 App B (被唤起方)

你需要给 App B 的某个 Activity 配置一个“暗号”(Scheme)。

在 App B 的AndroidManifest.xml中:

<!-- App B 的 AndroidManifest.xml --><activityandroid:name=".DetailActivity"><!-- 这里的 intent-filter 是关键 --><intent-filter><!-- 必须有 ACTION_VIEW --><actionandroid:name="android.intent.action.VIEW"/><!-- 必须有 DEFAULT --><categoryandroid:name="android.intent.category.DEFAULT"/><!-- 允许浏览器唤起(可选,但推荐) --><categoryandroid:name="android.intent.category.BROWSABLE"/><!-- 定义暗号:ebike://open_detail --><!-- scheme: 协议头,host: 路径/主机名 --><dataandroid:scheme="ebike"android:host="open_detail"/></intent-filter></activity>
第二步:在 App B 中接收参数 (可选)

DetailActivity.javaonCreate方法中:

// App B 的 DetailActivity.java@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_detail);// 获取 Intent 中的数据Intentintent=getIntent();Uridata=intent.getData();if(data!=null){// 比如 URL 是 ebike://open_detail?msg=hello&id=100Stringmsg=data.getQueryParameter("msg");// 获取 "hello"Stringid=data.getQueryParameter("id");// 获取 "100"Log.d("DeepLink","收到参数: "+msg);}}
第三步:在 App A 中编写跳转逻辑

App A 现在根本不需要知道 App B 的包名或类名,只需要访问这个 URL。

// 在 App A 的点击事件中publicvoidjumpByDeepLink(){// 1. 构建 URI,并带上参数Stringurl="ebike://open_detail?msg=来自AppA的问候&id=666";Intentintent=newIntent(Intent.ACTION_VIEW,Uri.parse(url));intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);// 2. 检查系统中是否有 App 能响应这个 Intent// (注意:在 Android 11+ 上,如果 App A 没加 <queries>,这个 resolveActivity 也可能返回 null,// 但直接 startActivity 通常会弹出一个系统选择框,或者直接跳转)try{startActivity(intent);}catch(Exceptione){Toast.makeText(context,"没有检测到已安装的目标应用",Toast.LENGTH_SHORT).show();}}

总结对比

特性方法一:直接唤起 (Intent/ComponentName)方法二:DeepLink (URL Scheme)
原理“我要去某个具体地址找老王”“我要喊一声老王,谁是老王谁答应”
配置难度简单中等(需配置 IntentFilter)
耦合度(需硬编码包名类名,B重构改名则A会挂)(只需约定 URL 字符串)
灵活性只能 App 唤起App 和 网页浏览器都能唤起
参数传递Bundle (类型丰富)URL 字符串 (只能传 String)
适用场景两个 App 都是你开发的,且不做网页跳转需要从 H5 页面跳入 App,或者想要标准化的协议

总结如下:

  1. 如果这两个 App 都要安装在同一台专用设备上(比如工业PDA、特定的E-bike中控屏):
    使用方法一(直接唤起)最快。因为环境是可控的,您确定两个 App 都会安装,直接写包名跳过去就行,代码改动最小。

  2. 如果您希望看起来像一个 App,用户体验更好:
    可以把App A 做成一个“壳”(Launcher),桌面只显示 App A 的图标。App B 在 Manifest 里去掉LAUNCHERcategory(这样桌面上看不到 B 的图标)。
    然后用户打开 A,点击某个按钮时,A 在后台启动 B 的 Activity。这样用户感觉就像是在同一个软件里操作一样。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/6 16:06:12

项目实战05—XXX火力发电厂工业蒸汽量预测

火力发电是一种很常用的发电技术,但是火力发电的转换效率并不高。其中蒸汽压力的高低直接关系到火力发电的效率,火力发电的效率与蒸汽的压力之间的关系并不是正相关关系。 火力发电过程要尽量使水处在蒸发的临界状态,这时火力发电的效率最高。因此,火力发电厂需要及…

作者头像 李华
网站建设 2026/6/8 19:43:42

在职备战法考,先择校还是先备考?

许多在职考生都听过一个建议&#xff1a;“别想太多&#xff0c;先学起来。”于是&#xff0c;你匆忙找来资料&#xff0c;埋头苦学两月&#xff0c;却越发感到方向模糊、效率低下、坚持困难……这时你可能才意识到&#xff1a;在错误的道路上“先出发”&#xff0c;往往意味着…

作者头像 李华
网站建设 2026/6/9 18:37:28

AgentScope x RocketMQ:打造企业级高可靠 A2A 智能体通信基座

作者&#xff1a;琛琪、稚柳 引言 Agentic AI 时代已至&#xff0c;在智能客服、代码生成、流程自动化等场景中&#xff0c;多智能体&#xff08;Multi-Agent&#xff09;协作正从构想走向落地。然而&#xff0c;当多个 Agent 需要像一个团队那样高效协作时&#xff0c;脆弱的…

作者头像 李华
网站建设 2026/6/10 0:52:25

2025年夸克网盘新用户送1T 空间,免费领取!

一、活动时间 2025年01月01日 &#xff5e; 2025年12月31日 二、面向用户 夸克 App 新用户&#xff0c;即在手机端和 PC 端从未使用手机号注册过夸克账号的用户 只安装过夸克客户端但从未注册夸克账号的用户&#xff0c;也可获得本次新用户活动奖励&#xff1b; 如果用户使…

作者头像 李华
网站建设 2026/6/9 10:46:27

PDF24 Creator PDF 工具箱 v11.29.0

可将大部分文件转成pdf格式的免费软件&#xff0c;安装好后会在你的 打印机 里看到一个叫PDF24的虚拟打印机&#xff0c;你可将要转成pdf格式的文件打印时选虚拟打印机PDF24&#xff0c;也可以直接将文件以拖拉方式拉进这软件的主视窗编辑区里&#xff0c;它会自动转成pdf格式&…

作者头像 李华
网站建设 2026/6/9 17:57:09

网络安全必备工具收藏指南:20款神器助你快速入门

工欲善其事必先利其器&#xff0c;在新入门网络安全的小伙伴而言。这些工具你必须要有所了解。本文我们简单说说这些网络安全工具吧&#xff01; Web安全类 Web类工具主要是通过各种扫描工具&#xff0c;发现web站点存在的各种漏洞如sql注入、xss等。从而获取系统权限&#xf…

作者头像 李华