Intent,Bundle与intentFilter,pendingIntent

Intent:

Intent负责对应用中一次操作的动作,动作涉及的数据,附加数据进行描述。系统或者应用根据此Intent的描述,负责找到对应的组件,将Intent传递给调用的组件,并且完成组件的调用。

SDK中给出了Intent作用的表现形式为:
· 通过[Context.startActivity()] or[Activity.startActivityForResult()] 启动一个Activity;
· 通过 [Context.startService()] 启动一个服务,或者通过[Context.bindService()]和后台服务交互;
· 通过广播方法[Context.sendBroadcast()],[Context.sendOrderedBroadcast()],  [Context.sendStickyBroadcast()]发给broadcast receivers。
intent的属性设置(可以在构建intent时传入,当然也可以通过Intent类的方法来获取和设置):
setAction: 设置动作,表示要干什么。
setData:设置数据,表示要传递给目标组件的数据。它是一个URI格式的数据。
setType:表示要访问的数据类型,是一个MIME类型的数据。
addCategory:设置要访问的组件的类别,可以同时添加多个类别。 
component(组件):指定Intent的的目标组件的类名称。通常 Android会根据Intent 中包含的其它属性的信息,比如action、data/type、category进行查找,最终找到一个与之匹配的目标组件。但是,如果 component这个属性有指定的话,将直接使用它指定的组件,而不再执行上述查找过程。指定了这个属性以后,Intent的其它所有属性都是可选的。
extras(附加信息):是其它所有附加信息的集合,使用extras可以为组件提供扩展信息。
setAction:

SDK中定义了一些标准的动作:

     ACTION_MAIN:Android Application的入口,每个Android应用必须且只能包含一个此类型的Action声明。 
    ACTION_VIEW:系统根据不同的Data类型,通过已注册的对应Application显示数据。
    ACTION_EDIT:系统根据不同的Data类型,通过已注册的对应Application编辑示数据。 
    ACTION_DIAL:打开系统默认的拨号程序,如果Data中设置了电话号码,则自动在拨号程序中输入此号码。 
    ACTION_CALL:直接呼叫Data中所带的号码。 
    ACTION_ANSWER:接听来电。 
    ACTION_SEND:由用户指定发送方式进行数据发送操作。
    ACTION_SENDTO:系统根据不同的Data类型,通过已注册的对应Application进行数据发送操作。
    ACTION_BOOT_COMPLETED:Android系统在启动完毕后发出带有此Action的广播(Broadcast)。 
    ACTION_TIME_CHANGED:Android系统的时间发生改变后发出带有此Action的广播(Broadcast)。 
    ACTION_PACKAGE_ADDED:Android系统安装了新的Application之后发出带有此Action的广播(Broadcast)。 
    ACTION_PACKAGE_CHANGED:Android系统中已存在的Application发生改变之后(如应用更新操作)发出带有此Action的广播(Broadcast)。 
    ACTION_PACKAGE_REMOVED:卸载了Android系统已存在的Application之后发出带有此Action的广播(Broadcast)。 
setData与setType:

Android中采用指向数据的一个URI来表示。对于不同的动作,其URI数据的类型是不同的(一般Intent的数据类型能够根据数据本身进行判定,也可以设置type属性指定特定类型数据),如ACTION_EDIT指定Data为文件URI。

     data元素组成的URI模型:scheme://host:port/path

    tel://:号码数据格式,后跟电话号码。 
    mailto://:邮件数据格式,后跟邮件收件人地址。
    smsto://:短息数据格式,后跟短信接收号码。
    content://:内容数据格式,后跟需要读取的内容。 
    file://:文件数据格式,后跟文件路径。
    geo://:地理位置数据格式,后跟地理位置信息
addCategory:

被执行动作的附加信息,例如 LAUNCHER_CATEGORY 表示Intent 的接受者应该在Launcher中作为顶级应用出现;而ALTERNATIVE_CATEGORY表示当前的Intent是一系列的可选动作中的一个,这些动作可以在同一块数据上执行。

