当前位置:   article > 正文

Android中AndroidManifests.xml 之meta-data_androidmanifest meta-data

androidmanifest meta-data

一、概念

meta-data( 元数据; 文件元数据)就像其名一样,主要用来定义一些组件相关的配置值。
按照官方定义,metadata是一组供父组件使用的名值对(name-value pair),因此相应的meta-data元素应该定义在相应的组件中。即如果想在activity中使用metadata,那么meta-data必须定义在AndroidManifest.xml的activity声明中。

  • AndroidManifests.xml下的meta-data则是对外界开放的,是向系统注册的信息,系统及外界是可以通过PackageInfo相关API获取到meta-data的信息。
  • 与strings的区别在于它们的作用域,strings只能在应用本地被读取,很像公有与私有的区别。

meta-data标签的使用在配置文件中配置参数,然后在Context中通过bundle取出参数

1.1 语法

 <meta-data android:name="string"
               android:resource="resource specification"
               android:value="string" />

标签<meta-data>是提供组件额外的数据用的,它本身就是一个键值对,可以自定义名称和值。它可以包含在以下组件当中:

    <activity>
    <activity-alias>
    <application>
    <provider>
    <receiver>
    <service> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

1.2 说明

一个以键-值对表示的数据项,以供父组件作为附加数据使用,数据类型任意。 一个组件元素可以包含任意数量的 子元素。 这些子元素的值存放在一个 Bundle 对象中,组件可以通过 PackageItemInfo.metaData 字段访问这些数据。

普通类型的值可以通过 value 属性来给定。 而资源 ID 的值则必须用 resource 属性来指定。 比如,以下代码把“com.android.settings.xxx”的名称赋值为 @string/kangaroo 资源中存储的数据:

   <meta-data android:name="com.android.settings.xxx" 
   android:value="@string/kangaroo" /> 
  • 1
  • 2

另一方面, 通过 Resource 属性将把“com.android.settings.xxx”赋值为资源的 ID ,而不是资源中存储的数据:

<meta-data android:name="com.android.settings.xxx" 
 android:resource="@string/kangaroo" /> 
  • 1
  • 2

强烈建议不要使用多个独立的 部分定义数据。 如果有比较复杂的数据需要和某个组件关联,请把它们作为资源存储,并用 resource 属性将资源 ID 告知组件。

1.3 属性

  • android:name
    数据项的唯一名称。 为了确保名称的唯一性,可使用 Java 风格的命名规则 — 如“com.example.project.activity.fred”。
  • android:resource
    对某个资源的引用。赋值为资源 ID 。 通过 Bundle.getInt() 方法可以从 meta-data Bundle 中读取该资源 ID。
  • android:value
    赋给数据项的值。 下表列出了可赋予的数据类型、组件用 Bundle 对象获取该类值的方法:
类型Bundle 方法
字符串值,双反斜杠(\)作为转义字符 — 比如“\n”、“\uxxxxx”表示 Unicode 字符getString()
整数值,比如“100”getInt()
布尔型值,“true”或“false”getBoolean()
颜色值,格式为“#rgb”、“#argb”、“#rrggbb”或“#aarrggbb”getInt()
浮点型值,比如“1.23”getFloat()

二、使用

所有的名值对被包装成Bundle供组件使用,因此使用方式同Bundle。metadata普通值由value属性给出,资源ID由resource属性给出。

2.1 用法

比如我们定义资源

<string name="x_key">resource key</string>
//R
public static final int ic_launcher=0x7f020000;
  • 1
  • 2
  • 3

定义metadata

<meta-data
    android:name="com.xesam.key_1"
    android:value="x_key" />
<meta-data
    android:name="com.xesam.key_2"
    android:value="@string/x_key" />
<meta-data
    android:name="com.xesam.img"
    android:resource="@drawable/ic_launcher" />
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

那么有:

metadata.getString("com.xesam.key_1") ==> "x_key"
metadata.getString("com.xesam.key_2") ==> "resource key"
metadata.getInt("com.xesam.img")      ==> 0x7f020000
  • 1
  • 2
  • 3

由于resource指向资源ID,因此用metadata可以定义一些稍微复杂的值。
比如要定义一副图片,则可以用这个,然后在代码中用getInt()取出图片的ID:

