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

一、概念

meta-data:元数据、文件元数据。主要用来定义一些组件相关的配置值。

metadata是一组供父组件使用的名值对(name-value pair),一个组件元素可以包含任意数量的meta-data子元素。这些子元素的值存放在一个 Bundle 对象中,组件可以通过 PackageItemInfo.metaData 字段访问这些数据。AndroidManifests.xml下的meta-data则是对外界开放的,是向系统注册的信息,系统及外界是可以通过PackageInfo相关API获取到meta-data的信息。

1.1 语法

xml 复制代码
<meta-data android:name="string"
               android:resource="resource specification"
               android:value="string" />

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

1.2 属性

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

二、 使用说明

普通类型的值:通过 value 属性来给定。

资源 ID 的值:必须用 resource 属性来指定。

定义资源

xml 复制代码
<string name="x_key">resource key</string>
//R
public static final int ic_launcher=0x7f020000;

定义metadata

xml 复制代码
<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" />
    <!--保存的是对应的Id,而不是保存的Id对应的资源-->

那么有:

java 复制代码
metadata.getString("com.xesam.key_1") ==> "x_key"
metadata.getString("com.xesam.key_2") ==> "resource key"
metadata.getInt("com.xesam.img")      ==> 0x7f020000

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

2.1 使用问题

xml 复制代码
<meta-data
    android:name="com.xesam.key_1"
    android:value="000" />

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

java 复制代码
return (String) o;在这里插入代码片

代码获取一个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中引用此值。

三、 具体应用场景解析

展示了meta-data元素在activity、application 、service和receiver元素中的读取方法

之前提到Meta-data中的内容会被收集到一个Bundle对象中,并且提供给组件的PackageItemInfo.metaData属性字段。可以通过调用PackageItemInfo 对象的metaData属性获得。而中ActivityInfo、ServiceInfo、 ApplicationInfo都是直接或间接继承自PackageItemInfo。

获取相应的PackageItemInfo值的时候要注意:

1 AppliacationInfo需要传递包名,

2 其他的传递ComponentName,所以需要构造一个 ComponentName对象,而不是使用getComponentName()方法。

getComponentName()方法返回的是当前组件。可能获取Meta-data值得地方不在对应的组件中。

AndroidMainfest.xml

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.MyApplication"
        tools:targetApi="31">
        <!--Application的MetaData的配置-->
        <meta-data android:name="applicationMetadataKey" android:value="applicationMetadataValue"/>
        <activity android:name=".MainActivity" android:exported="true">
        	<!--注意:targetSdkVersion大于等于SDK 31(也就是Android 12)时,如果Activity配置了Intent-filter,必须也同时配置exported属性,否则编译失败。-->
            <!--Activity的MetaData的配置-->
            <meta-data android:name="activityMetadataKey" android:value="activityMetadataValue"/>
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver android:name=".MainReceiver">
            <!--Receiver的MetaData的配置-->
            <meta-data android:name="receiverMetadataKey" android:value="receiverMetadataValue"/>
        </receiver>
        <service android:name=".MainService">
            <!--Service的MetaData的配置-->
            <meta-data android:name="serviceMetadataKey" android:value="serviceMetadataValue"/>
        </service>
    </application>

</manifest>

MainActivity.java

java 复制代码
package com.example.myapplication;

import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private TextView result;
    private Context mContext;
    private ComponentName componentName;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContext = this;
        componentName = this.getComponentName();
        result = (TextView) findViewById(R.id.result);
        findViewById(R.id.app).setOnClickListener(this);
        findViewById(R.id.act).setOnClickListener(this);
        findViewById(R.id.rec).setOnClickListener(this);
        findViewById(R.id.ser).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if(v.getId() == R.id.app){
            try {
                ApplicationInfo appInfo = mContext.getPackageManager().getApplicationInfo(mContext.getPackageName(), PackageManager.GET_META_DATA);
                String appMV = appInfo.metaData.getString("applicationMetadataKey");
                result.setText(appMV);
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
            }
        }
        else if(v.getId() == R.id.act){
            try {
                ActivityInfo actInfo = mContext.getPackageManager().getActivityInfo(componentName, PackageManager.GET_META_DATA);
                String actMV = actInfo.metaData.getString("activityMetadataKey");
                result.setText(actMV);
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
            }
        }
        else if(v.getId() ==  R.id.rec){
            ComponentName recCn = new ComponentName(mContext, MainReceiver.class);
             try {
                 ActivityInfo recInfo = mContext.getPackageManager().getReceiverInfo(recCn, PackageManager.GET_META_DATA);
                 String recMV = recInfo.metaData.getString("receiverMetadataKey");result.setText(recMV);
             } catch (PackageManager.NameNotFoundException e) {
                 e.printStackTrace();
             }
        } else if (v.getId() ==  R.id.ser) {
            ComponentName serCn = new ComponentName(mContext, MainService.class);
            try {
                ServiceInfo serInfo = mContext.getPackageManager().getServiceInfo(serCn, PackageManager.GET_META_DATA);
                String serMV = serInfo.metaData.getString("serviceMetadataKey");
                result.setText(serMV);
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
}

转载链接

https://blog.csdn.net/xuangelouzhu/article/details/113661113

相关推荐
姑苏风2 小时前
《Kotlin实战》-附录
android·开发语言·kotlin
数据猎手小k5 小时前
AndroidLab:一个系统化的Android代理框架,包含操作环境和可复现的基准测试,支持大型语言模型和多模态模型。
android·人工智能·机器学习·语言模型
你的小106 小时前
JavaWeb项目-----博客系统
android
风和先行6 小时前
adb 命令查看设备存储占用情况
android·adb
AaVictory.7 小时前
Android 开发 Java中 list实现 按照时间格式 yyyy-MM-dd HH:mm 顺序
android·java·list
似霰8 小时前
安卓智能指针sp、wp、RefBase浅析
android·c++·binder
大风起兮云飞扬丶8 小时前
Android——网络请求
android
干一行,爱一行8 小时前
android camera data -> surface 显示
android
断墨先生8 小时前
uniapp—android原生插件开发(3Android真机调试)
android·uni-app
无极程序员10 小时前
PHP常量
android·ide·android studio