安卓多用户管理之Userinfo

2024-01-09 15:20

本文主要是介绍安卓多用户管理之Userinfo,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 前言
  • Userinfo----用户信息
    • 1.1 属性
    • 1.2 构造器
    • 1.3 信息的判断及获取方法
        • 1.3.1 获取默认用户类型
        • 1.3.2 基础信息判断
    • 1.4 序列化部分
  • 总结


前言

UserManagerService内部类UserData中有一个Userinfo类型的info参数,在UserData中并未有所体现,但在后续的UserManagerService里会有对info参数的各种操作,需要看下Userinfo类的基本属性和方法


Userinfo----用户信息

源码有500行左右,复制在一块略显臃肿,对其分类解读。
源码结构大致如下:

public class UserInfo implements Parcelable {
...............
属性
...............
构造器
................
信息的判断及获取方法
................
序列化部分的方法
.................
}

1.1 属性

    /*** Primary user. Only one user can have this flag set. It identifies the first human user* on a device. This flag is not supported in headless system user mode.* 主要用户。只有一个用户可以设置此标志。它识别第一个人类用户* 在设备上。无头系统用户模式不支持此标志。*/@UnsupportedAppUsagepublic static final int FLAG_PRIMARY = 0x00000001;/*** User with administrative privileges. Such a user can create and* delete users.* 具有管理权限的用户。这样的用户可以创建* 删除用户。*/public static final int FLAG_ADMIN   = 0x00000002;/*** Indicates a guest user that may be transient.* @deprecated Use {@link UserManager#USER_TYPE_FULL_GUEST} instead.* 表示可能是临时的访客用户。* @不推荐使用{@link UserManager#USER_TYPE_FULL_GUEST}。*/@Deprecatedpublic static final int FLAG_GUEST   = 0x00000004;/*** Indicates the user has restrictions in privileges, in addition to those for normal users.* Exact meaning TBD. For instance, maybe they can't install apps or administer WiFi access pts.* @deprecated Use {@link UserManager#USER_TYPE_FULL_RESTRICTED} instead.* 表示除普通用户的权限外,用户还具有权限限制。* 确切含义待定。例如,他们可能无法安装应用程序或管理WiFi接入点。* @不推荐使用{@link UserManager#USER_TYPE_FULL_RESTRICTED}。*/@Deprecatedpublic static final int FLAG_RESTRICTED = 0x00000008;/*** Indicates that this user has gone through its first-time initialization.* 指示此用户已完成首次初始化。*/public static final int FLAG_INITIALIZED = 0x00000010;/*** Indicates that this user is a profile of another user, for example holding a users*corporate data.* @deprecated Use {@link UserManager#USER_TYPE_PROFILE_MANAGED} instead.* 指示此用户是另一个用户的配置文件,例如持有用户的公司数据。* @不推荐使用{@link UserManager#USER_TYPE_PROFILE_MANAGED}。*/@Deprecatedpublic static final int FLAG_MANAGED_PROFILE = 0x00000020;/*** Indicates that this user is disabled.** <p>Note: If an ephemeral user is disabled, it shouldn't be later re-enabled. Ephemeral users* are disabled as their removal is in progress to indicate that they shouldn't be re-entered.*指示此用户已被禁用。*<p>注意:如果临时用户被禁用,以后就不应该重新启用它。短暂用户在删除过程中被禁用,表示不应重新输入。*/public static final int FLAG_DISABLED = 0x00000040;public static final int FLAG_QUIET_MODE = 0x00000080;/*** Indicates that this user is ephemeral. I.e. the user will be removed after leaving* the foreground.* *指示此用户是临时用户。即用户离开前台后将被删除。*/public static final int FLAG_EPHEMERAL = 0x00000100;/*** User is for demo purposes only and can be removed at any time.* @deprecated Use {@link UserManager#USER_TYPE_FULL_DEMO} instead.* *用户仅用于演示目的,可以随时删除。*@不推荐使用{@link UserManager#USER_TYPE_FULL_DEMO}。*/@Deprecatedpublic static final int FLAG_DEMO = 0x00000200;/*** Indicates that this user is a non-profile human user.** <p>When creating a new (non-system) user, this flag will always be forced true unless the* user is a {@link #FLAG_PROFILE}. If user {@link UserHandle#USER_SYSTEM} is also a* human user, it must also be flagged as FULL.* /***指示此用户是非配置文件的人类用户。*<p>当创建新的(非系统)用户时,除非该用户标志了flag_PROFILE,否则此标志将始终强制为true。*如果用户标志了UserHandle#user_SYSTEM也是人类用户,则还必须将其标记为FULL。 */public static final int FLAG_FULL = 0x00000400;/*** Indicates that this user is {@link UserHandle#USER_SYSTEM}. Not applicable to created users.* *表示此用户是{@link UserHandle#user_SYSTEM}。不适用于创建的用户。*/public static final int FLAG_SYSTEM = 0x00000800;/*** Indicates that this user is a profile human user, such as a managed profile.* Mutually exclusive with {@link #FLAG_FULL}.**指示此用户是配置文件的人工用户,例如托管配置文件。*与{@link#FLAG_FULL}互斥。*/public static final int FLAG_PROFILE = 0x00001000;/*** @hide*/@IntDef(flag = true, prefix = "FLAG_", value = {FLAG_PRIMARY,FLAG_ADMIN,FLAG_GUEST,FLAG_RESTRICTED,FLAG_INITIALIZED,FLAG_MANAGED_PROFILE,FLAG_DISABLED,FLAG_QUIET_MODE,FLAG_EPHEMERAL,FLAG_DEMO,FLAG_FULL,FLAG_SYSTEM,FLAG_PROFILE})@Retention(RetentionPolicy.SOURCE)public @interface UserInfoFlag {}/***将"NO_PROFILE_GROUP_ID"设置为一个表示无效用户ID的常量。*/public static final int NO_PROFILE_GROUP_ID = UserHandle.USER_NULL;@UnsupportedAppUsagepublic @UserIdInt int id;@UnsupportedAppUsagepublic int serialNumber;@UnsupportedAppUsagepublic String name;@UnsupportedAppUsagepublic String iconPath;@UnsupportedAppUsagepublic @UserInfoFlag int flags;@UnsupportedAppUsagepublic long creationTime;@UnsupportedAppUsagepublic long lastLoggedInTime;public String lastLoggedInFingerprint;/*** Type of user, such as {@link UserManager#USER_TYPE_PROFILE_MANAGED}, corresponding to* {@link com.android.server.pm.UserTypeDetails#getName()}.*/public String userType;/*** If this user is a parent user, it would be its own user id.* If this user is a child user, it would be its parent user id.* Otherwise, it would be {@link #NO_PROFILE_GROUP_ID}.*/@UnsupportedAppUsagepublic int profileGroupId;public int restrictedProfileParentId;/*** Index for distinguishing different profiles with the same parent and user type for the* purpose of badging.* It is used for determining which badge color/label to use (if applicable) from* the options available for a particular user type.* 用于区分具有相同父级和用户类型的不同配置文件以进行标记的索引。* 它用于从特定用户类型的可用选项中确定使用哪种徽章颜色/标签(如果适用)。*/public int profileBadge;/** User is only partially created. */@UnsupportedAppUsagepublic boolean partial;/***代一个待移除的访客用户或者访客配置文件。这个变量的作用可能是用于跟踪需要移除的访客用户或者配置文件的信息,*以便在系统操作中进行相应的处理。*/@UnsupportedAppUsagepublic boolean guestToRemove;/*** This is used to optimize the creation of an user, i.e. OEMs might choose to pre-create a* number of users at the first boot, so the actual creation later is faster.** <p>A {@code preCreated} user is not a real user yet, so it should not show up on regular* user operations (other than user creation per se).** <p>Once the pre-created is used to create a "real" user later on, {@code preCreate} is set to* {@code false}.*这用于优化用户的创建,即原始设备制造商可能会选择在第一次启动时预先创建多个用户,因此以后的实际创建速度更快。*<p>{@code preCreated}用户还不是真正的用户,因此它不应该出现在常规用户操作中(而不是用户创建本身)。*<p>一旦预先创建的用于稍后创建“真正”用户,{@code preCreate}将设置为{@code false}。*/public boolean preCreated;/*** When {@code true}, it indicates this user was created by converting a {@link #preCreated}* user.** <p><b>NOTE: </b>only used for debugging purposes, it's not set when marshalled to a parcel.*当{@code true}时,表示该用户是通过转换{@link#preCreated}创建的用户。*<p><b>注意:</b>仅用于调试目的,当它被整理到一个包裹时没有设置。*/public boolean convertedFromPreCreated;