Category信息:

     CATEGORY_DEFAULT:Android系统中默认的执行方式,按照普通Activity的执行方式执行。 
    CATEGORY_HOME:设置该组件为Home Activity。
    CATEGORY_PREFERENCE:设置该组件为Preference。 
    CATEGORY_LAUNCHER:设置该组件为在当前应用程序启动器中优先级最高的Activity,通常为入口ACTION_MAIN配合使用。 
    CATEGORY_BROWSABLE:设置该组件可以使用浏览器启动。 
    CATEGORY_GADGET:设置该组件可以内嵌到另外的Activity中。
Intent的两种用法:

(1). 显式的Intent,即在构造Intent对象时就指定接收者,它一般用在知道目标组件名称的前提下,一般是在相同的应用程序内部实现的,如下:
Intent it = new Intent(Activity.Main.this, Activity2.class);
startActivity(it);

(2).隐式的Intent,即Intent的发送者在构造Intent对象时,并不知道也不关心接收者是谁,有利于降低发送者和接收者之间的耦合,它一般用在没有明确指出目标组件名称的前提下,一般是用于在不同应用程序之间,如下:
Intent it = new Intent();
it.setAction("com.google.test");
startActivity(it);
上面那个intent, 没有指明接收者, 只是给了一个action作为接收者的过滤条件。

隐式Intent解析机制

Intent解析机制主要是通过查找已注册在AndroidManifest.xml中的所有IntentFilter及其中定义的Intent,最终找到匹配的Intent。在这个解析过程中,Android是通过Intent的action、type、category这三个属性来进行判断的,判断方法如下:

· 如果Intent指明定了action,则目标组件的IntentFilter的action列表中就必须包含有这个action,否则不能匹配;

· 如果Intent没有提供type,系统将从data中得到数据类型。和action一样,目标组件的数据类型列表中必须包含Intent的数据类型,否则不能匹配。

· 如果Intent中的数据不是content: 类型的URI,而且Intent也没有明确指定它的type,将根据Intent中数据的scheme (比如 http: 或者[mailto]进行匹配。同上,Intent 的scheme必须出现在目标组件的scheme列表中。

· 如果Intent指定了一个或多个category,这些类别必须全部出现在组建的类别列表中。比如Intent中包含了两个类

每一个通过 startActivity() 方法发出的隐式 Intent 都至少有一个 category,就是 "android.intent.category.DEFAULT",所以只要是想接收一个隐式 Intent 的 Activity 都应该包括 "android.intent.category.DEFAULT" category,不然将导致 Intent 匹配失败.

向下一个Activity传递数据(使用Bundle和Intent.putExtras):

intent可以传递的数据类型:
基本数据类型 以及String String/CharSequence
传递一个Bundle
传递Serializable对象
Parcelable对象
Intent

向上一个Activity返回结果(使用setResult,针对
//在一个活动中用startActivityForResult方法启动下一个活动
        startActivityForResult(intent,REQUEST_CODE) ;
//REQUEST_CODE为请求码。该方法启动后会自动回调onActivityResult(int requestCode, int resultCode, Intent data) 

//在这个活动中,构造intent装载返回信息,用setResult来返回intent与处理码RESULT_OK
        Intent intent=getIntent();
        Bundle bundle2=new Bundle();
        bundle2.putString("name", "This is from ShowMsg!");
        intent.putExtras(bundle2);
        setResult(RESULT_OK, intent);

//在上一个活动重写的回调方法onActivityResult中根据requestCode与resultCode处理具体逻辑,取出数据
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode==REQUEST_CODE){
            if(resultCode==RESULT_CANCELED)
                  setTitle("cancle");
            else if (resultCode==RESULT_OK) {
                 String temp=null;
                 Bundle bundle=data.getExtras();
                 if(bundle!=null)   temp=bundle.getString("name");
                 setTitle(temp);
            }
        }
    }

——————————————————————————————————————————

Intent-Filter:

IntentFilter就是用于描述intent的各种属性, 比如action, category等。
在AndroidMainfest.xml 中对每一个Activity都做了说明—intent-filter,intent-filter声明了需要接收怎样的Intent,当发送的Intent和intent-filter中定义的相符合,就会启动相应的Activity

//一些属性设置的例子:





