必威体育Betway必威体育官网
当前位置:首页 > IT技术

Intent的基本知识

时间:2019-07-02 18:44:32来源:IT技术作者:seo实验室小编阅读:67次「手机版」
 

intent

我们知道,intent 是一个消息传递对象,使用它可以向其他Android组件请求操作。Intent的基本用途主要包括:启动 Activity、启动服务、传递广播。Intent分为显式Intent和隐式Intent。下面我通过启动Activity来讲解学习Intent。

Intent对象可以封装传递下面6种信息:

  1. 组件名称(componentname)
  2. 动作(Action)
  3. 种类(Category)
  4. 数据(Data)
  5. 附件信息(Extra)
  6. 标志(Flag)

下面来讲解这些信息

1、组件名称(CompomentName)

组件名称指定要访问的组件,但也是构建显式 Intent 的一项重要信息,如下所示:

Intent intent = new Intent(LoginActivity.this, HomeActivity.class);

startActivity(intent);

这样我们就启动了HomeActivity组件。

通过构造函数指定组件名称是我们常用的方式,此外还可以通过以下三种方法指定组件名称

Intent setClass (context packageContext,  Class<?> cls);

Intent setClassName (Context packageContext, String className);

Intent setClassName (String packageName, String className);

Intent setComponent (ComponentName component)

这里首先需要说明是的CompomentName对象,它定义了一个组件的基本信息,通过Android的源代码我们可以看到,其实不论哪种方法,最终Intent都会创建一个CompomentName对象封装被调用的组件信息。

其次我们来看一下Intent setClassName (String packageName, String className);这个方法。packageName指的是组件所属APP的包名。也就是Androidmanifest.xml中指定的包名,如下图所示:

最后,需要说明的是,如果传递字符串形式的className,必须指定类的全名,包括类所属的命名空间。下面给出了一个样例代码:

Intent intent = new Intent();

intent.setClassName("com.practise.salary.nvwa", "com.practise.salary.nvwa.HomeActivity");

startActivity(intent);

设置Intent的组件名称,调用相关的组件,我们称为显式调用,一般用于调用APP自身的组件,当然,我们也可以通过显式调用其他APP的组件,后面讲解显示调用时,我们在来学习。

2、动作(Action)

所谓动作就是与Activity、Service、BroadcastRecvier绑定的一个字符串,通常在AndroidManifest.xml声明组件时,设置动作参数,如下图所示:

我们可以通过设置Action属性,调用相关的组件,这称为隐式调用。

一般我们通过Intent的setAction方法设置Intent的动作,这样系统会根据动作中指定的字符串查找匹配的组件。如下所示代码:

Intent intent = new Intent();

intent.setAction("android.intent.action.MaiN");

startActivity(intent);

当我们定义自己的操作,建议将应用的软件包名称作为前缀,动作名称用大写。

3、种类(Category)

运行上面的代码,大家会发现,弹出了一个选择框,选在调用那个组件,如下图所示:

之所以会出现这种情况,是因为动作“android.intent.action.MAIN”对应的组件不止一个,Android系统无法判断到底调用那个组件(详细的筛选过程将在后面过滤规则中讲解)。

Intent的Category的就是为了解决这类冲突问题的,Category的设置也是在AndroidManifest.xml文件中完成,如下图所示:

Category也是一个字符串,我们可以通过addCategory为Intent添加Category,可以添加多个Category,如下面代码所示:

Intent intent = new Intent();

intent.setAction("com.practise.salary.nvwa.action.HOME");

/*

我们可以不用手动添加android.intent.category.DEFAULT,系统会自动添加这个Category

*/

intent.addCategory("android.intent.category.DEFAULT");  

startActivity(intent);

我们可以通过文件夹、文件类比Category和Action。

4、数据(Data)

在Intent的隐式调用中,系统要根据请求对满足条件的组件进行筛选,这就是Intent的筛选机制。筛选条件除了Action、Category外,还有一个就是Data。此外Data还承担了简单的数据传递工作

组件Data的申明如下图所示:

下面我们学习一下Intent的Data属性。

Data包括MIME Type和URI。

MIME Type指数据的类型,例如:video/mp4,video/avi通常我们通过

Intent setType (String type)

或者

Intent setTypeAndNormalize (String type)

