zoukankan      html  css  js  c++  java
  • (Android数据传递)Intent消息传递机制 “Intent”“数据传递”

    Intent类的继承关系:

     

    需要注意的是,该类实现了Parcelable(用于数据传递)和Cloneable接口.

    Intent是一种(系统级别的)消息传递机制,可以在应用程序内使用,也可以在应用程序间使用。

    使用Intent可以用来:

    1. 使用类名,显式启动一个特定的Service或Activity(显式);

    2. 启动Activity或Service来执行一个动作的Intent,通常需要使用特定的数据,或者特定的数据执行动作(隐式:请求对一条数据执行某个动作);

    3. 广播某个事件已经发生;

    Android通过广播Intent来公布系统事件,比如网络连接状态或者电池电量的改变。本地Android应用程序简单地注册监听特定的广播Intent并作出相应的响应的组件。因此,可以通过注册监听相同的Broadcast Receiver来替换许多本地应用程序。

    Intent支持Android设备上安装的任意应用程序组件之间的交互,不管它们是哪个应用程序的一部分都是如此。这就把设备从一个包含相互独立的组件集合的平台变成了一个互联的系统,进而可以基于内部的、系统的或者第三方应用程序的事件创建事件驱动的应用程序。

    使用Intent来传播动作(甚至在同一个应用程序内传播动作),而不是显式地加载类,这是一条基本的Android设计原则(模块化原则)。它鼓励组件之间的分离,允许无缝地替换应用程序元素。还提供了一个简单的用户扩展应用程序功能的模型的基础。

    当创建一个新的隐式的Intent时,需要指定一个要执行的动作,另外,也可以提供执行那个动作需要的数据的URI。还可以通过向Intent添加extra来向目标Activity发送额外的数据。Extra是一种向Intent附加基本类型值的机制。Extra作为一个Bundle对象存储在Intent中,可以使用getExtras方法检索。

    在自己的应用程序中利用第三方应用程序的Activity和Service是十分方便的,但是,无法保证用户设备上安装了特定的某个应用程序,或者设备上有能够处理你的请求的应用程序。因此,在调用startActivity之前,确定调用是否可以解析为一个Activity是一种很好的做法。

    Intent是一种异步消息机制

    解释:

    1. Intent是不同组件之间相互通讯的纽带,封装了不同组件之间通讯的条件;一个Intent对象表达一个目的或期望,叙述其所期望的服务或动作、与动作相关的数据等。Android系统则根据此对象之叙述,负责匹配并找到相匹配的组件,然后将Intent对象传递给目标组件;类似于“媒婆”的作用。

    2. Intent对象有三种用途:跳转活动、发送广播和开启(绑定)服务。

    3. Intent的数据结构,在一个Intent实例中,主要包含有:action、data(动作涉及的数据)、category、type、component、extra(附加数据)六个部分。

    4. Intent Resolution Android系统中的Intent解决方案有两种:显式和隐式。

    对于每种组件来说,激活的方法是不同的:

    1.通过传递一个Intent对象至 Context.startActivity()或Activity.startActivityForResult()以载入(或指定新工作给)一个activity。相应的activity可以通过调用 getIntent() 方法来查看激活它的intent。Android通过调用activity的onNewIntent()方法来传递给它继发的intent。

    一个activity经常启动了下一个。如果它期望它所启动的那个activity返回一个结果,它会以调用startActivityForResult()来取代startActivity()。比如说,如果它启动了另外一个activity以使用户挑选一张照片,它也许想知道哪张照片被选中了。结果将会被封装在一个Intent对象中,并传递给发出调用的activity的onActivityResult() 方法。

    2.通过传递一个Intent对象至Context.startService()将启动一个服务(或给予正在运行的服务以一个新的指令)。Android调用服务的onStart()方法并将Intent对象传递给它。

    与此类似,一个Intent可以被调用组件传递给 Context.bindService()以获取一个正在运行的目标服务的连接。这个服务会经由onBind() 方法的调用获取这个Intent对象(如果服务尚未启动,bindService()会先启动它)。比如说,一个activity可以连接至前述的音乐回放服务,并提供给用户一个可操作的(用户界面)以对回放进行控制。这个activity可以调用 bindService() 来建立连接,然后调用服务中定义的对象来影响回放。

    3.应用程序可以凭借将Intent对象传递给 Context.sendBroadcast() ,Context.sendOrderedBroadcast(), 以及Context.sendStickyBroadcast()和其它类似方法来产生一个广播。Android会调用所有对此广播有兴趣的广播接收器的 onReceive()方法将intent传递给它们。Broadcast Intent用于向监听器通知系统的应用程序或应用程序事件,从而可以扩展应用程序间的事件驱动的编程模型。

    综上所述,有以下三种情况:

    Intent的启动方式---两种解决方案

    1.显式方式。直接设置目标组件的ComponentName,用于一个应用内部的消息传递,比如启动另一个Activity或者一个services。

    2.隐式方式。ComponentName为空,用于调用其他应用中的组件。需要包含足够的信息,这样系统才能根据这些信息使用intent filter在所有的组件中过滤action、data或者category来匹配目标组件。

    Intent类中包含的内部类:Intent.FilterComparison和Intent.ShortcutIconResource。

    Intent数据结构

    1. componentName(组件名称),指定Intent的目标组件的类名称。组件名称是可选的,如果填写,Intent对象会发送给指定组件名称的组件,否则也可以通过其他Intent信息定位到适合的组件。组件名称是个ComponentName类型的对象。

    Intent intent = new Intent(); 
    // 构造的参数为当前Context和目标组件的类路径名 
    ComponentName cn = new ComponentName(HelloActivity.this, "com.byread.activity.OtherActivity"); 
    intent.setComponent(cn); 
    startActivity(intent);

    相当于常用方法:

    Intent intent = new Intent();
    intent.setClass(HelloActivity.this, OtherActivity.class);
    startActivity(intent);

    2. action(动作),指定Intent的执行动作,比如调用拨打电话组件。

    3. data(数据),起到表示数据和数据MIME类型的作用。不同的action是和不同的data类型配套的,通过设置data的Uri来获得。

    4. category(类别),被执行动作的附加信息。例如应用的启动Activity在intent-filter中设置category。

    5. extras(附加信息),为处理Intent组件提供附加的信息。可通过putXX()和getXX()方法存取信息;也可以通过创建Bundle对象,再通过putExtras()和getExtras()方法来存取。

    6. flags(标记),指示Android如何启动目标Activity,设置方法为调用Intent的setFlags方法。

    Android SDK中可以使用的Android原生动作,都是Intent类中的静态字符串常量。在创建隐式的Intent来启动应用程序内的Activity或者子Activity的时候,可以使用这些动作(ActivityIntent)。

    ACTION_ALL_APPS:打开一个列出所有已安装应用程序的Activity。

    ACTION_BUG_REPORT:显示一个可以报告bug的Activity。

    ACTION_ANSWER:打开一个处理来电的Activity,通常这个动作是由本地电话拨号程序进行处理的。

    ...

    对于第一种用途,即使用startActivity(Intent)时,可用的 Standard Activities Actions 有:

    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

    Intent实例中定义的Action字段信息,主要用于Intent的匹配,指向了Intent的走向。Android系统会根据Intent实例设置的Action进行信息匹配,以此执行相应的内容。(Android系统负责“配对”,找出与Intent相配的组件)

    (使用Intent来广播事件)除了这些Activity动作之外,Android还包含了很多广播动作,它们用来创建广播Intent以公布系统事件(使用sendBroadcast发送出去,Intent实例则是一封信)。

    对于第二种用途,使用registerReceiver(BroadcastReceiver, IntentFilter)或者使用<receiver>标签时,可用的 Standard Broadcast Actions 有:

    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

    可以对Intent的动作、数据和分类进行设置,从而使Broadcast Receiver能够精确地确定它们的需求。在这种方案中,Intent动作字符串可以用来标识要广播的事件,所以它应该是能够标识事件的唯一的字符串。习惯上,动作字符的使用与包名相同的构建方式。

    public static final String NEW_LIFEFORM_DETECTED="com.paad.action.NEW_LIFEFORM";

    标准的 Categories ,用于区分不同类型的Intent实例,使用addCategory(String)声明,Standard Categories 有以下几类:

    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

    此外,Intent的Extra字段附带信息,使用putExtra(String, Bundle)添加Extra字段信息,Standard Extra Data 有以下几类:

    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的Flag参数:

    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

    Intent类的构造方法

    构造函数:

    1、Intent() 空构造函数

    2、Intent(Intent o) 拷贝构造函数

    3、Intent(String action) 指定action类型的构造函数

    4、Intent(String action, Uri uri) 指定Action类型和Uri的构造函数,URI主要是结合程序之间的数据共享ContentProvider

    5、Intent(Context packageContext, Class<?> cls) 传入组件的构造函数,是最常使用的方式(显示指定跳转目的地)

    6、Intent(String action, Uri uri, Context packageContext, Class<?> cls) 前两种结合体

    其中所指定的action字段值,就是AndroidManifest.xml文件声明activity所用的<intent-filter>标签中的action值。

    使用Intent实例进行数据传递:

    Bundle bundle = new Bundle();
    bundle.putStringArray("NAMEARR", nameArr);
    Intent intent = new Intent(Main.this, CountList.class);
    intent.putExtras(bundle);
    startActivity(intent);

    其中nameArr则是字符串数组,使用Intent实例传递数据,借助了Bundle对象。

    Bundle bundle = this.getIntent().getExtras();
    String[] arrName = bundle.getStringArray("NAMEARR");

    接收数据时,使用与之对应的方法,实现Activity之间的数据传递。

    Android SDK 的开发者文档在讲述该类时,最先讲述的是其中的常量字段值,以及其含义。

    putExtra:将数据以key:value的形式放入一个Parcelable对象中,直接由Intent对象携带,适合少量数据。只是用来设定各种不同类型的附加数据。不被系统用来寻找匹配目标组件。

    setData:将数据以数据流的方式传输,Intent接收后再单独接收Data部分,适合数据量较大的数据传输,如文件或图片等。传入的是Uri,用于数据的过滤。setData可以被系统用来寻找匹配目标组件。

    // 增加Intent附加值 Action:0

    it.setAction(String.valueOf(0));

    it.setClass(IndexActivity.this, SptActivity.class);

    startActivity(it);

    有什么用途?

    public Intent setClassName (Context packageContext, String className) 启动本应用中的Activity或Service

    public Intent setClassName (String packageName, String className) 启动其他应用中的Activity或Service

    Sticky Intent的不同特点? https://my.oschina.net/ososchina/blog/347765 粘性Intent

    Pending Intent的不同特点?

    实例分析,创建新的Activity为联系人数据的ACTION_PICK动作提供服务。该界面将显示联系人数据库中的每一个联系人信息,并在关闭并且将其URI返回给调用它的Activity之前,用户可以选择其中的一个联系人。

  • 相关阅读:
    Java并发编程:如何创建线程?
    Java并发编程:volatile关键字解析
    Java并发编程:深入剖析ThreadLocal
    Java并发编程:同步容器
    Java ConcurrentModificationException异常原因和解决方法
    Java并发编程:并发容器之ConcurrentHashMap
    Java并发编程:并发容器之CopyOnWriteArrayList
    Java并发编程:Callable、Future和FutureTask
    rest-framework频率组件
    rest-framework的权限组件
  • 原文地址:https://www.cnblogs.com/CVstyle/p/6368880.html
Copyright © 2011-2022 走看看