决定一个应用程序最先启动那个组件
决定应用程序是否显示在程序列表里(说白了就是是否在桌面上显示一个图标)
两个属性一般成对出现。
是程序图标显示在home键菜单中

如果一个应用中有两个组件intent-filter都添加了android.intent.action.MAIN和
android.intent.category.LAUNCHER这两个属性, 则这个应用将会显示两个图标, 写在前面的组件先运行。
——————————————————————————————————————————

Bundle:

Bundle类也实现了Parcelable接口,一般在android中我们是通过Bundle来封装数据并进行传送的。
Bundle类是一个final类,用于存储和管理key-value对的类。
Bundle的底层是由Hashmap实现的。
范例
(1)新建一个bundle类
Bundle mBundle = new Bundle();
(2)bundle类中加入数据(key -value的形式,另一个activity里面取数据的时候,就要用到key,找出对应的value)
mBundle.putString("Data", "data from TestBundle");
(3)新建一个intent对象,并将该bundle加入这个intent对象
这种方法使得原来在连续活动中略显繁琐的intent传递更加方便,在每个活动中均可传递同一对象并新添加。

     Intent intent = new Intent();     
     intent.setClass(TestBundle.this, Target.class);    
     Bundle mBundle = new Bundle();    
     mBundle.putString("Data", "data from TestBundle");//压入数据     
     intent.putExtras(mBundle);    
     startActivity(intent);  

——————————————————————————————————————————

pendingIntent:

要得到一个pendingIntent对象,使用静态方法 [getActivity(Context, int, Intent, int)],[getBroadcast(Context, int, Intent, int)],[getService(Context, int, Intent, int) 分别对应着Intent的3个行为,跳转到一个activity组件、打开一个广播组件和打开一个服务组件。
参数有4个,比较重要的事第三个和第一个,其次是第四个和第二个。可以看到,要得到这个对象,必须传入一个Intent作为参数,必须有context作为参数,第四个用于确定pendingIntent的行为,有四个确定字段可选。

4、PendingIntent执行的操作实质上是参数传进来的Intent的操作,使用 PendingIntent 的目的在于它所包含的Intent的操作的执行是需要满足某些条件的。
5、主要的使用的地方和例子:通知Notificatio的发送,短消息SmsManager的发送和警报器AlarmManager的执行等。
总而言之,PendingIntent就是一个可以在满足一定条件下执行的Intent,它相比于Intent的优势在于自己携带有Context对象,这样他就不必依赖于某个activity才可以存在。

Intent和PendingIntent的区别:【掌握,以备面试之需】

 Intent是立即使用的,而PendingIntent可以等到事件发生后触发,PendingIntent可以cancel;
 Intent在程序结束后即终止,而PendingIntent在程序结束后依然有效;
 PendingIntent自带Context,而Intent需要在某个Context内运行;
 Intent在原task中运行,PendingIntent在新的task中运行。

PendingIntent的几个常量:(getActivity(Context, int, Intent, int)方法中的第四个参数)

FLAG_CANCEL_CURRENT:如果当前系统中已经存在一个相同的PendingIntent对象,那么就将先将已有的PendingIntent取消,然后重新生成一个PendingIntent对象。

FLAG_NO_CREATE:如果当前系统中不存在相同的PendingIntent对象,系统将不会创建该PendingIntent对象而是直接返回null。

FLAG_ONE_SHOT:该 PendingIntent只作用一次。在该PendingIntent对象通过send()方法触发过后,PendingIntent将自动调用 cancel()进行销毁,那么如果你再调用send()方法的话,系统将会返回一个SendIntentException。

FLAG_UPDATE_CURRENT: 如果系统中有一个和你描述的PendingIntent对等的PendingInent,那么系统将使用该PendingIntent对象,但是会使用新 的Intent来更新之前PendingIntent中的Intent对象数据,例如更新Intent中的Extras。

——————————————————————————————————————————
来源:
【各种intent信息分类:】http://blog.csdn.net/weihan1314/article/details/7973511
【intent详解:】http://blog.csdn.net/cnnumen/article/details/8464786
【pendingIntent:】http://blog.csdn.net/yuzhiboyi/article/details/8484771

你可能感兴趣的:(Intent,Bundle与intentFilter,pendingIntent)