完成MINE Type的设置。不同之处在于setTypeAndNormalize可以规范MINE Type。

URI,统一资源标识符(Uniform Resource Identifier,或URI)是一个用于标识某一资源名称的字符串,URI可以表示成如下格式:

scheme://host:port/path

  其中

  1. scheme:协议表示,如HTTP,https,ftp,content等;
  2. host:主机名称
  3. port:端口
  4. path:具体的资源路径

我们常见的url地址就是一种特殊的URI。

我们可以通过

Intent setData (Uri data)

Intent setDataAndNormalize (Uri data)

来设置Intent的URI,注意此处需要传递的是一个Uri对象,该对象封装了具体的URI,我们采用如下静态方法江URI字符串转换成URI对象。

Uri parse (String uriString)

此外我们还可以调用setDataAndType一次性设置URI和MIME Type。

Intent setDataAndType (Uri data, String type)

Intent setDataAndTypeAndNormalize(Uri data, String type)

需要注意的是,当我们调用setType方法设置MIME Type,会自动清理URI的属性值,当调用setData方法来设置URI时,会自动清理MIME Type的值,如果要同时设置URI和MIMIE Type,必须使用setDataAndType方法。

关于如何通过Data进行过滤,后面我们会讲到,下面我们通过一个样例来讲解如何通过Data完成简单的数据传递。

我们通过显示调用Intent同时设置Intent的Data。代码如下:

Intent intent = new Intent(LoginActivity.this, HomeActivity.class);

intent.setDataAndType(Uri.parse("content://findUser/20180910"), "nvwa/user");

startActivity(intent);

  在被调用的HomeActivity中,我们通过getItent()获取传递来的Intent。然后我们就可以通过

Uri getData ()

String getDataString ()

获取URI,有了URI我们就可以解析出其中数据。下面给出被调用的组件的样例代码

Intent intent = getIntent();

Uri uri = intent.getData();

Log.v("URI参数传递", uri.getPath());

输出结果如下图所示:

Uri类提供了更多的方法用于处理Uri值,可参考Uri相关的帮助 https://developer.android.Google.cn/reference/android/net/Uri。

5、附件信息(Extra)

通过Data只能传输比较简单的数据,Intent主要通过Extra完成组件之间的数据传递。

调用方通过intent的putExtra设置数据,被调用的组件通过getXXXExtra获取数据,代码如下所示:

调用方传递参数

Intent intent = new Intent(LoginActivity.this, HomeActivity.class);

intent.putExtra("userName", "zhangw");

intent.putExtra("loginTime", calendar.getinstance());

startActivity(intent);

被调方获取参数

Intent intent = getIntent();

Log.v("Extra数据传递", intent.getStringExtra("userName"));

我们分析Android代码可以发现,其实通过Exctra传递的是一个Bundle,我们可以把Bundle理解成一个键值对,他通过putXXX设置数据,通过getXXX读取数据。我们可以自己定义一个Bundle对象,进行数据的传递,下面给一个样例程序

  调用方传递参数

Bundle bundle = new Bundle();

bundle.putString("userName", "account");

bundle.putserializable("loginTime", Calendar.getInstance());

intent.putExtras(bundle);

被调方获取参数

Intent intent = getIntent();

Bundle bundle = intent.getExtras();

Log.v("登录时间", bundle.getSerializable("loginTime").toString());

输出结果如下图:

注意,调用方通过intent的getExtras获取传递的来的bundle。

  6、标记(Flag)

Intent通过

Intent setFlags (int flags)

设置标记。   关于标记的用法,后面我们用到后再给大家将,这并不表示这个概念不重要。

(张伟:2018年9月27日)

转载时请注明来源)

相关阅读

Android 关闭多个视图Intent.FLAG_ACTIVITY_CLEAR_TOP

如果已经启动了四个Activity:A,B,C和D。在D Activity里,我们要跳到B Activity,同时希望C finish掉,可以在startActivity(intent)里的int

Android Intent.FLAG_ACTIVITY_NEW_TASK的个人理解

首先分四部曲简单做一下说明 1.What(是什么):Intent类中的一个静态标志属性 public static final int FLAG_ACTIVITY_NEW_TASK = 0

分享到:

栏目导航

推荐阅读

热门阅读