首页 技术 正文
技术 2022年11月20日
0 收藏 426 点赞 4,626 浏览 12411 个字

Android应用将会根据Intent来启动指定组件,至于到底启动哪个组件,则取决于Intent的各属性。本期将详细介绍Intent的各属性值,以及 Android如何根据不同属性值来启动相应的组件。

Intent 对象大致包含 Component、Action、Category、Data、Type、Extra 和 Flag 这 7 种属性,其中Component用于明确指定需要启动的目标组件,而Extra则用于携带需要交换的数据。

一、Component属性

Intent 的 Component 属性需要接受一个 ComponentName 对象,ComponentName 对象包含如下几个构造器。

  • ComponentName(String pkg, String cls):创建pkg所在包下的cls类所对应的组件。

  • ComponentName(Context pkg, String cls):创建pkg所对应的包下的cls类所对应的组件。

  • ComponentName(Context pkg, Class<?> cls):创建 pkg 所对应的包下的 cls 类所对应的组件。

上面几个构造器的本质是相同的,这说明创建一个ComponentName需要指定包名和类名。这样就可以唯一地确定一个组件类,这样应用程序即可根据给定的组件类去启动特定的组件。

除此之外,Intent还包含了如下三个方法。

  • setClass(Context packageContext, Class<?> cls):设置该 Intent 将要启动的组件对应的类。

  • setClassName(Context packageContext, String className):设置该 Intent 将要启动的组件对应的类名。

  • setClassName(String packageName, String className):设置该 Intent 将要启动的组件对应的类名。

指定Component属性的Intent已经明确了它将要启动哪个组件,因此这种Intent也被称为显式Intent,没有指定Component属性的Intent被称为隐式Intent。

下面的示例程序示范了如何通过显式Intent (指定了 Component属性)来启动另一个 Activity。该程序的界面布局很简单,界面中只有一个按钮,用户单击该按钮将会启动第二个Activity。此处不再给出该程序的界面布局文件。该程序的Java代码如下:

package com.jinyu.cqkxzsxy.android.intent.componentattr;import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); Button startBtn = (Button) findViewById(R.id.start_btn);
// 为bn按钮绑定事件监听器
startBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// 创建一个ComponentName对象
ComponentName comp = new ComponentName(MainActivity.this, SecondActivity.class);
Intent intent = new Intent();
// 为Intent设置Component属性
intent.setComponent(comp);
startActivity(intent);
}
});
}
}

上面程序中的onClick回调方法里面的代码用于创建ComponentName对象,并将该对象设置成Intent 对象的Component属性,这样应用程序即可根据该Intent的意图去启动指定组件。 实际上,这几行关键代码完全可以简化为如下形式:

  1. // 根据指定组件类来创建Intent

  2. Intentintent=newIntent(MainActivity.this,SecondActivity.class);

  3. startActivity(intent);

从上面的代码可以看出,当需要为Intent设置Component属性时,实际上Intent己经提供了一个简化的构造器,这样方便程序直接指定启动其他组件。

当程序通过Intent的Component属性(明确指定了启动哪个组件)启动特定组件时,被启动组件几乎不需要使用<intent-filter…/>进行配置。

程序的SecondActivity也很简单,它的界面布局中只包含一个简单的文本框,用于显示该 Activity对应的Intent的Component属性的包名、类名。该Activity的Java代码如下:

package com.jinyu.cqkxzsxy.android.intent.componentattr;import android.content.ComponentName;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second); TextView showTv = (TextView) findViewById(R.id.show_tv);
// 获取该Activity对应的Intent的Component属性
ComponentName comp = getIntent().getComponent();
// 显示该ComponentName对象的包名、类名
showTv.setText("组件包名为:" + comp.getPackageName()
+ "\n组件类名为:" + comp.getClassName());
}
}

运行上面的程序,通过第一个Activity中的按钮进入第二个Activity中,将可以看到下图所示的界面。

Android零基础入门第79节:Intent 属性详解(上)

二、Action属性

Intent的Action属性的值是一个普通的字符串,代表该Intent所要完成的一个抽象动作。

Action要完成的只是一个抽象动作,这个动作具体由哪个组件(或许是Activity,或许是 BroadcastReceiver)来完成,Action这个字符串本身并不管。比如Android提供的标准Action: Intent.ACTION_VIEW,它只表示一个抽象的查看操作,但具体查看什么、启动哪个Activity 来查看,Intent.ACTION_VIEW并不知道——这取决于Activity的<intent-filter…/>配置,只要某个Activity的<intent-filter…/>配置中包含了该ACTION_VIEW,该Actvitiy就有可能被启动。

