Android--Intent和IntentFilter详解

Intent用于启动Activity, Service, 以及BroadcastReceiver三种组件, 同时还是组件之间通信的重要媒介.

使用Intent启动组件的优势
1, Intent为组件的启动提供了一致的编程模型. 无论想要启动的组件是Activity, Service, 还是BroadcastReceiver, 都可以使用Intent封装启动的意图.
2, 在某些时候, 应用程序只是想启动具有某种特征的组件, 并不想和某个特定的组件耦合. 使用Intent可以方便的达到这种高层次解耦的目的.

Intent的Component属性
Intent对象的setComponent(ComponentName comp)方法用于设置Intent的Component属性. ComponentName包含如下几个构造器:
ComponentName(String pkg, String cls)
ComponentName(Context pkg, String cls)
ComponentName(Context pkg, Class<?> cls)
由以上的构造器可知, 创建一个ComponentName对象需要指定包名和类名--这就可以唯一确定一个组件类, 这样应用程序即可根据给定的组件类去启动特定的组件. 例如:
ComponentName comp = new ComponentName(FirstActivity.this, SecondActivity.class);
Intent intent = new Intent();
intent.setComponent(comp);
以上三句代码创建了一个intent对象, 并为其指定了Component属性, 完全等价于下面的代码:
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
除了使用setComponent() 之外, 还可以使用setClass(), setClassName()来显式指定目标组件, 还可以调用getComponent()方法获得Intent中封装的ComponentName对象.
当程序采用这种形式启动组件时, 在Intent中明确的指定了待启动的组件类, 此时的Intent属于显式intent, 显式Intent应用场合比较狭窄, 多用于启动本应用中的component, 因为这种方式需要提前获知目标组件类的全限定名. 而隐式Intent则通过Intent中的action, category, data属性指定目标组件需要满足的若干条件, 系统筛选出满足所有条件的component, 从中选择最合适的component或者由用户选择一个component作为目标组件启动.
如果Intent中指定了ComponentName属性, 则Intent的其他属性将被忽略.

Intent的Action属性
action属性是一个字符串, 代表某一种特定的动作. Intent类预定义了一些action常量, 开发者也可以自定义action. 一般来说, 自定义的action应该以application的包名作为前缀, 然后附加特定的大写字符串, 例如"cn.xing.upload.action.UPLOAD_COMPLETE"就是一个命名良好的action.
Intent类的setAction()方法用于设定action, getAction()方法可以获取Intent中封装的action.
以下是Intent类中预定义的部分action:
ACTION_CALL--目标组件为activity, 代表拨号动作;
ACTION_EDIT--目标组件为activity, 代表向用户显示数据以供其编辑的动作;
ACTION_MAIN--目标组件为activity, 表示作为task中的初始activity启动;
ACTION_BATTERY_LOW--目标组件为broadcastReceiver, 提醒手机电量过低;
ACTION_SCREEN_ON--目标组件为broadcast, 表示开启屏幕.

Intent的Category属性
category属性也是一个字符串, 用于指定一些目标组件需要满足的额外条件. Intent对象中可以包含任意多个category属性. Intent类也预定义了一些category常量, 开发者也可以自定义category属性.
Intent类的addCategory()方法为Intent添加Category属性, getCategories()方法用于获取Intent中封装的所有category.
以下是Intent类中预定义的部分category:
CATEGORY_HOME--表示目标activity必须是一个显示home screen的activity;
CATEGORY_LAUNCHER--表示目标activity可以作为task栈中的初始activity, 常与ACTION_MAIN配合使用;
CATEGORY_GADGET--表示目标activity可以被作为另一个activity的一部分嵌入.

Intent的Data属性
data属性指定所操作数据的URI. data经常与action配合使用, 如果action为ACTION_EDIT, data的值应该指明被编辑文档的URI; 如果
action为ACTION_CALL, data的值应该是一个以"tel:"开头并在其后附加号码的URI; 如果action为ACTION_VIEW, data的值应该是一个以"http: "开头并在其后附加网址的URI...
Intent类的setData()方法用于设置data属性, setType()方法用于设置data的MIME类型, setDataAndType()方法可以同时设定两者. 可以通过getData()方法获取data属性的值, 通过getType()方法获取data的MIME类型.

Intent的Extra属性
通过Intent启动一个component时, 经常需要携带一些额外的数据过去. 携带数据需要调用Intent的putExtra()方法, 该方法存在多个重载方法, 可用于携带基本数据类型及其数组, String类型及其数组, Serializable类型及其数组, Parcelable类型及其数组, Bundle类型等. Serializable和Parcelable类型代表一个可序列化的对象
, Bundle与Map类似,可用于存储键值对.

Intent的Flag属性
flag属性是一个int值, 用于通知android系统如何启动目标activity, 或者启动目标activity之后应该采取怎样的后续操作. 所有的flag都在Intent类中定义, 部分常用flag如下:
FLAG_ACTIVITY_NEW_TASK--通知系统将目标activity作为一个新task的初始activity;
FLAG_ACTIVITY_NO_HISTORY--通知系统不要将目标activity放入历史栈中;
FLAG_FROM_BACKGROUND--通知系统这个Intent来源于后台操作, 而非用户的直接选择...