属性类型含义
FLAG_PRIMARYint主要用户标志
FLAG_ADMINint具有管理权限的用户标志
FLAG_GUESTint临时的访客用户标志
FLAG_RESTRICTEDint受限制的标志
FLAG_INITIALIZEDint完成首次初始化标志
FLAG_MANAGED_PROFILEint被管理用户标志
FLAG_DISABLEDint被禁用标志
FLAG_QUIET_MODEint安静模式标志
FLAG_EPHEMERALint临时用户标志
FLAG_DEMOintdemo标志,可以随时删除
FLAG_FULLint非配置文件的人类用户标志
FLAG_SYSTEMint系统用户标志
FLAG_PROFILEint配置文件的人类用户标志
NO_PROFILE_GROUP_IDint字面翻译没有配置文件组ID,值为无效用户ID的常量
idint用户id
serialNumberint序列号
nameString名字
iconPathString图标路径
flagsint标志
creationTimelong创造时间
lastLoggedInTimelong上次登录时间
lastLoggedInFingerprintString上次登录的指纹
userTypeString用户类型
profileGroupIdint配置文件组ID
restrictedProfileParentIdint受限制配置文件的父级ID
profileBadgeint配置文件徽章
partialboolean偏好
guestToRemoveboolean待移除的访客
preCreatedboolean提前创建
convertedFromPreCreatedboolean通过提前创建转变的