下面通过一个简单的示例来示范Action属性(就是普通字符串)的作用。下面程序的第一个Activity非常简单,它只包括一个普通按钮,当用户单击该按钮时,程序会“跳转”到第二个Activity。但第一个Activity指定跳转的Intent时,并不指定要跳转的目标Activity,而是为Intent指定Action属性。此处不给出界面布局的代码,第一个Activity 的Java代码如下:

package com.jinyu.cqkxzsxy.android.intent.actionattr;import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;public class MainActivity extends AppCompatActivity {
private static final String TEST_ACTION = "com.jinyu.cqkxzsxy.android.intent.action.TEST_ACTION";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); Button startBtn = (Button) findViewById(R.id.start_btn);
// 为bn按钮绑定事件监听器
startBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// 创建Intent对象
Intent intent = new Intent();
// 为Intent设置Action属性(属性值就是一个普通字符串)
intent.setAction(MainActivity.TEST_ACTION);
startActivity(intent);
}
});
}
}

上面程序中的onClick回调方法里面的代码指定了根据Intent来启动Activity。但该Intent并未指定要启动哪个Activity,从上面程序中的代码无法看出该程序将要启动哪个Activity。那么到底程序会启动哪个Activity呢?这取决于Activity配置中 <intent-fiIter…/>元素的配置。

<intent-filter…/>元素是 AndroidManifest.xml 文件中<activity…/>元素的子元素,前面已经学习过,<activity…/>元素用于为应用程序配置 Activity,<activity…/>的<intent-filter…/>子元素则用于配置该Activity所能“响应”的Intent。

<intent-filter…/>元素里通常可包含如下子元素。

  • 0〜N个<action…/>子元素。

  • 0〜N个<category…/>子元素。

  • 0〜1个<data…/>子元素。

<action…/>、<category…/>子元素的配置非常简单,它们都可指定android:name属性,该属性的值就是一个普通字符串。当<activity…/>元素的<intent-fiIter…/>子元素里包含多个<action…/>子元素(相当于指定了多个字符串)时,就表明该Activity能响应Action属性值为其中任意一个字符串的Intent。

由于上面的程序指定启动Action属性为MainActivity.TEST_ACTION常量的 Activity,也就要求被启动的 Activity 对应的配置元素的<intent-filter…/>元素里至少包括一个<action…/>子元素。另外上面程序中的代码并未指定目标Intent的Category属性,但该Intent 已有一个值为 android.intent.category.DEFAULT 的 Category 属性值,因此被启动 Activity 对应的配置元素的<intent-filter…/>元素里至少还包括一个如下的<category…/>子元素。被启动的Activity的完整配置如下:

        <activity android:name=".SecondActivity">
<intent-filter>
<!-- 指定该Activity能响应Action为指定字符串的Intent -->
<action android:name="com.jinyu.cqkxzsxy.android.intent.action.TEST_ACTION" />
<!-- 指定该Activity能响应Action属性为helloWorld的Intent -->
<action android:name="helloWorld" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

上面Activity配置的代码指定该Activity能响应具有指定Action属性值、默认 Category属性值的Intent。其中有一行代码只是试验用的,对于本程序没有影响——它表明该Activity能响应Action属性值为helloWorld字符串、Category属性值为 android.intent.category.DEFAULT的Intent,但我们的程序并未尝试启动这样的Activity,可以自己尝试用这样的Intent来启动Activity,将会看到程序也会启动该Activity。

上面的配置代码中配置了一个实现类为SecondActivity的Activity,因此程序还应该提供这个Activity代码。代码如下:

package com.jinyu.cqkxzsxy.android.intent.actionattr;import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;public class SecondActivity extends AppCompatActivity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second); TextView showTv = (TextView) findViewById(R.id.show_tv);
// 获取该Activity对应的Intent的Action属性
String action = getIntent().getAction();
// 显示Action属性
showTv.setText("Action为:" + action);
}
}

上面的程序代码很简单,它只是在启动时把启动该Activity的Intent的Action属性值显示在指定文本框内。

运行上面的程序,单击程序中的“启动指定 Action、默认Category对应的Activity”按钮,将看到下图所示界面。

Android零基础入门第79节:Intent 属性详解(上)

实际上Android内部提供了大量标准的Action常量,其中用于启动Activity的标准的Action常量及对应的字符串如下表所示。

Android零基础入门第79节:Intent 属性详解(上)

三、Category属性

Intent的Category属性的值也是一个普通的字符串,用于为Action增加额外的附加类别信息。通常Action 属性与Category属性结合使用。

