Activity被打开的不同姿势

原创 2016年09月26日 00:43:49

Activity被打开的不同姿势

我们都知道在Android中,我们是通过Intent来打开一个Activity的,但是你知道这个过程是如何做到的吗?当然如果你不知道,那太好了,这篇文章也不会告诉你的。如果有兴趣知道请看罗大的文章:Android应用程序启动过程源代码分析。本文所要探讨是我们打开Activity的方式。这里面没有干货,更多的只是总结!

显式调用

我们知道Activity有一个接近于教科书似的使用方法。如下:

Intent intent = new intent(this,AActivity.class);
startActivity(intent);

这就是Activity被打开的普通方法。这种方法被称为显式调用。想要调用那个Activity一目了然。这样的方法在开发的过程中最常见,也是大部分新手最早的学习内容。当然如下的方式也可以看成是一种扩展。

Intent intent = new Intent();
intent.setClass(this,AActivity.class);
startActivity(intent);

可以看到本质上没有什么差别。

隐式调用

隐式调用在开发中其实也是比较常见的,特别是要跨应用调用的时候,我们也经常会使用隐式调用的方式。比较经典的如下:

Uri uri = Uri.parse("tel:119");
Intent it = new Intent(Intent.ACTION_DIAL, uri);
startActivity(it);

这段代码运行后会拨打119电话,可以看到它使用了一个action,然后通过uri来传递消息。而运行这段代码之所以能够运行是因为系统为拨打电话这个功能加上了ACTION_DIAL这个action,所以这个Itent便能打电话了。当然你也可以在你的应用中的某个Activity加上这个ACTION_DIAL,这样的话,如果有应用通过这段代码来打电话就会跳出选择框来选择。这个就是Android中的隐式调用,可以看出来它并没有指定哪个Activity来处理,这样就把选择权交给了用户。这种方式通常会应用在跨应用调用上。因为本应用只能显式的打开自己Manifest里面组册的应用。不在自己Manifest里面注册的Activity如果通过显式调用就会抛出未找到Activity的异常。而通过action这种方式就能够让系统去查找所有拥有这个Action的应用。当然这个还是普通的隐式调用,更有趣的如下:

Intent intent = new Intent();
Uri uri = Uri.parse("market://details?id=" + applicationName);
intent.setData(uri);
intent.setPackage(mMarketPackageName);
startActivity(intent);

这段代码能够实现在mMarketPackageName这个应用市场打开applicationName这个应用。前提是该应用市场定义这个方式的Scheme。这也是通过了隐式调用来实现的。只不过这次指定的是Scheme。不过隐式调用有个需要注意的地方,就是要判断这个Intent能否被系统处理,否则一样会崩溃,判断方法如下:

intent.resolveActivity(mContext.getPackageManager()) != null

这段代码便能够判断目标Intent是否可以被处理。

更进一步

上面说到Scheme,它是一种协议,通过这个协议,我们可以从web打开应用。所以Activity不仅仅可以通过应用来打开,web/wap这样的方式也是可以的。这时候你需要的是在你的onclick时间里填上Scheme地址。静态的打开方式可以参考下面:

<a href="weixin://dl/moments">朋友圈</a>

将该代码嵌入到网页中,点击它,你就能打开朋友圈了。这是Scheme协议的使用,至于实现,以后用空再谈,或者自己动手查找一下,其实还是很简单的。

其它

上文提到了两种调用Activity的方式。一种隐式一种显式。隐式需要注意的是你要调用的Activity是否存在,因为不同的系统会用不同的情况,所以要先判断再调用,除非特别有把握的,比如发短信打电话。而显式调用就是不能跨应用调用,否则会出异常。另外有几个tips来分享:

tips 1 跨应用的安全性问题

如果是服务的提供者,就是被调用的Activity,这个时候你需要关注页面是否存在安全性的问题。当你提供了跨域调用的功能后,你的Activity就有可能会被置于其它应用的Task中。所以如果你要提供给其它应用使用的Activity,你需要关注这个Activity是否有敏感数据,它会不会被盗取。由于Scheme协议其实也是一种隐式调用方式,所以如果开启了Scheme协议,你也需要关注这个问题。

tips 2 了解Bundle作用

之前在公司的工程中看到了这样的代码:

if (bundle != null && bundle.containsKey(KEY)) {
  intent.putExtra(KEY,bundle.getBoolean(KEY));
}

在没有看过源码之前我并没有任何想法,当我看过Intent源码之后就发现了这是有问题的。因为在源码中,有一个Bundle变量mExtra,当我们putExtra的时候,其实是把数据放到了这个mExtra中了,而putExtras()来添加Bundle的时候,添加进来的Bundle实例会被遍历一遍,然后加入到mExtra中,也就是说通过Bundle加入的数据和putExtra加入的数据是被放在了统一的地方,所以上面的步骤其实是多此一举。包括getExtras获得Bundle实例再分析也是多此一举,直接从Intent中取就行了。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Android数据存储——SharedPreferences(记录应用被打开的次数)

本文通过一个实例记录应用被打开的次数来简单演示一下SharedPreferences的应用:当用户第一次打开应用时系统在本地创建SharedPreferences来记录使用App被打开的次数。

javascript中如何通过被打开的窗体在opener窗体中添加option选项javascript

如果我们要在一个普通窗体中用javascript动态添加一个option选项,我们会这样写: document.form1.list1.options[0]=new option("a1","a1"...

(IOS_演示被打开的程序

  • 2015-06-02 19:17
  • 424B
  • 下载

linux多网卡绑定的一些细节以及创建多个不同模式bond接口的正确姿势

本文主要讨论一下linux下bonding驱动生成的bond网卡的一些生效的机制,并且描述了通过命令行和配置文件实现管理bond网卡的方法。希望对大家在使用到linux的bond接口时起到一定的帮助。...

酷炫的外部开启Activity新姿势

酷炫的外部开启Activity新姿势在H5页面疯狂的今天,H5和Native的交互就至关重要,而且交互的方式有很多,google提供了一个公共的方式:js与native互调,即js可以调用Native...

让Activity更加简洁第二篇---AsyncTask的使用姿势

如果你点开的这篇文章,那么 AsyncTask 的基本用法肯定是掌握了的。这篇文章不是分析 AsyncTask的内部原理,而是侧重于如何使用,让我们视图层中的Activity看起来更舒适。本文的项目地...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)