1.2 构造器

四个构造器如下:

      /*** Creates a UserInfo whose user type is determined automatically by the flags according to* {@link #getDefaultUserType}; can only be used for user types handled there.* 创建UserInfo,其用户类型由根据{@link#getDefaultUserType}的标志自动确定;只能用于在那里处理的用户类型*/@UnsupportedAppUsagepublic UserInfo(int id, String name, int flags) {this(id, name, null, flags);}/*** Creates a UserInfo whose user type is determined automatically by the flags according to* {@link #getDefaultUserType}; can only be used for user types handled there.* 创建UserInfo,其用户类型由根据{@link#getDefaultUserType}的标志自动确定;只能用于在那里处理的用户类型*/@UnsupportedAppUsagepublic UserInfo(int id, String name, String iconPath, int flags) {this(id, name, iconPath, flags, getDefaultUserType(flags));}public UserInfo(int id, String name, String iconPath, int flags, String userType) {this.id = id;this.name = name;this.flags = flags;this.userType = userType;this.iconPath = iconPath;this.profileGroupId = NO_PROFILE_GROUP_ID;this.restrictedProfileParentId = NO_PROFILE_GROUP_ID;}public UserInfo(UserInfo orig) {name = orig.name;iconPath = orig.iconPath;id = orig.id;flags = orig.flags;userType = orig.userType;serialNumber = orig.serialNumber;creationTime = orig.creationTime;lastLoggedInTime = orig.lastLoggedInTime;lastLoggedInFingerprint = orig.lastLoggedInFingerprint;partial = orig.partial;preCreated = orig.preCreated;convertedFromPreCreated = orig.convertedFromPreCreated;profileGroupId = orig.profileGroupId;restrictedProfileParentId = orig.restrictedProfileParentId;guestToRemove = orig.guestToRemove;profileBadge = orig.profileBadge;}

1.3 信息的判断及获取方法