一个Intent对象最多只能包括一个Action属性,程序可调用Intent的 setAction(String str)方法来设置Action属性值;但一个Intent对象可以包括多个Category属性, 程序可调用Intent的addCategory (String str)方法来为Intent添加Category属性。当程序创建 Intent时,该Intent默认启动Category属性值为Intent.CATEGORY_DEFAULT常量(常量值为 android.intent.category.DEFAULT)的组件。

接下来的示例程序将会示范Category属性的用法。该程序的第一个Activity的代码如下:

package com.jinyu.cqkxzsxy.android.intent.categoryattr;import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;public class MainActivity extends AppCompatActivity {
private static final String TEST_ACTION = "com.jinyu.cqkxzsxy.android.intent.action.TEST_ACTION";
private static final String TEST_CATEGORY = "com.jinyu.cqkxzsxy.android.intent.category.TEST_CATEGORY"; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); Button startBtn = (Button) findViewById(R.id.start_btn);
// 为bn按钮绑定事件监听器
startBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// 创建Intent对象
Intent intent = new Intent();
// 为Intent设置Action属性(属性值就是一个普通字符串)
intent.setAction(MainActivity.TEST_ACTION);
// 添加Category属性
intent.addCategory(MainActivity.TEST_CATEGORY);
startActivity(intent);
}
});
}
}

上面程序中的onClick回调方法里面的代码指定了该Intent的Action属性值为com.jinyu.cqkxzsxy.android.intent.action.TEST_ACTION字符串,并为该 Intent 添加 了 字符串为com.jinyu.cqkxzsxy.android.intent.category.TEST_CATEGORY属性。这意味着上面的程序所要启动的目标Activity里应该包含 <action…/> 子元素和<category…/>子元素。

下面是程序要启动的目标Action所对应的配置代码:

        <activity android:name=".SecondActivity">
<intent-filter>
<!-- 指定该Activity能响应action为指定字符串的Intent -->
<action android:name="com.jinyu.cqkxzsxy.android.intent.action.TEST_ACTION" />
<!-- 指定该Activity能响应category为指定字符串的Intent -->
<category android:name="com.jinyu.cqkxzsxy.android.intent.category.TEST_CATEGORY" />
<!-- 指定该Activity能响应category为android.intent.category.DEFAULT的Intent -->
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

上面配置Activity时也指定该Activity的实现类为SecondActivity,该实现类的代码如下:

package com.jinyu.cqkxzsxy.android.intent.categoryattr;import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;import java.util.Set;public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second); TextView showTv = (TextView) findViewById(R.id.show_tv);
// 获取该Activity对应的Intent的Action属性
String action = getIntent().getAction();
// 获取该Activity对应的Intent的Category属性
Set<String> cates = getIntent().getCategories();
// 显示Category属性
showTv.setText("Action为:" + action + "\nCategory属性为:" + cates);
}
}

上面的程序也很简单,它只是在启动时把启动该Activity的Intent的Action、Catetory属 性值分别显示在不同的文本框内。

运行上面的程序,单击程序中的“启动指定Action、指定 Category对应的Activity”按钮,将看到下图所示的界面。

Android零基础入门第79节:Intent 属性详解(上)

实际上Android内部也提供了大量标准的Catetory常量,其中标准的Category常量及对应的字符串如下表所示。

Android零基础入门第79节:Intent 属性详解(上)

关于Intent的Component、Action、Category三个属性先分享到这里,如果还不够熟悉,建议多加练习。

由于内容较多,本期先学习到这里,下期接着学习其他四个属性。

今天就先到这里,如果有问题欢迎留言一起探讨,也欢迎加入Android零基础入门技术讨论微信群,共同成长!

如果该系列分享对你有帮助,就动动手指关注、点赞、留言吧,你的互动就是对我最大的鼓励!

此文章版权为微信公众号分享达人秀(ShareExpert)——鑫鱻所有,若需转载请联系作者授权,特此声明!

往期总结回顾:

Android零基础入门第1节:Android的前世今生

Android零基础入门第2节:Android 系统架构和应用组件那些事

Android零基础入门第3节:带你一起来聊一聊Android开发环境

Android零基础入门第4节:正确安装和配置JDK, 高富帅养成第一招

Android零基础入门第5节:善用ADT Bundle, 轻松邂逅女神

Android零基础入门第6节:配置优化SDK Manager, 正式约会女神

Android零基础入门第7节:搞定Android模拟器,开启甜蜜之旅

Android零基础入门第8节:HelloWorld,我的第一趟旅程出发点

