Android笔记一.深入理解Intent和IntentFilters(一)
来源:互联网 发布:游戏王软件 编辑:程序博客网 时间:2024/06/05 14:21
深入理解Intent和IntentFiler(一)
转载请表明出处:http://blog.csdn.net/u012637501(嵌入式_小J的天空)
为了比较深刻的理解并灵活使用Intent,我计划将这部分的学习分为两步:一是深入理解Intent基本概念以及其类;二是,通过实例来阐述如何灵活使用Intent来启动一个组件以及实现组件之间的传递数据。
一、什么是Intent,有什么作用?
Android的应用程序包括四大组件:Activity、contentProvider、Service、BroadcastReceiver,为了方便不同组件之间的交流通信,应用程序就采用了一种统一的方式启动组件及传递数据,即使用Intent。
Intent封装了Android应用程序需要启动某个组件的"意图",Intent类的对象是组件间的通信载体,一个Intent对象就是一组信息,其包含接收Intent组件所关心的信息(如action 和 Data)和Android 系统关心的信息(如Category等)。也就是说,发送"意图"的组件通过Intent对象所包含的内容,来启动指定的(即Component属性)或通过筛选(即Action&Category属性)的某(些)组件,然后实施相应的动作(即Action属性)并传递相应的数据(即Data属性)以便完成相应的动作。
二、Intent是如何实现组件间相互调用?1.Intent实现
三、Intent对象详解 上图请求一个Activity组件的简单的实现流程图,算是用的最多的Intent解析实例。
首先,发出"意图"的组件,通过调用Context.startActivity(intent)开始启动组件:发出"意图"的组件传入已经构好的Intent对象(为一组信息,它决定了是否能够成功的启动另一个组件);
然后,调用"动作"实际的执行着Instrumentation对象,它是整个应用激活的Activity管理者,集中负责应用内所有Activity的运行。它有一个隐藏的方法execStartActivity方法,就是负责根据Intent启动Activity。该方法去掉一些细节,它做得最重要的事情,就是将此调用,通过RPC的方式,传递到ActivityManagerService。
最后,ActivityManagerService会将这些关键信息递交给另一个服务PackageManagerService,此服务掌握整个软件包及其各组件的信息,它会将传递过来的Intent,与已知的所有Intent Filters进行匹配(如果带有Component信息,就不用比了)。如果找到了,就把相关Component的信息通知回AcitivityManagerService,在这里,会完成启动Activity这个很多细节的事情。
2.Intent匹配 到底发出"意图"的组件是如何找到所需的组件呢?在这里,Intent Filters就开始起作用了,Intent Filters定义在AndroidMainFest.xml文件中,每一个Activity都会有一个<Intent Filters/>元素,它包含了<action/>、<data/>等子元素。当我们的intent对象没有包含Component信息时,这种"意图"被称之为隐形"意图"。也就是说,"意图"没有指明具体要启动哪个组件以及完成什么样的动作。这时我们就需要通过Intent Filters中的子元素进行信息匹配,从而确定当前包含Intent Filters属性的Activity是不是我们要启动的那个(些)组件。即发送"意图"组件配置好intent对象,被启动组件实现Intent Filters属性,最后,发送组件会根据被启动组件AndroidMainFest.xml中的<Intent Filters/>信息来确定它是不是目标组件。
Intent类的对象是组件间的通信载体,利用Intent对象我们可以很方便的实现不同组件之间的通信。一个Intent对象就是一组信息,这些信息都是通过其Component、Action、Category、Data、Extra和Flag这7种属性体现的。Intent代表了Android应用的启动"意图",Android应用将会根据Intent来启动指定组件,至于到底启动哪个组件,则取决于Intent的属性。
1.Action属性 Action属性为一个普通的字符串,它代表了该Intent对象要完成一个什么样的"动作"。当我们为Intent对象指明了一个action时,被启动的组件就会依照这个动作的指示表现出相应的行为,比如查看、拨打、编辑等,需要注意的是一个组件(如Activity)只能有一个action。我们可以方便自己的应用程序组件之间的通信,自定义action的(字符串)创建新的动作;也可以直接使用Intent类中的静态成员变量,比如ACTION_VIEW,ACTION_PICK,它们是Android中为action属性预定义的一批action变量。
在设置Intent对象Action属性时,有两种:
(1)自定义字符串public final String CUSTOME_ACTION="intent.action.CUSTOME_JIANG";//字符串可以任意Intent intent=new Intent();intent.setAction(ActionAttr.CUSTOME_ACTION); //注意:ActionAttr为我们创建的类,也可以使用this.CUSTOME_ACTION(2)使用系统预定action常量Intent intent=new Intent();intent.setAction(Intent.ACTION_CALL); //其中ACTION_CALL为Intent类的静态成员变量,可以类直接调用 //对应字符串"android.intent.action.CALL"
Action属性为Intent对象描述了一个"动作",那么Data属性就为Intent对象的Action属性提供了操作的数据。这里需要注意的是,Data属性只接受一个Uri对象,一个Uri对象通常通过如下形式的字符串来表示:
Uri字符串格式:scheme://host:port/path 举例: content://com.android.contacts/contacts/1或tel://18819463209
在设置Intent对象Data属性时可以这样:
Intent intent=new Intent();String data="content://com.android.contacts/contacts/1";Uri uri=Uri.parse(data);//将字符串转换为Uriintent.setData(uri);或者Intent intent=new Intent();intent.setData(Uri.parse("content://com.android.contacts/contacts/1"));
博主笔记1:action属性和data属性为Intent所传递信息的主要部分,action/data属性举例:
ACTION_VIEW content://contacts/people/1 -- 传递的信息: 显示 号码为1的人相关信息
ACTION_DIAL content://contacts/people/1 -- 传递的信息:给编号为1的人 打 电话
ACTION_VIEW tel:123 -- 传递的信息:将号码123 显示
ACTION_DIAL tel:123 --传递的信息: 拨打 号码123
ACTION_EDIT content://contacts/people/1 -- 传递的信息: 编辑编号为1的联系人
ACTION_VIEW content://contacts/people/ -- 传递的信息:列出显示所有联系人.如果希望在查看某个联系人,需要定义一个新的intent并且属性设置为{ ACTION_VIEW content://contacts/N } 传递到一个新的Activity。
总结:action属性、data属性是intent的主要属性。
通过Action,配合Data或Type属性可以准确的表达出一个完整的意图了。但为了使的"意图"更加精确,我们也给意图添加一些约束,这个约束由"意图"的Catagory属性实现。一个意图只能指定一个action属性,但是可以添加一个或多个Catagory属性。Category属性可以自定义字符串实现,但为了方便不同应用之间的通信还可以设置系统预定义的Category常量。调用方法addCategory 用来为Intent 添加一个Category,方法removeCategory 用来移除一个Category;getCategories方法返回已定义的Category。
在设置Intent对象Categoty属性时可以这样:
(1)自定义字符串public final String CUSTOME_CATEGORY="intent.action.CUSTOME_CATEGORY";//字符串可以任意Intent intent=new Intent();intent.addCategory(ActionAttr.CUSTOME_CATEGORY); (2)使用系统预定action、category常量 以下代码实现当点击某个按钮时,通过Intent对象实现返回HOME桌面。Intent intent=new Intent();intent.setAction(Intent.ACTION_MAIN);intent.addCategory(Intent.CATEGORY_HOME);//返回Home桌面
博主笔记2:一般来说Action属性和Category属性都是同时使用的。在Android中,所有应用主Activity(就是单独启动时候,第一个运行的那个Activity...),都需要能够接受一个Category为 CATEGORY_LAUNCHER,Action为ACTION_Main的意图。对于发出"意图"的组件,我们可以通过setAction()、addCategory()方法为"意图"添加action属性或者同时添加Action、Category属性;对于接收"意图"的组件,在AndroidManifest.xm文件中,我们可以这样设置:
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".ActionCateAttr"
android:label="第一个Activity界面" >
<intent-filter>
<action android:name="android.intent.action.MAIN" /> //默认Action
<category android:name="android.intent.category.LAUNCHER" /> //默认Category
</intent-filter>
</activity>
<activity
android:name=".SecondaryActivity"
android:label="第二个Activity界面" >
<intent-filter>
<action android:name="intent.action.JIANG_ACTION" />
<category android:name="intent.action.JIANG_CATEGORY" />
<category android:name="android.intent.category.DEFAULT" /> //默认Category
</intent-filter>
</activity>
注释:发出"意图"的Activity将Category为 CATEGORY_LAUNCHER,Action为ACTION_Main,接收"意图"的Activity须设置一个默认的Category属性CATEGORY_DEFAULT,这里不能将其设置为CATEGORY_LAUNCHER否者会报错。另外,如果我们使用了系统预定义的action常量,则需要在AndroidManifest.xm文件中添加相应的权限,这方面的内容我们将在第二部分讲到。
4.Type属性
Type属性用于指定该Data所指定Uri对应的MIME类型,这种类型可以是任何自定义的MIME类型,只要符合abc/xyz格式的字符串即可。这里需要注意的是,Type属性和Data属性一般会出现相互覆盖的情况,如果希望Intent既有Data属性也有Type属性,必须通过setDataAndType()方法来实现。对于Type属性的理解,我记得有篇博文是这样作比方的:说了Data,就必须要提Type,很多时候,会有人误解,觉着Data和Type的差别,就犹如泡妞和泡马子之间的差别一样,微乎其微。但其实不然,Type信息,是用MIME来表示的,比如text/plain,这样的东西。说到这里,两者差别就很清晰了,Data就是门牌号,指明了具体的位置,具体问题具体分析,而type,则是强调物以类聚,解决一批量的问题。实际的例子是这样的,比如,从某个应用拨打一个电话,会发起的是action为ACTION_DIAL且data为tel:xxx这样的Intent,对应的人类语言就是拨打xxx的电话,很具象。而如果使用type,就宽泛了许多,比如浏览器收到一个未知的MIME类型的数据(比如一个视频...),就会放出这样的Intent,求系统的其他应用来帮助,表达成自然语言应该就是:查看pdf类文档,这样的。
常见的MIME类型(通用型):
超文本标记语言文本 .html text/html
xml文档 .xml text/xml
XHTML文档 .xhtml application/xhtml+xml
普通文本 .txt text/plain
RTF文本 .rtf application/rtf
PDF文档 .pdf application/pdf
Microsoft Word文件 .word application/msword
PNG图像 .png image/png
GIF图形 .gif image/gif
JPEG图形 .jpeg,.jpg image/jpeg
au声音文件 .au audio/basic
MIDI音乐文件 mid,.midi audio/midi,audio/x-midi
RealAudio音乐文件 .ra, .ram audio/x-pn-realaudio
MPEG文件 .mpg,.mpeg video/mpeg
AVI文件 .avi video/x-msvideo
GZIP文件 .gz application/x-gzip
TAR文件 .tar application/x-tar
任意的二进制数据 application/octet-stream
5.Ertras属性6.Flags属性四、Intent相关类
(2)常用方法
通过上面的这些项,识别问题,基本完美解决了,剩下一个重要的问题,就是传参。Extras是用来做这个事情的,它是一个Bundle 类的对象,有一组可序列化的key/value对组成。每一个Action都会有与之对应的key和value类型约定,发起Intent的时候,需要按照要求把Data不能表示的额外参数放入Extras中。
能识别,有输入,整个Intent基本就完整了,但还有一些附件的指令,需要放在Flags中带过去。顾名思义,Flags是一个整形数,有一些列的标志 位构成,这些标志,是用来指明运行模式的。比如,你期望这个意图的执行者,和你运行在两个完全不同的任务中(或说进程也无妨吧...),就需要设置FLAG_ACTIVITY_NEW_TASK 的标志位。
7.Component属性
通常来说,"意图"可分为显示intent和隐式intent。Intent Filters它是用来描述一个Activity或 Serveice等组件,我们通过在组件AndroidManifest.xml中<intent-ilters/>元素中添加<action/>等属性,以满足期望能够响应怎么样的Intent,这种没有指明要启动组件名方式就称之为隐式intent。当然,我们也可以使"意图"实现启动指定的组件,即称之为显示intent,主要通过Component属性来实现。Intent的Component属性需要接受一个ComponentName对象,这个对实现将要启动指定组件的类名、类所在的包名绑定在intent上。
ComponentName comp=new ComponentName(ComponentAttr.this,SecondaryActivity.class); Intent intent=new Intent();intent.setComponent( comp);//设置intent的Component属性,指定"意图"要启动组件的包和类名注释:第一句用于创建一个ComponentName对象,来指定包名和类型-这就可以唯一地确定一个组件类。
1.Activity类
这里我们只需学习使用Intent启动Activity组件将要用的的方法
void
startActivity(Intent intent)
作用:启动Activity,具体启动哪个Activity和怎么样启动由intent属性决定
voidstartActivityForResult(Intent intent, int requestCode)
作用:启动Activity,并返回一个结果。当被启动的Activity退出时,会调用 onActivityResult() 方法并向其传入一个 requestCode参数,这个 requestCode参数为非负数(>0),作用是标志是哪个Activity组件发出的"意图",需要注意的是如果 requestCode小于0时,这个方法的只能用于启动一个Activity而不能返回值了。另外,Intent的action属性设为能够返回一个结果,如果设置为
Intent.ACTION_MAIN
or Intent.ACTION_VIEW,也是不能获取结果的。
待写:另外还有如何启动Service、BroadcastReceiver组件的方法,这以后学到了再说吧。
2.Intent类
(1)构造函数
Intent():创建一个空的构造函数 Intent(Intent o) :拷贝构造函数
Intent(String action) :创建一个具有acion属性的意图对象
Intent(String action, Uri uri):创建一个带action属性的意图,接受一个Uri对象
Intent(Context packageContext, Class<?> cls):创建一个已经指定组件的意图
Intent(String action, Uri uri, Context packageContext, Class<?> cls)
为一个指定的组件创建一个带action和data属性的意图
Intent
addCategory(String category)
Add a new category to the intent.
Intent
addFlags(int flags)
Add additional flags to the intent (or with existing flags value).
String
getAction()
Retrieve the general action to be performed, such as
ACTION_VIEW
.Set<String>
getCategories()
Return the set of all categories in the intent.
ComponentName
getComponent()
Retrieve the concrete component associated with the intent.
Uri
getData()
Retrieve data this intent is operating on.
Bundle
getExtras()
Retrieves a map of extended data from the intent.
int
getFlags()
Retrieve any special flags associated with this intent.
static Intent
getIntent(String uri)
This method was deprecated in API level 4. Use
parseUri(String, int)
instead.String
getPackage()
Retrieve the application package name this Intent is limited to.
String
getScheme()
Return the scheme portion of the intent's data.
Intent
getSelector()
Return the specific selector associated with this Intent.
Rect
getSourceBounds()
Get the bounds of the sender of this intent, in screen coordinates.
String
getType()
Retrieve any explicit MIME type included in the intent.
boolean
hasCategory(String category)
Check if a category exists in the intent.
boolean
hasExtra(String name)
Returns true if an extra value is associated with the given name.
static Intent
makeMainActivity(ComponentName mainActivity)
Create an intent to launch the main (root) activity of a task.
static Intent
makeMainSelectorActivity(String selectorAction, String selectorCategory)
Make an Intent for the main activity of an application, without specifying a specific activity to run but giving a selector to find the activity.
static Intent
parseIntent(Resources resources, XmlPullParser parser, AttributeSet attrs)
Parses(解析) the "intent" element (and its children) from XML and instantiates an Intent object.
static Intent
parseUri(String uri, int flags)
Create an intent from a URI.
Intent
putExtra(String name, int value)
Add extended data to the intent.
Intent
putExtra(String name, CharSequence value)
Add extended data to the intent.
Intent
setAction(String action)
Set the general action to be performed.
Intent
setClass(Context packageContext, Class<?> cls)
Convenience for calling
setComponent(ComponentName)
with the name returned by a Class
object.Intent
setClassName(Context packageContext, String className)
Convenience for calling
setComponent(ComponentName)
with an explicit class name.Intent
setClassName(String packageName, String className)
Convenience for calling
setComponent(ComponentName)
with an explicit application package name and class name.Intent
setComponent(ComponentName component)
(Usually optional) Explicitly set the component to handle the intent.
Intent
setData(Uri data)
Set the data this intent is operating on.
Intent
setFlags(int flags)
Set special flags controlling how this intent is handled.
Intent
setPackage(String packageName)
(Usually optional) Set an explicit application package name that limits the components this Intent will resolve to.
void
setSourceBounds(Rect r)
Set the bounds of the sender of this intent, in screen coordinates.
Intent
setType(String type)
Set an explicit MIME data type.
String
toString()
Returns a string containing a concise(简洁), human-readable (可读)description of this object.
String
toUri(int flags)
Convert this Intent into a String holding a URI representation of it.
即ACTION、CAYEGORY常量等,由Intent或其对象调用设置intent属性
a.标准Activity Actions
以下actions常量,用于Intent定义用来操作各种Activity,通常使用 startActivity(Intent)方法实现。
ACTION_MAIN //传递返回到主Activity动作
ACTION_VIEW //传递显示动作
ACTION_ATTACH_DATA
ACTION_EDIT //传递编辑动作
ACTION_PICK
ACTION_CHOOSER //传递选择动作
ACTION_GET_CONTENT
ACTION_DIAL
ACTION_CALL
ACTION_SEND
ACTION_SENDTO
ACTION_ANSWER //传递接听电话动作
ACTION_INSERT
ACTION_DELETE
ACTION_RUN
ACTION_SYNC
ACTION_PICK_ACTIVITY
ACTION_SEARCH
ACTION_WEB_SEARCH
ACTION_FACTORY_TEST
以下"意图"的action属性常量,用于接收广播,通常使用 registerReceiver(BroadcastReceiver, IntentFilter)方法或者在AndroidManifest.xml 文件中定义了<receiver>属性的Activity。
ACTION_TIME_TICK
ACTION_TIME_CHANGED
ACTION_TIMEZONE_CHANGED
ACTION_BOOT_COMPLETED
ACTION_PACKAGE_ADDED
ACTION_PACKAGE_CHANGED
ACTION_PACKAGE_REMOVED
ACTION_PACKAGE_RESTARTED
ACTION_PACKAGE_DATA_CLEARED
ACTION_UID_REMOVED
ACTION_BATTERY_CHANGED
ACTION_POWER_CONNECTED
ACTION_POWER_DISCONNECTED
ACTION_SHUTDOWN
为Action增加额外的附加类别信息,通常使用addCategory (String category)方法。
CATEGORY_DEFAULT
CATEGORY_BROWSABLE
CATEGORY_TAB
CATEGORY_ALTERNATIVE
CATEGORY_SELECTED_ALTERNATIVE
CATEGORY_LAUNCHER
CATEGORY_INFO
CATEGORY_HOME
CATEGORY_PREFERENCE
CATEGORY_TEST
CATEGORY_CAR_DOCK
CATEGORY_DESK_DOCK
CATEGORY_LE_DESK_DOCK
CATEGORY_HE_DESK_DOCK
CATEGORY_CAR_MODE
CATEGORY_APP_MARKET
通过putExtra(String, Bundle)方法实现。
EXTRA_ALARM_COUNT
EXTRA_BCC
EXTRA_CC
EXTRA_CHANGED_COMPONENT_NAME
EXTRA_DATA_REMOVED
EXTRA_DOCK_STATE
EXTRA_DOCK_STATE_HE_DESK
EXTRA_DOCK_STATE_LE_DESK
EXTRA_DOCK_STATE_CAR
EXTRA_DOCK_STATE_DESK
EXTRA_DOCK_STATE_UNDOCKED
EXTRA_DONT_KILL_APP
EXTRA_EMAIL
EXTRA_INITIAL_INTENTS
EXTRA_INTENT
EXTRA_KEY_EVENT
EXTRA_ORIGINATING_URI
EXTRA_PHONE_NUMBER
EXTRA_REFERRER
EXTRA_REMOTE_INTENT_TOKEN
EXTRA_REPLACING
EXTRA_SHORTCUT_ICON
EXTRA_SHORTCUT_ICON_RESOURCE
EXTRA_SHORTCUT_INTENT
EXTRA_STREAM
EXTRA_SHORTCUT_NAME
EXTRA_SUBJECT
EXTRA_TEMPLATE
EXTRA_TEXT
EXTRA_TITLE
EXTRA_UID
通过 setFlags(int) 和addFlags(int)设置intent的flags属性。
getFlags()
addFlags(int)
FLAG_GRANT_READ_URI_PERMISSION
FLAG_GRANT_WRITE_URI_PERMISSION
FLAG_GRANT_PERSISTABLE_URI_PERMISSION
FLAG_GRANT_PREFIX_URI_PERMISSION
FLAG_DEBUG_LOG_RESOLUTION
FLAG_FROM_BACKGROUND
FLAG_ACTIVITY_BROUGHT_TO_FRONT
FLAG_ACTIVITY_CLEAR_TASK
FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
FLAG_ACTIVITY_FORWARD_RESULT
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
FLAG_ACTIVITY_MULTIPLE_TASK
FLAG_ACTIVITY_NEW_DOCUMENT
FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_NO_ANIMATION
FLAG_ACTIVITY_NO_HISTORY
FLAG_ACTIVITY_NO_USER_ACTION
FLAG_ACTIVITY_PREVIOUS_IS_TOP
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
FLAG_ACTIVITY_REORDER_TO_FRONT
FLAG_ACTIVITY_SINGLE_TOP
FLAG_ACTIVITY_TASK_ON_HOME
FLAG_RECEIVER_REGISTERED_ONLY
参考:http://developer.android.com/reference/android/net/Uri.html
0 0
- Android笔记一.深入理解Intent和IntentFilters(一)
- Android笔记五.深入理解Intent和IntentFilters(一)
- 深入理解Intent和IntentFiler(一)
- Android笔记二.深入理解Intent和IntentFilter(二)
- Android学习笔记-Intent(一)
- Android学习笔记-Intent(一)
- 《深入理解计算机系统》笔记一
- android 学习笔记(一):Intent 和 Intent 过滤器 跟着API指南来学习
- Android学习笔记(一)-------浅谈Intent思路
- Android学习笔记(一) Intent用法总结
- [深入理解Android卷一全文-第九章]深入理解Vold和Rild
- [深入理解Android卷一全文-第九章]深入理解Vold和Rild
- 深入理解计算机学习笔记(一)
- 笔记一 深入理解体系与架构
- 《深入理解计算机系统》学习笔记(一)
- 深入理解计算机系统学习笔记(一)
- 《深入理解计算机系统》读后笔记一
- 深入理解计算机网络—学习笔记一
- 一些 Oracle Sql 语句的使用
- Android:Layout_weight的深刻理解
- 一个简单的easyui动态初始化datagrid的列名的实例
- POI读取Excel浅谈
- Poi 读写Excel 合并ExcelSheet Struts2实现
- Android笔记一.深入理解Intent和IntentFilters(一)
- Linux 下FTP搭建
- POI Excel导出,我的又一个模板方法
- 一个Java时间工具类
- 进程和线程的概念、区别与联系
- Redhat 5 下 Oracle10g 安装 修改版
- CSS cursor 属性
- javascript——运动侧边分享
- DES加密使用