1.3.1 获取默认用户类型
    /*** Get the user type (such as {@link UserManager#USER_TYPE_PROFILE_MANAGED}) that corresponds to* the given {@link UserInfoFlag}s.* <p>The userInfoFlag can contain GUEST, RESTRICTED, MANAGED_PROFILE, DEMO, or else be* interpreted as a regular "secondary" user. It cannot contain more than one of these.* It can contain other UserInfoFlag properties (like EPHEMERAL), which will be ignored here.** @throws IllegalArgumentException if userInfoFlag is more than one type of user or if it*                                  is a SYSTEM user.**获取对应于的用户类型(例如{@link UserManager#user_type_PROFILE_MANAGED})*给定的{@link UserInfoFlag}s。*<p>userInfoFlag可以包含GUEST、RESTRICTED、MANAGED_PROFILE、DEMO,或者被解释为常规的“次要”用户。其中不能包含多个。*它可以包含其他UserInfoFlag属性(如EPHEMERAL),此处将忽略这些属性。*如果userInfoFlag是多种类型的用户,或者如果是SYSTEM用户。* @hide*/public static @NonNull String getDefaultUserType(@UserInfoFlag int userInfoFlag) {if ((userInfoFlag & FLAG_SYSTEM) != 0) {throw new IllegalArgumentException("Cannot getDefaultUserType for flags "+ Integer.toHexString(userInfoFlag) + " because it corresponds to a "+ "SYSTEM user type.");}final int supportedFlagTypes =FLAG_GUEST | FLAG_RESTRICTED | FLAG_MANAGED_PROFILE | FLAG_DEMO;switch (userInfoFlag & supportedFlagTypes) {case 0 :                   return UserManager.USER_TYPE_FULL_SECONDARY;case FLAG_GUEST:           return UserManager.USER_TYPE_FULL_GUEST;case FLAG_RESTRICTED:      return UserManager.USER_TYPE_FULL_RESTRICTED;case FLAG_MANAGED_PROFILE: return UserManager.USER_TYPE_PROFILE_MANAGED;case FLAG_DEMO:            return UserManager.USER_TYPE_FULL_DEMO;default:throw new IllegalArgumentException("Cannot getDefaultUserType for flags "+ Integer.toHexString(userInfoFlag) + " because it doesn't correspond to a "+ "valid user type.");}}

首先将userInfoFlagFLAG_SYSTEM进行位与操作,如果结果不等于0就会抛出异常表示当前用户类型相当于系统用户。
FLAG_SYSTEM即0x00000800 是一个十六进制数,转换成二进制为 0000 0000 0000 0000 0000 1000 0000 0000。在这里,只有自己&自己情况下才会抛出异常。
然后定义了一个supportedFlagTypes变量,它包含了一系列支持的用户类型标志位,包含了FLAG_GUESTFLAG_RESTRICTEDFLAG_MANAGED_PROFILEFLAG_DEMO

如果是0,表示userInfoFlag不包含任何支持的用户类型标志位,因此返回UserManager.USER_TYPE_FULL_SECONDARY
如果按位与的结果匹配到了FLAG_GUESTFLAG_RESTRICTEDFLAG_MANAGED_PROFILE或者FLAG_DEMO,那么分别返回对应的用户类型。
最后,如果userInfoFlag不匹配任何已知的用户类型标志位,那么抛出一个IllegalArgumentException异常,说明userInfoFlag不对应任何有效的用户类型。

1.3.2 基础信息判断