int imageId = meta.getInt("com.xesam.img");
((ImageView) findViewById(R.id.img)).setImageResource(imageId);
  • 1
  • 2

2.2 使用问题

<meta-data
    android:name="com.xesam.key_1"
    android:value="000" />
  • 1
  • 2
  • 3

类似这样的值如果使用bundle.getString()的话是不起作用的,因为Bundle中使用的是形如:

return (String) o;
  • 1

代码获取一个StringValue值的,但是在将metadata包装成bundle的时候,"000"被解析成整数0,
因此bundle.getString(“com.xesam.key_1”)返回的是(String)0,显然,java是不允许这样的,因此最后得到的是null。 话说android为什么不是用String.valueOf()或者obj.toString()呢?

为了避免这种情况:
1,可以在形如000的字符串前面放个\0空字符,强迫android按照字符串解析000。
2,在资源文件中指定需要的值,然后在metadata的value中引用此值。

三、 具体应用场景解析

3.1 在activity中

xml中配置如下

<!-- Activity -->  
        <activity android:name=".MyActivity" 
        		  android:label="@string/app_name">  
            <intent-filter>  
                <action android:name="android.intent.action.MAIN" />  
                <category android:name="android.intent.category.LAUNCHER" />  
            </intent-filter>  
            <meta-data android:name="activity_name" 
                       android:value="activity_value" />  
        </activity>  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

java代码如下

   //在Activity应用<meta-data>元素。
    ActivityInfo actInfo = mContext.getPackageManager().getActivityInfo(  
                        getComponentName(), PackageManager.GET_META_DATA);  
                String msg = actInfo.metaData.getString("activity_name");  
  • 1
  • 2
  • 3
  • 4

3.2 在service中

xml中配置如下

<!-- 服务 -->  
        <service android:name=".MyService">  
            <meta-data android:name="service_name" 
                       android:value="service_value" />  
        </service>  
  • 1
  • 2
  • 3
  • 4
  • 5

java代码如下

 //在service应用<meta-data>元素。
ComponentName cn = new ComponentName(this, MyService.class);  
        try {  
            ServiceInfo serInfo = this.getPackageManager().getServiceInfo(cn,  
                    PackageManager.GET_META_DATA);  
        } catch (NameNotFoundException e) {  
            e.printStackTrace();  
        }  
        String msg = serInfo.metaData.getString("service_name");  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

3.3 在application中

xml中配置如下

<!-- app -->  
        <meta-data android:name="application_name" android:value="application_value" />  
  • 1
  • 2

java代码如下

 //在application应用<meta-data>元素。
ApplicationInfo appInfo = this.getPackageManager().getApplicationInfo(  
                    getPackageName(), PackageManager.GET_META_DATA);  
            String msg = appInfo.metaData.getString("application_name");  
  • 1
  • 2
  • 3
  • 4

3.4 在receiver中,也就是广播接收者(拨打电话的时候会看到toast消息)

xml中配置如下

 <receiver android:name=".MyReceiver">  
                <meta-data android:name="receiver_name" android:value="receiver_value" />  
                <intent-filter>  
                    <action android:name="android.intent.action.PHONE_STATE" />  
                </intent-filter>  
            </receiver>  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

java代码如下

    //在receiver应用<meta-data>元素。
if (TextUtils.equals("android.intent.action.PHONE_STATE", intent  
                .getAction())) {  
            ComponentName cn = new ComponentName(context, MyReceiver.class);  
            try {  
                ActivityInfo info = context.getPackageManager().getReceiverInfo(cn,  
                        PackageManager.GET_META_DATA);  
            } catch (NameNotFoundException e) {  
                e.printStackTrace();  
            }  
            String msg = info.metaData.getString("receiver_name");  
            // 打电话测试即可  
            Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();  
        }  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
 Logcat输出信息 
11:11:46.733: V/MainActivity(571): application meta data value:application_meta_data_value
11:11:46.733: V/MainActivity(571): activity meta data value:activity_meta_data_value
11:11:46.763: V/MainActivity(571): service meta data value:service_meta_data_value
11:11:46.783: V/MainActivity(571): receiver meta data value:receiver_meta_data_value
  • 1
  • 2
  • 3
  • 4
  • 5
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/652632
推荐阅读
相关标签
  

闽ICP备14008679号