Android零基础入门第9节:Android应用实战,不懂代码也可以开发

Android零基础入门第10节:开发IDE大升级,终于迎来了Android Studio

Android零基础入门第11节:简单几步带你飞,运行Android Studio工程

Android零基础入门第12节:熟悉Android Studio界面,开始装逼卖萌

Android零基础入门第13节:Android Studio个性化配置,打造开发利器

Android零基础入门第14节:使用高速Genymotion,跨入火箭时代

Android零基础入门第15节:掌握Android Studio项目结构,扬帆起航

Android零基础入门第16节:Android用户界面开发概述

Android零基础入门第17节:文本框TextView

Android零基础入门第18节:输入框EditText

Android零基础入门第19节:按钮Button

Android零基础入门第20节:复选框CheckBox和单选按钮RadioButton

Android零基础入门第21节:开关组件ToggleButton和Switch

Android零基础入门第22节:图像视图ImageView

Android零基础入门第23节:图像按钮ImageButton和缩放按钮ZoomButton

Android零基础入门第24节:自定义View简单使用,打造属于你的控件

Android零基础入门第25节:简单且最常用的LinearLayout线性布局

Android零基础入门第26节:两种对齐方式,layout_gravity和gravity大不同

Android零基础入门第27节:正确使用padding和margin

Android零基础入门第28节:轻松掌握RelativeLayout相对布局

Android零基础入门第29节:善用TableLayout表格布局

Android零基础入门第30节:两分钟掌握FrameLayout帧布局

Android零基础入门第31节:少用的AbsoluteLayout绝对布局

Android零基础入门第32节:新推出的GridLayout网格布局

Android零基础入门第33节:Android事件处理概述

Android零基础入门第34节:Android中基于监听的事件处理

Android零基础入门第35节:Android中基于回调的事件处理

Android零基础入门第36节:Android系统事件的处理

Android零基础入门第37节:初识ListView

Android零基础入门第38节:初识Adapter

Android零基础入门第39节:ListActivity和自定义列表项

Android零基础入门第40节:自定义ArrayAdapter

Android零基础入门第41节:使用SimpleAdapter

Android零基础入门第42节:自定义BaseAdapter

Android零基础入门第43节:ListView优化和列表首尾使用

Android零基础入门第44节:ListView数据动态更新

Android零基础入门第45节:网格视图GridView

Android零基础入门第46节:列表选项框Spinner

Android零基础入门第47节:自动完成文本框AutoCompleteTextView

Android零基础入门第48节:可折叠列表ExpandableListView

Android零基础入门第49节:AdapterViewFlipper图片轮播

Android零基础入门第50节:StackView卡片堆叠

Android零基础入门第51节:进度条ProgressBar

Android零基础入门第52节:自定义ProgressBar炫酷进度条

Android零基础入门第53节:拖动条SeekBar和星级评分条RatingBar

Android零基础入门第54节:视图切换组件ViewSwitcher

Android零基础入门第55节:ImageSwitcher和TextSwitcher

Android零基础入门第56节:翻转视图ViewFlipper

Android零基础入门第57节:DatePicker和TimePicker选择器

Android零基础入门第58节:数值选择器NumberPicker

Android零基础入门第59节:常用三大Clock时钟组件

Android零基础入门第60节:日历视图CalendarView和定时器Chronometer

Android零基础入门第61节:滚动视图ScrollView

Android零基础入门第62节:搜索框组件SearchView

Android零基础入门第63节:值得借鉴学习的选项卡TabHost

Android零基础入门第64节:揭开RecyclerView庐山真面目

Android零基础入门第65节:RecyclerView分割线开发技巧

Android零基础入门第66节:RecyclerView点击事件处理

Android零基础入门第67节:RecyclerView数据动态更新

Android零基础入门第68节:RecyclerView添加首尾视图

Android零基础入门第69节:ViewPager快速实现引导页

Android零基础入门第70节:ViewPager打造TabHost效果

Android零基础入门第71节:CardView简单实现卡片式布局

Android零基础入门第72节:SwipeRefreshLayout下拉刷新

Android零基础入门第73节:Activity创建和配置

Android零基础入门第74节:Activity启动和关闭

Android零基础入门第75节:Activity状态和生命周期

Android零基础入门第76节:Activity数据保存和横竖屏切换

Android零基础入门第77节:Activity任务栈和启动模式

Android零基础入门第78节:四大组件的纽带——Intent

Android零基础入门第79节:Intent 属性详解(上)

Android零基础入门第79节:Intent 属性详解(上)

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,075
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,551
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,399
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,176
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,811
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,893