该部分些许无聊,flags 位与标志再判断是否相等就不作更多说明。通过UserManagerAPI再判断相关状态暂不做更多说明…后续看情况再写一篇UserManager的文章,这部分真的太碎了…

    @UnsupportedAppUsagepublic boolean isPrimary() {return (flags & FLAG_PRIMARY) == FLAG_PRIMARY;}@UnsupportedAppUsagepublic boolean isAdmin() {return (flags & FLAG_ADMIN) == FLAG_ADMIN;}@UnsupportedAppUsagepublic boolean isGuest() {return UserManager.isUserTypeGuest(userType);}@UnsupportedAppUsagepublic boolean isRestricted() {return UserManager.isUserTypeRestricted(userType);}public boolean isProfile() {return (flags & FLAG_PROFILE) != 0;}@UnsupportedAppUsagepublic boolean isManagedProfile() {return UserManager.isUserTypeManagedProfile(userType);}@UnsupportedAppUsagepublic boolean isEnabled() {return (flags & FLAG_DISABLED) != FLAG_DISABLED;}public boolean isQuietModeEnabled() {return (flags & FLAG_QUIET_MODE) == FLAG_QUIET_MODE;}public boolean isEphemeral() {return (flags & FLAG_EPHEMERAL) == FLAG_EPHEMERAL;}public boolean isInitialized() {return (flags & FLAG_INITIALIZED) == FLAG_INITIALIZED;}public boolean isDemo() {return UserManager.isUserTypeDemo(userType);}public boolean isFull() {return (flags & FLAG_FULL) == FLAG_FULL;}/*** Returns true if the user is a split system user.* <p>If {@link UserManager#isSplitSystemUser split system user mode} is not enabled,* the method always returns false.**如果用户是拆分系统用户,则返回true。*<p>如果没有启用{@link UserManager#isSplitSystemUser拆分系统用户模式},*该方法总是返回false。*/public boolean isSystemOnly() {return isSystemOnly(id);}/*** Returns true if the given user is a split system user.* <p>If {@link UserManager#isSplitSystemUser split system user mode} is not enabled,* the method always returns false.*如果给定用户是拆分系统用户,则返回true。*<p>如果没有启用{@link UserManager#isSplitSystemUser拆分系统用户模式},*该方法总是返回false。*/public static boolean isSystemOnly(int userId) {return userId == UserHandle.USER_SYSTEM && UserManager.isSplitSystemUser();}/*** @return true if this user can be switched to.* @如果此用户可以切换到,则返回true。**/public boolean supportsSwitchTo() {if (isEphemeral() && !isEnabled()) {// Don't support switching to an ephemeral user with removal in progress.//不支持在删除过程中切换到临时用户。return false;}if (preCreated) {// Don't support switching to pre-created users until they become "real" users.//在用户成为“真实”用户之前,不支持切换到预先创建的用户。return false;}return !isProfile();}/*** @return true if this user can be switched to by end user through UI.* *@return true如果最终用户可以通过UI切换到此用户。*/public boolean supportsSwitchToByUser() {// Hide the system user when it does not represent a human user.// 当系统用户不代表人类用户时,隐藏系统用户。boolean hideSystemUser = UserManager.isHeadlessSystemUserMode();return (!hideSystemUser || id != UserHandle.USER_SYSTEM) && supportsSwitchTo();}// TODO(b/142482943): Make this logic more specific and customizable. (canHaveProfile(userType))//都产生todo了,可知该部分还不是完善,暂不做解读/* @hide */public boolean canHaveProfile() {if (isProfile() || isGuest() || isRestricted()) {return false;}if (UserManager.isSplitSystemUser() || UserManager.isHeadlessSystemUserMode()) {return id != UserHandle.USER_SYSTEM;} else {return id == UserHandle.USER_SYSTEM;}}

1.4 序列化部分

	//describeContents方法: 这个方法返回一个标志位,用于描述Parcelable对象特殊对象的对象类型。//通常情况下,如果对象中存在文件描述符,那么返回1,否则返回0。在这个例子中,返回0表示不包含文件描述符。@Overridepublic int describeContents() {return 0;}/***writeToParcel方法: 这个方法用于将对象的数据写入Parcel对象中,以便进行传输。在这个例子中,通过调用Parcel对象的*不同写入方法,将id、name、iconPath、flags、userType、serialNumber、creationTime、lastLoggedInTime、*lastLoggedInFingerprint、partial、preCreated、profileGroupId、guestToRemove、restrictedProfileParentId*和profileBadge等变量的值写入Parcel对象中。*/@Overridepublic void writeToParcel(Parcel dest, int parcelableFlags) {dest.writeInt(id);dest.writeString8(name);dest.writeString8(iconPath);dest.writeInt(flags);dest.writeString8(userType);dest.writeInt(serialNumber);dest.writeLong(creationTime);dest.writeLong(lastLoggedInTime);dest.writeString8(lastLoggedInFingerprint);dest.writeBoolean(partial);dest.writeBoolean(preCreated);dest.writeInt(profileGroupId);dest.writeBoolean(guestToRemove);dest.writeInt(restrictedProfileParentId);dest.writeInt(profileBadge);}@UnsupportedAppUsagepublic static final @android.annotation.NonNull Parcelable.Creator<UserInfo> CREATOR= new Parcelable.Creator<UserInfo>() {//createFromParcel方法: 这个方法接收一个Parcel对象作为参数,用于从Parcel中反序列化出一个UserInfo对象。//在这个例子中,这个方法返回一个新的UserInfo对象,通过读取Parcel对象中的数据来初始化UserInfo对象的各个字段。public UserInfo createFromParcel(Parcel source) {return new UserInfo(source);}//newArray方法: 这个方法接收一个整型参数size,用于创建一个指定大小的UserInfo数组。在这个例子中,//这个方法返回一个UserInfo类型的数组,其大小由传入的size参数决定。public UserInfo[] newArray(int size) {return new UserInfo[size];}};//这个构造函数通常用于在反序列化过程中创建UserInfo对象private UserInfo(Parcel source) {id = source.readInt();name = source.readString8();iconPath = source.readString8();flags = source.readInt();userType = source.readString8();serialNumber = source.readInt();creationTime = source.readLong();lastLoggedInTime = source.readLong();lastLoggedInFingerprint = source.readString8();partial = source.readBoolean();preCreated = source.readBoolean();profileGroupId = source.readInt();guestToRemove = source.readBoolean();restrictedProfileParentId = source.readInt();profileBadge = source.readInt();}

总结

Userinfo主要内容还是看它的属性,方法主要是通过属性标志位的与或操作判断结果,以及常见的序列化传输方法。

这篇关于安卓多用户管理之Userinfo的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/587561

相关文章

Python中bisect_left 函数实现高效插入与有序列表管理

《Python中bisect_left函数实现高效插入与有序列表管理》Python的bisect_left函数通过二分查找高效定位有序列表插入位置,与bisect_right的区别在于处理重复元素时... 目录一、bisect_left 基本介绍1.1 函数定义1.2 核心功能二、bisect_left 与

Spring中管理bean对象的方式(专业级说明)

《Spring中管理bean对象的方式(专业级说明)》在Spring框架中,Bean的管理是核心功能,主要通过IoC(控制反转)容器实现,下面给大家介绍Spring中管理bean对象的方式,感兴趣的朋... 目录1.Bean的声明与注册1.1 基于XML配置1.2 基于注解(主流方式)1.3 基于Java

基于Python+PyQt5打造一个跨平台Emoji表情管理神器

《基于Python+PyQt5打造一个跨平台Emoji表情管理神器》在当今数字化社交时代,Emoji已成为全球通用的视觉语言,本文主要为大家详细介绍了如何使用Python和PyQt5开发一个功能全面的... 目录概述功能特性1. 全量Emoji集合2. 智能搜索系统3. 高效交互设计4. 现代化UI展示效果

Mysql中的用户管理实践

《Mysql中的用户管理实践》:本文主要介绍Mysql中的用户管理实践,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录13. 用户管理13.1 用户 13.1.1 用户信息 13.1.2 创建用户 13.1.3 删除用户 13.1.4 修改用户

linux服务之NIS账户管理服务方式

《linux服务之NIS账户管理服务方式》:本文主要介绍linux服务之NIS账户管理服务方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、所需要的软件二、服务器配置1、安装 NIS 服务2、设定 NIS 的域名 (NIS domain name)3、修改主

Python+PyQt5开发一个Windows电脑启动项管理神器

《Python+PyQt5开发一个Windows电脑启动项管理神器》:本文主要介绍如何使用PyQt5开发一款颜值与功能并存的Windows启动项管理工具,不仅能查看/删除现有启动项,还能智能添加新... 目录开篇:为什么我们需要启动项管理工具功能全景图核心技术解析1. Windows注册表操作2. 启动文件

gradle第三方Jar包依赖统一管理方式

《gradle第三方Jar包依赖统一管理方式》:本文主要介绍gradle第三方Jar包依赖统一管理方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录背景实现1.顶层模块build.gradle添加依赖管理插件2.顶层模块build.gradle添加所有管理依赖包

基于Python打造一个智能单词管理神器

《基于Python打造一个智能单词管理神器》这篇文章主要为大家详细介绍了如何使用Python打造一个智能单词管理神器,从查询到导出的一站式解决,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 项目概述:为什么需要这个工具2. 环境搭建与快速入门2.1 环境要求2.2 首次运行配置3. 核心功能使用指

HTML5中的Microdata与历史记录管理详解

《HTML5中的Microdata与历史记录管理详解》Microdata作为HTML5新增的一个特性,它允许开发者在HTML文档中添加更多的语义信息,以便于搜索引擎和浏览器更好地理解页面内容,本文将探... 目录html5中的Mijscrodata与历史记录管理背景简介html5中的Microdata使用M

Spring 基于XML配置 bean管理 Bean-IOC的方法

《Spring基于XML配置bean管理Bean-IOC的方法》:本文主要介绍Spring基于XML配置bean管理Bean-IOC的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一... 目录一. spring学习的核心内容二. 基于 XML 配置 bean1. 通过类型来获取 bean2. 通过