Android跨应用启动实例详解
发布时间 - 2026-01-11 00:47:20 点击率:次Android跨应用启动

前言:
相信大家,很多时候都是在自己的应用中,启动自己写的Activity,Service、BroadcastReceiver、contentProvider 。换句话说,这些都只是 * 单个应用中 组件间 * 的启动。而我们下面要谈论的是 两个应用间 组件 的启动。即——使用 隐式Intent方式 启动应用B的某个组件。
一、在开始之前,先来梳理一下跨应用启动的2种方式:
第一种:在Activity中,启动另一个app的组件。
第二种:在Service中,启动另一个app的组件。
从所周知,Android中有四大组件,那么为什么小编,只介绍Activity和Service中启动另一个应用的四大组件?
其实,BroadcastReceiver组件也是可以启动 4大组件的。这是因为onReceive()方法中会要求传入context实例,有了context实例,就能使用context的方法,启动其他组件。
至于contentProvider,我想大家还没见过,这娃自动去干过事情吧,都是被动的调用。
所以在写代码的时候,我们经常会在Activity或者Service中去启动一个组件,BroadcastReceiver很少,而contentProvider更是没见过。
另外需要跟大家说一下,Context类是一个抽象类,传入的context实例是由其子类来实现的,这种——用父类声明变量,由子类来实现的思维方式,在Java中是很常见的。特别是接口和抽象类,经常用到这种方式。对于小编这种由C转Java的人来说,真是一大坑啊。
为什么Activity和Service都可以直接使用图中的四个方法呢,这是因为Activity和Service都是继承自ContextWrapper,所以子类拥有父类的方法。BroadcastReceiver和contentProvider则不是,具体大家可以看官方API。
二、跨应用启动的实战
** 下面让我们正式进入今天的主题:跨应用启动实战**
1:AppA的Activity中,启动AppB的Activity
Android提供了在一个App中启动另一个App中的Activity的能力,这使我们的程序很容易就可以调用其他程序的功能,从而就丰富了我们App的功能。比如在微信中发送一个位置信息,对方可以点击这个位置信息启动腾讯地图并导航。这个场景在现实中作用很大,尤其是朋友在陌生的环境找不到对方时,这个功能简直就是救星。
本来想把本文的名字叫启动另一个进程中的Activity。因为每个App都会运行在自己的虚拟机中,每个虚拟机跑在一个进程中。但仔细一想,能够称为一个进程,前提是这个App必须要运行起来才行。而Android提供的能力,是不需要另一个App启动就可以将其特定的Activity启动起来的。
也就是说B应用是处理未启动的状态,也就是还没有成为系统的一个进程,那么当使用A启动B应用的某个组件时,请问,B应用是否成为系统的进程?答案是yes。怎么看呢,可以从Android Studio 的Android device monito 中结合虚拟机看。
我们有至少两种办法达到启动另一个App中的Activity。
第一种———隐式Intent的action方式。
相信这种方式,大家都不会陌生。这里就不进行过多的解析。这里只贴一下AppB的manifest(文件清单):
从文件清单中,我们可以看到,appB中有两个Activity。其中SecondActivity就是要被appA启动的Activity。
那么我们只要在appA的任意一个组件(Activity或Service),做如下的调用:
Intent intent=new Intent("android.intent.action.SecondActivity");
startActivity(intent);
就可以成功在 A应用中 启动B应用的 组件。另外还要跟大家说一点,SecondActivity的category一定要在文件清单中添加上,否则启动的时候会报错的。
不知道大家有没有思考过这三个事情: 1、当A应用 启动 B应用的SecondActivity,那么B应用的MainActivity会不会被启动呢?正常情况下,我们点击应用B,进到的是MainActivity这个活动,那么现在我们是通过跨应用启动,会不会要经过B的MainActivity呢?答案是不会。 2、当我们在SecondActivity中点击Back回退键时,回到的是A应用的mainActivity界面,这里时候大家有没有想过。 SecondActivity和appA的mainActivity是不是同处于一个栈中呢?这时候就要去打印栈的ID了。 3、由上面的两件事,不知道大家想起:Android对于Activity的管理,也就是framework层的ActivityManager。也就是说,你手机上的N多应用,当你打开某一个应用是,这个应用的Activity都是由ActivityManager这娃来创建和管理的。应用本身并没有创建Activity的能力。当然这其中又涉及到了Ibinder的通讯。这里暂时不讲。
第二种用intent设置className或component的办法启动。举例如下。
新建两个项目ProjectA和ProjectB,用B中的MainActivity启动A的MainActivitity。关键代码如下:
ProjectA MainActivity
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW);
String packageName = "com.example.mylife.anotherapp";
String className = "com.example.mylife.anotherapp.MainActivity";
intent.setClassName(packageName, className);
//second method
//intent.setComponent(new ComponentName("com.example.mylife.anotherapp","com.example.mylife.anotherapp.MainActivity"));
Bundle bundle = new Bundle();
bundle.putString("msg", "this message is from project B ");
intent.putExtras(bundle);
intent.putExtra("pid", android.os.Process.myPid());
startActivityForResult(intent, 1);
//startActivity(intent);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case 1:
if(resultCode == RESULT_OK) {
textView.setText(data.getStringExtra("result"));
}
break;
}
}
ProjectB MainActivity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView)findViewById(R.id.text);
Intent intent = getIntent();
if(intent != null) {
textView.setText(intent.getStringExtra("msg"));
}
}
public void OnClick(View view) {
Intent intent = new Intent();
intent.putExtra("result","OK! from project a.");
this.setResult(RESULT_OK,intent);
this.finish();//要清楚这里为什么要用finish()。
}
注意:如果在应用B中,是通过按下Back键,回退到应用A的MainActivity活动,那么A的onActivityResult()方法是不会被回调的,这是因为ProjectB的MainActivity活动只是出栈而已,并没有销毁。而只有ProjectB的MainActivity活动被销毁的时候,才会回调A的onActivityResult()方法。那如果是按了Back键回退的话怎么处理呢?这时候只要重写appB的onBackPressed()方法就好了。
@Override
public void onBackPressed() {
super.onBackPressed();
Intent intent = new Intent();
intent.putExtra("result","OK! from project a.");
this.setResult(RESULT_OK,intent);
this.finish();//要清楚这里为什么要用finish()。
}
二:进阶———在A应用的Activity中启动(停止)——B应用的服务
应用B的manifest
应用B的service的代码:
public class MyService extends Service {
private static final String TAG = "MyService";
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate: ");
}
@Override
public int onStartCommand(Intent intent,int flags, int startId) {
Log.d(TAG, "onStartCommand: ");
if(intent != null) {
Log.d(TAG, "onStartCommand: "+intent.getStringExtra("msg"));
}
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy: ");
}
}
应用A的代码:
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW);
String packageName = "com.example.mylife.anotherapp";
String className = "com.example.mylife.anotherapp.MyService";
intent.setClassName(packageName, className);
switch (v.getId()) {
case R.id.btn_start:
Bundle bundle = new Bundle();
bundle.putString("msg", "this message is from project B ");
intent.putExtras(bundle);
intent.putExtra("pid", android.os.Process.myPid());
startService(intent);
break;
case R.id.btn_stop:
stopService(intent);
break;
}
}
测试结果:A应用直接启动B应用的服务,而B应用并不会打开自己的Activity。
本次代码参考://www./article/111896.htm
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
# Android跨应用启动
# Android 跨应用
# 自己的
# 的是
# 子类
# 都是
# 这是因为
# 就可以
# 是由
# 中有
# 要用
# 周知
# 来实现
# 回调
# 第二种
# 小编
# 第一种
# 的人
# 是一个
# 进阶
# 也就是说
# 这时候
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
东莞专业网站制作公司有哪些,东莞招聘网站哪个好?
Laravel如何发送系统通知?(Notification渠道示例)
如何在橙子建站上传落地页?操作指南详解
Laravel如何使用查询构建器?(Query Builder高级用法)
HTML5打空格有哪些误区_新手常犯的空格使用错误【技巧】
UC浏览器如何切换小说阅读源_UC浏览器阅读源切换【方法】
如何快速上传自定义模板至建站之星?
QQ浏览器网页版登录入口 个人中心在线进入
Laravel如何将应用部署到生产服务器_Laravel生产环境部署流程
如何基于云服务器快速搭建网站及云盘系统?
IOS倒计时设置UIButton标题title的抖动问题
如何在IIS中新建站点并解决端口绑定冲突?
百度浏览器如何管理插件 百度浏览器插件管理方法
HTML透明颜色代码在Angular里怎么设置_Angular透明颜色使用指南【详解】
如何续费美橙建站之星域名及服务?
原生JS获取元素集合的子元素宽度实例
详解Android图表 MPAndroidChart折线图
海南网站制作公司有哪些,海口网是哪家的?
使用Dockerfile构建java web环境
大连企业网站制作公司,大连2025企业社保缴费网上缴费流程?
如何在云主机上快速搭建网站?
如何用PHP工具快速搭建高效网站?
非常酷的网站设计制作软件,酷培ai教育官方网站?
电商网站制作价格怎么算,网上拍卖流程以及规则?
南京网站制作费用,南京远驱官方网站?
Python并发异常传播_错误处理解析【教程】
Laravel中Service Container是做什么的_Laravel服务容器与依赖注入核心概念解析
Laravel路由怎么定义_Laravel核心路由系统完全入门指南
Laravel怎么使用artisan命令缓存配置和视图
bing浏览器学术搜索入口_bing学术文献检索地址
php嵌入式断网后怎么恢复_php检测网络重连并恢复硬件控制【操作】
制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?
活动邀请函制作网站有哪些,活动邀请函文案?
Android滚轮选择时间控件使用详解
详解jQuery中基本的动画方法
中山网站推广排名,中山信息港登录入口?
标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?
昵图网官方站入口 昵图网素材图库官网入口
Laravel N+1查询问题如何解决_Eloquent预加载(Eager Loading)优化数据库查询
中山网站制作网页,中山新生登记系统登记流程?
Linux网络带宽限制_tc配置实践解析【教程】
node.js报错:Cannot find module 'ejs'的解决办法
HTML透明颜色代码怎么让图片透明_给img元素加透明色的技巧【方法】
Laravel如何实现模型的全局作用域?(Global Scope示例)
Laravel如何集成Inertia.js与Vue/React?(安装配置)
北京企业网站设计制作公司,北京铁路集团官方网站?
Laravel队列由Redis驱动怎么配置_Laravel Redis队列使用教程
如何用花生壳三步快速搭建专属网站?
Laravel如何使用Vite进行前端资源打包?(配置示例)
Laravel如何获取当前登录用户信息_Laravel Auth门面使用与Session用户读取【技巧】

