美文网首页
关于Intent你知多少?

关于Intent你知多少?

作者: PrivateGO | 来源:发表于2017-06-02 10:32 被阅读26次

    什么是Intent?

    Intent是一个消息传递对象,可以使用它来启动其它应用组件。Intent使组件之间通信更加便利,主要用于以下三点:

    启动Activity:

    可以将intent作为参数调用Context.startActivity(intent)方法启动一个Activity。此时该Intent对象描述了将要启动的目标Activity名称及相关数据信息。同时还可以调用startActivityForResult()方法回传信息。

    启动Service:

    Service是一个常用于在后台执行操作的组件。可以使用Context.startService(intent)在后台启动一个Service。同样的使用bindService(intent)也需要用到Intent参数。

    发送Broadcast:

    Broadcast是一种可以被应用程序截获的广播机制。可以通过调用sendBroadcast(intent),sendOrderedBroadcast(intent),sendStickyBroadcast(intent)方法发送一条广播。

    可以看到,四大组件中的Activity, Service, Broadcast的启动或发送都需要用到Intent。
    Intent的类型

    显示Intent:指按名称(完全限定类名)指定要启动的组件。通常在启动自己编写的组件时需要使用显示Intent。

    隐式Intent:指不指定特定的组件,而是声明要执行的常规操作,从而允许其他应用中的组件来处理它。

    创建隐式 Intent 时,Android 系统通过将 Intent 的内容与在设备上其他应用的清单文件中声明的 Intent 过滤器进行比较,从而找到要启动的相应组件。 如果 Intent 与 Intent 过滤器匹配,则系统将启动该组件,并向其传递 Intent 对象。 如果多个 Intent 过滤器兼容,则系统会显示一个对话框,支持用户选取要使用的应用。
    Intent 过滤器是应用清单文件中的一个表达式,它指定该组件要接收的 Intent 类型。 例如,通过为 Activity 声明 Intent 过滤器,您可以使其他应用能够直接使用某一特定类型的 Intent 启动 Activity。同样,如果您没有为 Activity 声明任何 Intent 过滤器,则 Activity 只能通过显式 Intent 启动。
    注意:为了确保应用的安全性,启动Service时,请始终使用显示Intent,且不要为服务声明Intent过滤器。使用隐式Intent启动服务存在安全隐患,因为您无法确定哪些服务将响应Intent,且用户无法看到哪些服务已经启动。从Android5.0(API 21)开始,如果使用隐式Intent调用bingService(),系统会引发异常。

    Intent包含哪些信息?

    Intent的源码中定义了如下关键属性:

    private String mAction;
    private Uri mData;
    private String mType;
    private String mPackage;
    private ComponentName mComponent;
    private int mFlags;
    private ArraySet<String> mCategories;
    private Bundle mExtras;
    private Rect mSourceBounds;
    private Intent mSelector;
    private ClipData mClipData;
    private int mContentUserHint = UserHandle.USER_CURRENT;

    Action 操作
    指定要执行的通用操作的字符串。对于广播 Intent,这是指已发生且正在报告的操作。操作在很大程度上决定了其余 Intent 的构成,特别是数据和 extra 中包含的内容。一些用于启动Activity的常见操作:
    ACTION_VIEW:如果有一些某项 Activity 可向用户显示的信息(例如,要使用图库应用查看的照片;或者要使用地图应用查看的地址),可使用 Intent 将此操作与 startActivity() 结合使用。
    ACTION_SEND:也称为“共享”Intent。如果有一些用户可通过其他应用(例如,电子邮件应用或社交共享应用)共享的数据,则应使用Intent将此操作与 startActivity() 结合使用。

    Data 数据
    引用待操作数据和/或该数据 MIME 类型的 URI(Uri 对象)。提供的数据类型通常由 Intent 的操作决定。例如,如果操作是 ACTION_EDIT,则数据应包含待编辑文档的 URI。 创建 Intent 时,除了指定 URI 以外,指定数据类型(其 MIME 类型)也很重要。

    ComponentName 组件名称
    构建显示Intent的必要信息。如果没有ComponentName,则表示Intent是隐式的。

    Type 类别
    一个包含应处理 Intent 组件类型的附加信息的字符串。 您可以将任意数量的类别描述放入一个 Intent 中,但大多数 Intent 均不需要类别。 以下是一些常见类别:
    CATEGORY_BROWSABLE:目标Activity允许本身通过网络浏览器启动,以显示链接引用的数据,如图像或电子邮件。
    CATEGORY_LAUNCHER:该Activity是任务的初始Activity,在系统的应用启动器中列出。

    Extra
    用于携带完成请求操作所需的附加信息的键值对。正如某些操作使用特定类型的数据 URI 一样,有些操作也使用特定的 extra。
    可以使用各种 putExtra() 方法添加 extra 数据,每种方法均接受两个参数:键名和值。您还可以创建一个包含所有 extra 数据的 Bundle 对象,然后使用 putExtras() 将Bundle 插入 Intent 中。

    Intent可以传递Bitmap吗?

    查看Intent的源码中,有一个putExtra(String name, byte[] value)方法:

    public Intent putExtra(String name, byte[] value) {
    if (mExtras == null) {
    mExtras = new Bundle();
    }
    mExtras.putByteArray(name, value);
    return this;
    }
    可以将Bitmap转化成byte[]进行传递。经测试intent是可以传递bitmap的。

    但是,在测试过程中发现,传递的一张500多k的图片是出错了

    JavaBinder: !!! FAILED BINDER TRANSACTION !!!
    显然,是传输的图片过大,超出了Binder传输的限制了。因为启动另一个Activity的过程中,需要与AMS进程进行Binder通信。(关于Binder通信机制下次详细介绍)

    Binder通信过程中,会发生一次内存拷贝,显示,传输的数据越小效率就越高。因此,不建议使用Intent传递比较大的数据。

    Intent和PendingIntent的区别

    Intent 是及时启动,intent 随所在的activity 消失而消失。

    PendingIntent这个类用于处理即将发生的事情。比如在通知Notification中用于跳转页面,但不是马上跳转。

    Intent一般是用作Activity、Sercvice、BroadcastReceiver之间传递数据,而Pendingintent,一般用在 Notification上,可以理解为延迟执行的intent,PendingIntent是对Intent一个包装。


    本文原创发布于公众号《Android面试专栏》,欢迎搜索关注!也欢迎大家留言投稿!

    相关文章

      网友评论

          本文标题:关于Intent你知多少?

          本文链接:https://www.haomeiwen.com/subject/kxoyfxtx.html