Android跨应用启动实例详解

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。

本次代码参考:http://www.jb51.net/article/111896.htm

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • 关于Android中点击通知栏的通知启动Activity问题解决

    前言 最近遇到一个很奇葩的问题,终于解决了,所以想着记录一下,方便大家或者自己以后有需要的时候可以参考学习. 问题场景 用小米手机使用小米推送一条消息,然后点击通知栏中的消息启动应用,然后进入会话的Activity.应用启动后,如果当前界面不是会话界面,那么新消息会在通知栏显示消息提醒,然后点击会话消息后却进不了会话的Activity,即点击了通知栏通知后,系统都没有启动指定Activity的意思,没有看到系统启动Activity的Log,到是会看到系统处理这个Activity的影子. 这个指定

  • Android显式启动与隐式启动Activity的区别介绍

    前段时间立志坚持写博客,但是发现自己的积累的确不多,于是假期泡了泡图书馆,读了一些很有价值的文章.收获颇多,今天的文章分享为主,共同学习. 为什么要写显式启动与隐式启动Activity.这源于自己的一次面试,被Baidu工程师问道,但是后来觉得自己回答的不好,废话少说,进入正题. 如题,Android的Acitivity启动大致有两种方式:显式启动与隐式启动.下面分别介绍: A:显式启动 对于初学者来说,这个最常见,下面用代码来解释什么是显式启动. 复制代码 代码如下: Intent inten

  • Android 启动activity的4种方式及打开其他应用的activity的坑

    Android启动的四种方式分别为standard,singleTop,singleTask,singleInstence. standard是最常见的activity启动方式,也是默认的启动的方式.当启动一个activity的时候他将进入返回栈的栈顶.系统不会管栈内是否有相同的activity,方式像后入先出. singleTop方式是在活动启动的时候,系统先判定栈顶是否有相同的活动,如果没有则新建活动,否则将不新建活动.而是直接使用他. singleTask方式在活动启动的时候,系统先判定栈

  • Android 中启动自己另一个程序的activity如何实现

    Android 中启动自己另一个程序的activity如何实现 可以使用action,举例: 1. 比如建立activity4,我们对它的AndroidManifest.xml修改一下  <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:<a href="http://lib.csdn.net/base/android" rel="external no

  • android中Activity详解(生命周期、以各种方式启动Activity、状态保存,完全退出等)

    一.什么是Activity? 简单的说:Activity就是布满整个窗口或者悬浮于其他窗口上的交互界面.在一个应用程序中通常由多个Activity构成,都会在Manifestxml中指定一个主的Activity,如下设置 <actionandroid:name="AndroidintentactionMAIN" /> 当程序第一次运行时用户就会看这个Activity,这个Activity可以通过启动其他的Activity进行相关操作.当启动其他的Activity时这个当前的

  • Android 启动另一个App/apk中的Activity实现代码

    Android 启动另一个App/apk中的Activity实现代码 前言: Android提供了在一个App中启动另一个App中的Activity的能力,这使我们的程序很容易就可以调用其他程序的功能,从而就丰富了我们App的功能.比如在微信中发送一个位置信息,对方可以点击这个位置信息启动腾讯地图并导航.这个场景在现实中作用很大,尤其是朋友在陌生的环境找不到对方时,这个功能简直就是救星. 本来想把本文的名字叫启动另一个进程中的Activity,觉得这样才有逼格.因为每个App都会运行在自己的虚拟

  • Android跨应用启动实例详解

    Android跨应用启动 前言: 相信大家,很多时候都是在自己的应用中,启动自己写的Activity,Service.BroadcastReceiver.contentProvider .换句话说,这些都只是 * 单个应用中 组件间 * 的启动.而我们下面要谈论的是 两个应用间 组件 的启动.即--使用 隐式Intent方式 启动应用B的某个组件. 一.在开始之前,先来梳理一下跨应用启动的2种方式: 第一种:在Activity中,启动另一个app的组件. 第二种:在Service中,启动另一个a

  • Android Intent封装的实例详解

    Android Intent封装的实例详解 什么是Intent: Intent是协调应用间.组件之间的通讯和交互.通过Intent你可以启动Activity.Service.Broadcasts.更可以跨程序调用第三方组件.例如:启动拨打电话界面.音乐播放等. 组件     启动 Activity startActicity() Service startService(),bindService( ) Broadcasts sendBroadcast() 使用Intent: 栗子:在一个Act

  • Android 中ContentProvider的实例详解

    Android 中ContentProvider的实例详解 Content Provider 的简单介绍: * Android中的Content Provider 机制可支持在多个应用中存储和读取数据.这也是跨应用 共享数据的唯一方式.在Android系统中,没有一个公共的内存区域,供多个应用共享存储数据: * Android 提供了一些主要数据类型的ContentProvider ,比如:音频.视频.图片和私人通讯录等: 在android.provider 包下面找到一些android提供的C

  • Android 中 ActivityLifecycleCallbacks的实例详解

    Android 中 ActivityLifecycleCallbacks的实例详解           以上就是使用ActivityLifecycleCallbacks的实例,代码注释写的很清楚大家可以参考下, MyApplication如下: package com.cc; import java.util.LinkedList; import android.app.Activity; import android.app.Application; import android.os.Bun

  • Android全局获取Context实例详解

    Android全局获取Context实例详解 在弹出Toast 启动活动 发送广播 操作数据库 使用通知等等时都需要Context 如果操作在活动中进行是很简单的,因为活动本身就是一个Context对象 但是当逻辑代码脱离了Activity类,此时使用Context就需要一些技巧了: 我们可以定制一个自己的Application类,以便管理程序内一些全局状态信息,比如全局Context 代码如下: public class MyApplication extends Application{ p

  • Android之ImageSwitcher的实例详解

    Android之ImageSwitcher的实例详解 一. 简单示例 实例代码: public class AndroidUIActivity extends Activity { // 当前显示的图片索引 private int index; // 图片数组 private int[] images = { R.drawable.image1, R.drawable.image2, R.drawable.image3, R.drawable.image4, R.drawable.image5

  • Android 帧动画的实例详解

    Android 帧动画的实例详解 对于 Android 帧动画 大体上可以理解成 一张张图片 按一定顺序切换, 这样当连续几张图是一组动画时,就可以连起来了看成是一个小电影,你懂得 好得,比就装到这里,下面开始进入正题,由于产品需求 需要做一个 声音喇叭动态切换的样式,我特么第一就想到是帧动画切换,然后就百度了一些资料,发现 真的, 现在这个网上太多的资料是 copy粘贴过来的, 一错全错,对于这种情况我只想说,made,一群垃圾, 所以今天我将带你们走进Android 正确帧动画地址. 第一步

  • JSONP跨域请求实例详解

    JSOP简介 JSONP(JSON with Padding)是JSON的一种"使用模式",可用于解决主流浏览器的跨域数据访问的问题.由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的<script> 元素是一个例外.利用 <script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是所谓的 JSONP.用 JSON

  • JS JSOP跨域请求实例详解

    在项目开发中遇到跨域的问题,一般都是通过JSONP来解决的.但是JSONP到底是个什么东西呢,实现的原理又是什么呢.在项目的空闲时间可以好好的来研究一下了. 1.什么是JSONP? 要了解JSONP,不得不提一下JSON,那么什么是JSON? JSON is a subset of the object literal notation of JavaScript. Since JSON is a subset of JavaScript, it can be used in the langu

  • Android的搜索框架实例详解

    基础知识 Android的搜索框架将代您管理的搜索对话框,您不需要自己去开发一个搜索框,不需要担心要把搜索框放什么位置,也不需要担心搜索框影响您当前的界面.所有的这些工作都由SearchManager类来为您处理(以下简称"搜索管理器"),它管理的Android搜索对话框的整个生命周期,并执行您的应用程序将发送的搜索请求,返回相应的搜索关键字. 当用户执行一个搜索,搜索管理器将使用一个专门的Intent把搜索查询的关键字传给您在配置文件中配置的处理搜索结果的Activity.从本质上讲

随机推荐