IntentFilter类
IntentFilter类表示Intent过滤器, 大部分情况下, 每一个component都会定义一个或多个IntentFilter, 用于表明其可处理的Intent.
一般来说, component的IntentFilter应该在AndroidManifest.xml文件中定义.
定义的方法: 在<activity>, <receiver>, <service>元素中增加一个或多个<intent-filter>子元素. 如:

<activity android:name=".FirstActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

IntentFilter与隐式Intent
android系统处理隐式Intent时, 会比较Intent和IntentFilter的action, data, category属性, 如果以上3个属性全都相符的话, 则IntentFilter所属的component就可以作为目标组件的候选(存在多个符合条件的component时).

  1. 测试action属性. intent最多只能定义1个action, 而filter可以定义1个或多个action.
    通过action测试的条件为: filter定义了intent的action. 例如intent的action为"android.intent.action.MAIN", 则定义了"android.intent.action.MAIN"这个action的filter都能通过action测试(当然, filter还可以包含更多额外的action).
    如果filter没有定义action, 则这个filter将阻塞所有intent. 如果intent没有定义action, 那么只要filter定义了action就可以通过action测试.
  2. 测试category属性. intent可以任意多个category, filter也可以任意个category. 通过category测试的条件为: filter定义了intent的所有category. 例如intent定义了"android.intent.category.DEFAULT"和"cn.xing.intent.category.UPLOAD"这2个category, 则定义了以上2个category属性的filter才能通过测试(当然, filter还可以包含更多额外的category).
    根据上面的规则, 如果一个intent没有定义category, 则所有filter都可以通过category测试. 但是有一种例外: 以startActivity(intent)方式启动一个activity时, 系统为会intent增加一个值为"android.intent.category.DEFAULT"的category, 这就意味着每一个期望通过category测试的activity, 都要在其filter中定义"android.intent.category.DEFAULT"(除了作为程序入口的activity).
  3. 测试data属性. intent最多只能定义1个data, filter则可以定义多个data.
    通过data测试的条件为:
    a. 如果intent没有指定data和data type, 则只有没有定义data和date type的filter才能通过测试;
    b. 如果intent定义了data没有定义data type, 则只有定义了相同data且没有定义date type的filter才能通过测试;
    c. 如果intent没有定义data却定义了data type, 则只有未定义data且定义了相同的data type的filter才能通过测试;
    d. 如果intent既定义了data也定义了data type, 则只有定义了相同的data和data type的filter才能通过测试.
    data属性是一个URI, URI中包含scheme, host, post和path, 典型的URI为:
    scheme://host:port/path
    scheme, host, post和path都是可选的. 比较2个data时, 只比较filter中包含的部分. 比如filter的一个data只是指定了scheme部分, 则测试时只是比较data的scheme部分, 只要两者的scheme部分相同, 就视为"相同的data".

Intent:用于向下传参数
传出Activity代码:

String data = "Hello SecondActivity" ;
Intent intent = new Intent (当前Activity. this, 目标Activity.class ) ;
intent.putExtra( "传入名称", data) ;
startActivity(intent) ;

接受Activity代码:

Intent intent = getIntent();
String data = intent.getStringExtra( "传入名称" );
Intent:用于参数回传

先有传入:

intent.setClass(MainActivity. this, Register_Activity.class );
startActivityForResult(intent,1);
startActivityForResult(Intent intent,int RequestCode);//把intent要启动的目标Activity设置一个RequestCode值(当然RequestCode的值使大于等于0的一个值)。

在回传:

Intent intent = new Intent();
intent.putExtra("data1",name.getText().toString() );
intent.putExtra("data2",textP1);
setResult(RESULT_OK,intent);
finish();//结束当前Activity

在接收:重写方法 onActivityResult(intrequestCode, intresultCode,Intent data)
onActivityResult(int requestCode, int resultCode, Intent intent)
RequestCode的作用 :区别请求的activity,android将每个请求设定一个大于等于0的int值,这就是requestcode。
resultCode参数对应于子模块中setResut(int resultCode, Intent intent)函数中的resultCode值,用于区别不同的返回结果(如请求正常、请求异常等)。
由此,在onActivityResult函数中即可利用requestCode区别开不同的返回结果。
而onActivityResult中的resultCode参数对应于子模块中setResut(int resultCode, Intent intent)函数中的resultCode值,用于区别不同的返回结果(如请求正常、请求异常等)。

protected void onActivityResult(int requestCode, int resultCode , Intent data) {
    switch (requestCode) {
        case 1:
            if (resultCode == RESULT_OK) {
                data1 = data.getStringExtra( "data1");
                data2 = data.getStringExtra( "data2");
                name.setText( data1);
                edit_pwd.setText( data2);
                nameY = data1;
                edit_pwdyY = data2;
            }
            break;
        default:
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容