• 详解intent和intentfilter


    1.Intent对象简介

      Intent中文意思指"意图",按照Android的设计理念,Android使用Intent来封装程序的"调用意图",不管启动Activity、Service、BroadcastReceiver,Android都使用统一的Intent对象来封装这一"启动意图"。此外,Intent也是应用程序组件之间通信的重要媒介。

      Android应用程序包含三种重要组件:Activity、Service、BroadcastReceiver,应用程序采用一致的方式启动它们,都是依靠Intent来进行启动的,Intent中封装了程序要启动的意图。

      下面是Intent启动不同组件的部分方法:

      Activity组件:startActivity(Intent intent);startActivityForResult(Intent intent,int requestCode);

      Service组件:startService(Intent intent);bindService(Intent intent,ServiceConnection conn,int flags);

      BroadcastReceiver组件:sendBroadcast(Intent intent);sendOrderedBroadcast(Intent intent,String receiverPermission);

    2.intent的属性及intentfilter的配置

      Intent的属性大致包含:Component,Action,Category,Data,Type,Extra,Flag这7种属性,其中Component用于明确指定需要启动的组件,而Extra则用于"携带"需要交换的数据。

      2.1 Component属性

        Intent的Component属性需要接收一个ComponentName对象,ComponentName构造器包含如下对象:

        1>ComponentName(String pkg,String cls),

        2>ComponentName(Context pkg,String cls),

        3>ComponentName(Context pkg,Class<?> cls)

        创建pkg包下cls类对应的组件,上面的三个构造器本质上就是一个。查看第二个和第三个构造器源代码:

    1   public ComponentName(Context pkg, String cls) {
    2         if (cls == null) throw new NullPointerException("class name is null");
    3         mPackage = pkg.getPackageName();
    4         mClass = cls;
    5     }

        

    1   public ComponentName(Context pkg, Class<?> cls) {
    2         mPackage = pkg.getPackageName();
    3         mClass = cls.getName();
    4     }

        mpackage和mClass分别表示包名和类名,最终都是为了获取包名和类名。注意这块mClass是类的完整名称(包名+类名)

        这说明创建一个ComponentName需要指定包名和类名就可以唯一确定一个组件类。这样,应用程序可以根据给定的组件类启动特定的组件。这里顺便说下Intent包含的三个方法:

        1>setClass(Context context,Class<?> cls)

        2>setClassName(Context context,String className)

        3>setClassName(String packageName,String className)

        这三个方法其实本质上还是调用上面的三个方法,查看第一个源代码:

    1   public Intent setClass(Context packageContext, Class<?> cls) {
    2         mComponent = new ComponentName(packageContext, cls);
    3         return this;
    4     }

        后面两个也是调用不同的ComponentName构造方法,这里就不啰嗦了,自己可以看下源码。

        TIP:

          Android应用的Context代表访问该应用环境信息的接口,Android应用的包名作为应用的唯一标识,因此Android应用的Context对象和包名有一一对应的关系。

        指定Component属性的Intent已经明确它要启动的哪个组件,因此这种Intent也被称为显示"意图".

      2.2 action、category属性与intent-filter配置

        Intent的action、category属性都是普通的字符串,其中action表示Intent需要完成的一个抽象"动作",而category则为action添加额外的类别信息,通常action和category一块使用。

        需要指出的是,一个Intent中只能包含一个action属性,但可以包含多个category属性。当程序创建Intent时,该Intent默认启动常量值为andorid.intent.category.DEFAULT的组件。

        下面写一个Demo,从一个Activity(隐式)启动另一个Activity,布局文件很简单,activity_main添加一个按钮,activity_other显示一行字,这里就不写出了:

        MainActivity类:

    复制代码
     1 package com.example.administrator.intentandintentfilterdemo;
     2 
     3 import android.content.Intent;
     4 import android.os.Bundle;
     5 import android.support.v7.app.ActionBarActivity;
     6 import android.view.View;
     7 
     8 public class MainActivity extends ActionBarActivity {
     9     private static final String FLAG_OTHER = "com.example.administrator.intentandintentfilterdemo.OTHERACTIVITY";
    10     @Override
    11     protected void onCreate(Bundle savedInstanceState) {
    12         super.onCreate(savedInstanceState);
    13         setContentView(R.layout.activity_main);
    14     }
    15 
    16     public void start(View view){
    17         Intent intent = new Intent();
    18         intent.setAction(FLAG_OTHER);
    19         intent.addCategory("android.intent.category.DEFAULT2");
    20         startActivity(intent);
    21     }
    22 
    23 
    24 }
    复制代码

        OtherActivity类:

    复制代码
     1 package com.example.administrator.intentandintentfilterdemo;
     2 
     3 import android.app.Activity;
     4 import android.os.Bundle;
     5 
     6 /**
     7  * Created by Administrator on 2015/3/22.
     8  */
     9 public class OtherActivity extends Activity{
    10     @Override
    11     protected void onCreate(Bundle savedInstanceState) {
    12         super.onCreate(savedInstanceState);
    13         setContentView(R.layout.activity_other);
    14     }
    15 }
    复制代码

        AndroidManifest.xml:

    复制代码
     1 <?xml version="1.0" encoding="utf-8"?>
     2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     3     package="com.example.administrator.intentandintentfilterdemo" >
     4 
     5     <application
     6         android:allowBackup="true"
     7         android:icon="@drawable/ic_launcher"
     8         android:label="@string/app_name"
     9         android:theme="@style/AppTheme" >
    10         <activity
    11             android:name=".MainActivity"
    12             android:label="@string/app_name" >
    13             <intent-filter>
    14                 <action android:name="android.intent.action.MAIN" />
    15 
    16                 <category android:name="android.intent.category.LAUNCHER" />
    17             </intent-filter>
    18         </activity>
    19 
    20         <activity
    21             android:name=".OtherActivity"
    22             android:label="@string/app_name" >
    23             <intent-filter>
    24                 <action android:name="com.example.administrator.intentandintentfilterdemo.OTHERACTIVITY"/>
    25                 <action android:name="com.example.administrator.intentandintentfilterdemo.TEMP"/>
    26                 <category android:name="android.intent.category.DEFAULT2"/>
    27                 <category android:name="android.intent.category.DEFAULT"/>
    28             </intent-filter>
    29         </activity>
    30     </application>
    31 
    32 </manifest>
    复制代码

        如果我们不在intent-filter中配置默认category属性,那么就会报异常。从中可以看出只要配置文件中intent-filter包含action、category就可以启动目标组件。切记,在intent-filter中要配置默认的category。

      2.3 data、type属性与intent-filter配置

        Data属性通常用于向action提供操作的数据。一个Data属性接收一个Uri对象,Uri通常通过如下字符串来表示:

        content://com.android.linzi:80/student/1

        Uri总满足如下格式:

        scheme://host:port/path

        上面content是scheme部分,com.android.linzi是host部分,80是prot部分,/student/1是path部分

        Type属性用于指定该Data所指定的MIME类型,这种类型可以是任何自定义的类型,只要符合abc/xyz格式的字符串即可。

        由于Data属性和Type属性关系比较微妙,这两个属性可以相互覆盖,所以希望既有Data属性又有Type属性时应该调用Intent的setDataAndType()方法。

        对上面代码稍作修改

        MainActivity类:

       

    复制代码
    1   public void start(View view){
    2         Intent intent = new Intent();
    3         intent.setAction(FLAG_OTHER);
    4         intent.addCategory("android.intent.category.DEFAULT2");
    5 //        intent.setData(Uri.parse("content://com.example.linzi:80/hanfeng/1"));
    6 //        intent.setType("image/jpg");
    7         intent.setDataAndType(Uri.parse("content://com.example.linzi:80/hanfeng/1"),"image/jpg");
    8         startActivity(intent);
    9     }
    复制代码

        如果将第7行换成5、6行就会报异常,Data和Type会相互覆盖

        AndroidManifest.xml:

        

    复制代码
     1 <activity
     2             android:name=".OtherActivity"
     3             android:label="@string/app_name" >
     4             <intent-filter>
     5                 <action android:name="com.example.administrator.intentandintentfilterdemo.OTHERACTIVITY"/>
     6                 <action android:name="com.example.administrator.intentandintentfilterdemo.TEMP"/>
     7                 <category android:name="android.intent.category.DEFAULT2"/>
     8                 <category android:name="android.intent.category.DEFAULT"/>
     9                 <data
    10                     android:scheme="content"
    11                     android:host="com.example.linzi"
    12                     android:path="/hanfeng/1"
    13                     android:port="80"
    14                     android:mimeType="image/jpg"/>
    15             </intent-filter>
    16         </activity>
    复制代码

      2.4 Extra属性 

        Intent的Extra属性通常用于在多个Activity之间进行数据交换,Extra属性应该是一个Bundle对象,它可以用来存储多组key-value值。

        可以通过putExtra()方法存放数据,putExtra()方法本质上也是通过Bundle来存储数据的,下面是其源码。(这里不做多的介绍,具体请参考前面写的关于Activity的博文)

    复制代码
    1 public Intent putExtra(String name, boolean value) {
    2         if (mExtras == null) {
    3             mExtras = new Bundle();
    4         }
    5         mExtras.putBoolean(name, value);
    6         return this;
    7     }
    复制代码

      2.5 Flag属性

        Intent的Flag属性用于为该Intent添加额外的控制旗标,Intent可调用addFlags()方法为其添加控制旗标

        Android为Intent提供了大量的Flag,每个Flag都有特定的功能,具体请参考Android API文档。

    3.总结:

      在启动Android Activity、Service、BroadcastReceiver等组件时,总需要借助Intent来实现(显示和隐式),Android Intent封装了应用程序的启动意图,但这种意图并未与其它任何组件藕合,这样可以很好的为增强程序的可扩展性和可维护性。应当熟悉component、action、category、data、type各属性的功能和用法。

  • 相关阅读:
    elastic search-php 多关键词查询实践(名称,日期,省份)
    记一次thinkphp 配置主从域名网站单点登录,退出
    thinkphp6 解决登录session跨域
    php富文本图片传递 通用css更改
    ELASTIC-PHP + IK分词器 + THINKPHP6 初次使用 (关键词查询)
    think-queue 加 redis实现批量导入excel
    百度api根据ip获取省市区
    php使用GD库将图片圆角 解决背景变黑问题 以及 图片丢失问题
    在树莓派上实现截图
    Arduino入门实践(五)--1、关于lcd的成像原理
  • 原文地址:https://www.cnblogs.com/Alex80/p/11382120.html
Copyright © 2020-2023  润新知