当前位置: 首页 > news >正文

景县网站建设/网站推广软件费用是多少

景县网站建设,网站推广软件费用是多少,做网站网页需要什么软件,网站建设的目的分析源码链接 https://android.googlesource.com/platform/frameworks/base//633dc9b/services/java/com/android/server/firewall/IntentFirewall.java 源码如下: package com.android.server.firewall; import android.content.Intent; import android.content.Inte…

源码链接

https://android.googlesource.com/platform/frameworks/base/+/633dc9b/services/java/com/android/server/firewall/IntentFirewall.java
源码如下:

package com.android.server.firewall;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.os.ServiceManager;
import android.util.Slog;
import android.util.Xml;
import com.android.internal.util.XmlUtils;
import com.android.server.IntentResolver;
import com.android.server.pm.PackageManagerService;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class IntentFirewall {private static final String TAG = "IntentFirewall";// e.g. /data/system/ifw/ifw.xml or /data/secure/system/ifw/ifw.xmlprivate static final File RULES_FILE =new File(Environment.getSystemSecureDirectory(), "ifw/ifw.xml");private static final String TAG_RULES = "rules";private static final String TAG_ACTIVITY = "activity";private static final String TAG_SERVICE = "service";private static final String TAG_BROADCAST = "broadcast";private static final HashMap<String, FilterFactory> factoryMap;private final AMSInterface mAms;private final IntentResolver<FirewallIntentFilter, Rule> mActivityResolver =new FirewallIntentResolver();private final IntentResolver<FirewallIntentFilter, Rule> mServiceResolver =new FirewallIntentResolver();private final IntentResolver<FirewallIntentFilter, Rule> mBroadcastResolver =new FirewallIntentResolver();static {FilterFactory[] factories = new FilterFactory[] {AndFilter.FACTORY,OrFilter.FACTORY,NotFilter.FACTORY,StringFilter.ACTION,StringFilter.COMPONENT,StringFilter.COMPONENT_NAME,StringFilter.COMPONENT_PACKAGE,StringFilter.DATA,StringFilter.HOST,StringFilter.MIME_TYPE,StringFilter.PATH,StringFilter.SENDER_PACKAGE,StringFilter.SSP,CategoryFilter.FACTORY,SenderFilter.FACTORY,SenderPermissionFilter.FACTORY,PortFilter.FACTORY};// load factor ~= .75factoryMap = new HashMap<String, FilterFactory>(factories.length * 4 / 3);for (int i=0; i<factories.length; i++) {FilterFactory factory = factories[i];factoryMap.put(factory.getTagName(), factory);}}public IntentFirewall(AMSInterface ams) {mAms = ams;readRules(getRulesFile());}public boolean checkStartActivity(Intent intent, ApplicationInfo callerApp,String callerPackage, int callerUid, int callerPid, String resolvedType,ActivityInfo resolvedActivity) {List<Rule> matchingRules = mActivityResolver.queryIntent(intent, resolvedType, false, 0);boolean log = false;boolean block = false;for (int i=0; i< matchingRules.size(); i++) {Rule rule = matchingRules.get(i);if (rule.matches(this, intent, callerApp, callerPackage, callerUid, callerPid,resolvedType, resolvedActivity.applicationInfo)) {block |= rule.getBlock();log |= rule.getLog();// if we've already determined that we should both block and log, there's no need// to continue trying rulesif (block && log) {break;}}}if (log) {// TODO: log info about intent to event log}return !block;}public static File getRulesFile() {return RULES_FILE;}private void readRules(File rulesFile) {FileInputStream fis;try {fis = new FileInputStream(rulesFile);} catch (FileNotFoundException ex) {// Nope, no rules. Nothing else to do!return;}try {XmlPullParser parser = Xml.newPullParser();parser.setInput(fis, null);XmlUtils.beginDocument(parser, TAG_RULES);int outerDepth = parser.getDepth();while (XmlUtils.nextElementWithin(parser, outerDepth)) {IntentResolver<FirewallIntentFilter, Rule> resolver = null;String tagName = parser.getName();if (tagName.equals(TAG_ACTIVITY)) {resolver = mActivityResolver;} else if (tagName.equals(TAG_SERVICE)) {resolver = mServiceResolver;} else if (tagName.equals(TAG_BROADCAST)) {resolver = mBroadcastResolver;}if (resolver != null) {Rule rule = new Rule();try {rule.readFromXml(parser);} catch (XmlPullParserException ex) {Slog.e(TAG, "Error reading intent firewall rule", ex);continue;} catch (IOException ex) {Slog.e(TAG, "Error reading intent firewall rule", ex);continue;}for (int i=0; i<rule.getIntentFilterCount(); i++) {resolver.addFilter(rule.getIntentFilter(i));}}}} catch (XmlPullParserException ex) {Slog.e(TAG, "Error reading intent firewall rules", ex);} catch (IOException ex) {Slog.e(TAG, "Error reading intent firewall rules", ex);} finally {try {fis.close();} catch (IOException ex) {Slog.e(TAG, "Error while closing " + rulesFile, ex);}}}static Filter parseFilter(XmlPullParser parser) throws IOException, XmlPullParserException {String elementName = parser.getName();FilterFactory factory = factoryMap.get(elementName);if (factory == null) {throw new XmlPullParserException("Unknown element in filter list: " + elementName);}return factory.newFilter(parser);}private static class Rule extends AndFilter {private static final String TAG_INTENT_FILTER = "intent-filter";private static final String ATTR_BLOCK = "block";private static final String ATTR_LOG = "log";private final ArrayList<FirewallIntentFilter> mIntentFilters =new ArrayList<FirewallIntentFilter>(1);private boolean block;private boolean log;@Overridepublic Rule readFromXml(XmlPullParser parser) throws IOException, XmlPullParserException {block = Boolean.parseBoolean(parser.getAttributeValue(null, ATTR_BLOCK));log = Boolean.parseBoolean(parser.getAttributeValue(null, ATTR_LOG));super.readFromXml(parser);return this;}@Overrideprotected void readChild(XmlPullParser parser) throws IOException, XmlPullParserException {if (parser.getName().equals(TAG_INTENT_FILTER)) {FirewallIntentFilter intentFilter = new FirewallIntentFilter(this);intentFilter.readFromXml(parser);mIntentFilters.add(intentFilter);} else {super.readChild(parser);}}public int getIntentFilterCount() {return mIntentFilters.size();}public FirewallIntentFilter getIntentFilter(int index) {return mIntentFilters.get(index);}public boolean getBlock() {return block;}public boolean getLog() {return log;}}private static class FirewallIntentFilter extends IntentFilter {private final Rule rule;public FirewallIntentFilter(Rule rule) {this.rule = rule;}}private static class FirewallIntentResolverextends IntentResolver<FirewallIntentFilter, Rule> {@Overrideprotected boolean allowFilterResult(FirewallIntentFilter filter, List<Rule> dest) {return !dest.contains(filter.rule);}@Overrideprotected boolean isPackageForFilter(String packageName, FirewallIntentFilter filter) {return true;}@Overrideprotected FirewallIntentFilter[] newArray(int size) {return new FirewallIntentFilter[size];}@Overrideprotected Rule newResult(FirewallIntentFilter filter, int match, int userId) {return filter.rule;}@Overrideprotected void sortResults(List<Rule> results) {// there's no need to sort the resultsreturn;}}/*** This interface contains the methods we need from ActivityManagerService. This allows AMS to* export these methods to us without making them public, and also makes it easier to test this* component.*/public interface AMSInterface {int checkComponentPermission(String permission, int pid, int uid,int owningUid, boolean exported);}/*** Checks if the caller has access to a component** @param permission If present, the caller must have this permission* @param pid The pid of the caller* @param uid The uid of the caller* @param owningUid The uid of the application that owns the component* @param exported Whether the component is exported* @return True if the caller can access the described component*/boolean checkComponentPermission(String permission, int pid, int uid, int owningUid,boolean exported) {return mAms.checkComponentPermission(permission, pid, uid, owningUid, exported) ==PackageManager.PERMISSION_GRANTED;}boolean signaturesMatch(int uid1, int uid2) {PackageManagerService pm = (PackageManagerService)ServiceManager.getService("package");return pm.checkUidSignatures(uid1, uid2) == PackageManager.SIGNATURE_MATCH;}
}

组件IntentFirewall的作用

IntentFirewall是Android框架中的一个组件,它可以根据XML文件中定义的规则来控制Intent的发送和接收。Intent是Android中用于组件间通信和启动的一种消息对象,它可以携带动作、数据、类别等信息。IntentFirewall可以根据Intent的属性和调用者的信息,决定是否允许或拒绝Intent的传递,从而增强系统的安全性和灵活性。
主要功能主要有以下几条:
(1)过滤任何类型的Intent,包括Activity,Service,Broadcast和ContentProvider。
(2)动态更新过滤规则,无需重启系统。
(3)支持多种过滤条件,包括动作、数据、类别、组件、权限、用户、进程等。
(4)支持多种过滤动作,包括阻止、记录、修改和转发Intent。

代码逻辑如下:

根据提供的Android IntentFirewall源代码,概括了其主要逻辑如下:

  1. 定义相关常量和变量,包括规则文件路径、解析器等

  2. 构造函数中初始化解析器,并读取规则文件

  3. checkStartActivity()方法检查启动Activity的Intent是否被阻止

  4. readRules()方法读取并解析规则文件

  5. parseFilter()解析过滤器标签

  6. Rule类封装单条规则信息

  7. FirewallIntentFilter类扩展IntentFilter表示规则Intent过滤器

  8. FirewallIntentResolver类自定义的解析器实现

  9. 定义AMSInterface接口与AMS服务交互

  10. checkComponentPermission()根据权限检查组件访问

  11. signaturesMatch()检查两个UID签名是否匹配

综上,该类主要实现了一个基于规则的Android Intent防火墙,可以通过配置来过滤恶意的组件启动请求,保护应用安全。

详细解读具体代码逻辑

private static final String TAG = "IntentFirewall";

这行代码定义了一个私有的静态的最终的字符串常量,名为TAG,值为"IntentFirewall",用于作为日志的标签。

private static final File RULES_FILE =new File(Environment.getSystemSecureDirectory(), "ifw/ifw.xml");

这行代码定义了一个私有的静态的最终的文件常量,名为RULES_FILE,值为一个File对象,用于表示规则文件的位置,它调用了Environment类的getSystemSecureDirectory方法,获取系统的安全目录,然后在该目录下创建一个名为"ifw/ifw.xml"的文件。

    private static final String TAG_RULES = "rules";private static final String TAG_ACTIVITY = "activity";private static final String TAG_SERVICE = "service";private static final String TAG_BROADCAST = "broadcast";

这块代码定义了四个私有的静态的最终的字符串常量,分别名为TAG_RULES,TAG_ACTIVITY,TAG_SERVICE,TAG_BROADCAST,值分别为为"rules",“activity”,“service”,“broadcast”,用于分别表示XML文件中的根元素的标签、活动类型的过滤规则的标签、服务类型的过滤规则的标签、广播类型的过滤规则的标签。这段代码是IntentFirewall类的一部分,用于定义一些常量和成员变量,它们分别用于表示日志的标签,规则文件的位置,XML文件中的元素的标签,过滤器工厂的映射,ActivityManagerService的接口,以及不同类型的过滤规则的解析器。

private static final HashMap<String, FilterFactory> factoryMap;private final AMSInterface mAms;private final IntentResolver<FirewallIntentFilter, Rule> mActivityResolver =new FirewallIntentResolver();private final IntentResolver<FirewallIntentFilter, Rule> mServiceResolver =new FirewallIntentResolver();private final IntentResolver<FirewallIntentFilter, Rule> mBroadcastResolver =new FirewallIntentResolver();
  • private static final HashMap<String, FilterFactory> factoryMap; 这行代码定义了一个私有的静态的最终的哈希映射常量,名为factoryMap,类型为HashMap<String, FilterFactory>,用于存储过滤器工厂的对象,键为过滤器的名称,值为过滤器工厂的实例。
  • private final AMSInterface mAms; 这行代码定义了一个私有的最终的接口变量,名为mAms,类型为AMSInterface,用于表示ActivityManagerService的接口,用于管理和调度系统中的四大组件。
  • private final IntentResolver<FirewallIntentFilter, Rule> mActivityResolver = new FirewallIntentResolver(); 这行代码定义了一个私有的最终的IntentResolver变量,名为mActivityResolver,类型为IntentResolver<FirewallIntentFilter, Rule>,值为一个FirewallIntentResolver对象,用于存储和查询活动类型的过滤规则。
  • private final IntentResolver<FirewallIntentFilter, Rule> mServiceResolver = new FirewallIntentResolver(); 这行代码定义了一个私有的最终的IntentResolver变量,名为mServiceResolver,类型为IntentResolver<FirewallIntentFilter, Rule>,值为一个FirewallIntentResolver对象,用于存储和查询服务类型的过滤规则。
  • private final IntentResolver<FirewallIntentFilter, Rule> mBroadcastResolver = new FirewallIntentResolver(); 这行代码定义了一个私有的最终的IntentResolver变量,名为mBroadcastResolver,类型为IntentResolver<FirewallIntentFilter, Rule>,值为一个FirewallIntentResolver对象,用于存储和查询广播类型的过滤规则。

这代码是IntentFirewall类的一部分,用于定义一些成员变量,它们分别用于表示过滤器工厂的映射,ActivityManagerService的接口,以及不同类型的过滤规则的解析器。

static {FilterFactory[] factories = new FilterFactory[] {AndFilter.FACTORY,OrFilter.FACTORY,NotFilter.FACTORY,StringFilter.ACTION,StringFilter.COMPONENT,StringFilter.COMPONENT_NAME,StringFilter.COMPONENT_PACKAGE,StringFilter.DATA,StringFilter.HOST,StringFilter.MIME_TYPE,StringFilter.PATH,StringFilter.SENDER_PACKAGE,StringFilter.SSP,CategoryFilter.FACTORY,SenderFilter.FACTORY,SenderPermissionFilter.FACTORY,PortFilter.FACTORY};
  • static { 这行代码表示开始一个静态代码块,用于在类加载时执行一些初始化操作,只执行一次。
  • FilterFactory[] factories = new FilterFactory[] { 这行代码定义了一个FilterFactory类型的数组,名为factories,用于存储所有可用的过滤器工厂的对象,过滤器工厂是用于创建和管理过滤器的类,过滤器是用于定义过滤条件的接口。
  • AndFilter.FACTORY, 这行代码表示将AndFilter类的FACTORY常量添加到factories数组中,这是一个AndFilterFactory类型的对象,用于创建和管理AndFilter类型的过滤器,AndFilter是用于实现逻辑与操作的过滤器,它可以包含多个子过滤器,只有当所有子过滤器都匹配时,才返回true。
  • OrFilter.FACTORY, 这行代码表示将OrFilter类的FACTORY常量添加到factories数组中,这是一个OrFilterFactory类型的对象,用于创建和管理OrFilter类型的过滤器,OrFilter是用于实现逻辑或操作的过滤器,它可以包含多个子过滤器,只要有一个子过滤器匹配,就返回true。
  • NotFilter.FACTORY, 这行代码表示将NotFilter类的FACTORY常量添加到factories数组中,这是一个NotFilterFactory类型的对象,用于创建和管理NotFilter类型的过滤器,NotFilter是用于实现逻辑非操作的过滤器,它可以包含一个子过滤器,返回子过滤器的相反结果。
  • StringFilter.ACTION, 这行代码表示将StringFilter类的ACTION常量添加到factories数组中,这是一个StringFilter类型的对象,用于创建和管理StringFilter类型的过滤器,StringFilter是用于匹配字符串属性的过滤器,它可以指定一个或多个字符串值,以及一个匹配模式,比如完全匹配,前缀匹配,后缀匹配,正则匹配等。ACTION常量表示匹配Intent的动作属性,比如android.intent.action.VIEW等。
  • StringFilter.COMPONENT, 这行代码表示将StringFilter类的COMPONENT常量添加到factories数组中,这是一个StringFilter类型的对象,用于匹配Intent的组件属性,比如com.example.app.MainActivity等。
  • StringFilter.COMPONENT_NAME, 这行代码表示将StringFilter类的COMPONENT_NAME常量添加到factories数组中,这是一个StringFilter类型的对象,用于匹配Intent的组件的名称属性,比如MainActivity等。
  • StringFilter.COMPONENT_PACKAGE, 这行代码表示将StringFilter类的COMPONENT_PACKAGE常量添加到factories数组中,这是一个StringFilter类型的对象,用于匹配Intent的组件的包名属性,比如com.example.app等。
  • StringFilter.DATA, 这行代码表示将StringFilter类的DATA常量添加到factories数组中,这是一个StringFilter类型的对象,用于匹配Intent的数据属性,比如http://www.example.com等。
  • StringFilter.HOST, 这行代码表示将StringFilter类的HOST常量添加到factories数组中,这是一个StringFilter类型的对象,用于匹配Intent的数据的主机属性,比如www.example.com等。
  • StringFilter.MIME_TYPE, 这行代码表示将StringFilter类的MIME_TYPE常量添加到factories数组中,这是一个StringFilter类型的对象,用于匹配Intent的数据的MIME类型属性,比如image/jpeg等。
  • StringFilter.PATH, 这行代码表示将StringFilter类的PATH常量添加到factories数组中,这是一个StringFilter类型的对象,用于匹配Intent的数据的路径属性,比如/index.html等。
  • StringFilter.SENDER_PACKAGE, 这行代码表示将StringFilter类的SENDER_PACKAGE常量添加到factories数组中,这是一个StringFilter类型的对象,用于匹配Intent的发送者的包名属性,比如com.example.sender等。
  • StringFilter.SSP, 这行代码表示将StringFilter类的SSP常量添加到factories数组中,这是一个StringFilter类型的对象,用于匹配Intent的数据的方案特定部分(Scheme Specific Part)属性,比如//www.example.com/index.html等。
  • CategoryFilter.FACTORY, 这行代码表示将CategoryFilter类的FACTORY常量添加到factories数组中,这是一个CategoryFilterFactory类型的对象,用于创建和管理CategoryFilter类型的过滤器,CategoryFilter是用于匹配Intent的类别属性的过滤器,它可以指定一个或多个类别值,比如android.intent.category.BROWSABLE等。
  • SenderFilter.FACTORY, 这行代码表示将SenderFilter类的FACTORY常量添加到factories数组中,这是一个SenderFilterFactory类型的对象,用于创建和管理SenderFilter类型的过滤器,SenderFilter是用于匹配Intent的发送者的过滤器,它可以指定一个或多个用户ID,进程ID,应用信息等。
  • SenderPermissionFilter.FACTORY, 这行代码表示将SenderPermissionFilter类的FACTORY常量添加到factories数组中,这是一个SenderPermissionFilterFactory类型的对象,用于创建和管理SenderPermissionFilter类型的过滤器,SenderPermissionFilter是用于匹配Intent的发送者的权限的过滤器,它可以指定一个或多个权限名称,以及是否需要强制执行等。
  • PortFilter.FACTORY 这行代码表示将PortFilter类的FACTORY常量添加到factories数组中,这是一个PortFilterFactory类型的对象,用于创建和管理PortFilter类型的过滤器,PortFilter是用于匹配Intent的数据的端口属性的过滤器,它可以指定一个或多个端口范围,比如80-8080等。
  • }; 这行代码表示结束数组的初始化。
factoryMap = new HashMap<String, FilterFactory>(factories.length * 4 / 3);for (int i=0; i<factories.length; i++) {FilterFactory factory = factories[i];factoryMap.put(factory.getTagName(), factory);}
  • factoryMap = new HashMap<String, FilterFactory>(factories.length * 4 / 3); 这行代码创建了一个HashMap对象,指定键和值的类型为String和FilterFactory,分别表示过滤器的名称和实例,然后将其赋值给factoryMap常量,用于存储过滤器工厂的映射。这里使用了一个参数的构造方法,指定HashMap的初始容量为factories数组的长度乘以4除以3,这样做的目的是为了减少HashMap的扩容次数,提高性能。
  • for (int i=0; i<factories.length; i++) { 这行代码开始一个for循环,用于遍历factories数组中的每个元素,每个元素都是一个FilterFactory对象,用于创建和管理过滤器。
  • FilterFactory factory = factories[i]; 这行代码定义了一个FilterFactory类型的变量,名为factory,然后将factories数组中的第i个元素赋值给它,表示当前的过滤器工厂对象。
  • factoryMap.put(factory.getTagName(), factory); 这行代码调用factoryMap对象的put方法,将factory对象的getTagName方法返回的字符串作为键,将factory对象本身作为值,添加到factoryMap中,表示将过滤器的名称和实例映射起来。
  • } 这行代码表示结束for循环。
public IntentFirewall(AMSInterface ams) {mAms = ams;readRules(getRulesFile());}

用于获取规则文件的对象,它返回一个文件类型的常量,表示规则文件的位置。它调用了Environment类的getSystemSecureDirectory方法,获取系统的安全目录,然后在该目录下创建一个名为"ifw/ifw.xml"的文件。

private void readRules(File rulesFile) {FileInputStream fis;try {fis = new FileInputStream(rulesFile);} catch (FileNotFoundException ex) {// Nope, no rules. Nothing else to do!return;}try {XmlPullParser parser = Xml.newPullParser();parser.setInput(fis, null);XmlUtils.beginDocument(parser, TAG_RULES);int outerDepth = parser.getDepth();while (XmlUtils.nextElementWithin(parser, outerDepth)) {IntentResolver<FirewallIntentFilter, Rule> resolver = null;String tagName = parser.getName();if (tagName.equals(TAG_ACTIVITY)) {resolver = mActivityResolver;} else if (tagName.equals(TAG_SERVICE)) {resolver = mServiceResolver;} else if (tagName.equals(TAG_BROADCAST)) {resolver = mBroadcastResolver;}if (resolver != null) {Rule rule = new Rule();try {rule.readFromXml(parser);} catch (XmlPullParserException ex) {Slog.e(TAG, "Error reading intent firewall rule", ex);continue;} catch (IOException ex) {Slog.e(TAG, "Error reading intent firewall rule", ex);continue;}for (int i=0; i<rule.getIntentFilterCount(); i++) {resolver.addFilter(rule.getIntentFilter(i));}}}} catch (XmlPullParserException ex) {Slog.e(TAG, "Error reading intent firewall rules", ex);} catch (IOException ex) {Slog.e(TAG, "Error reading intent firewall rules", ex);} finally {try {fis.close();} catch (IOException ex) {Slog.e(TAG, "Error while closing " + rulesFile, ex);}}}
  • 这个方法的参数是一个File类型的对象,表示存储过滤规则的XML文件。
  • 这个方法首先定义了一个FileInputStream类型的变量,用于读取文件的内容,然后使用一个try-catch语句,尝试创建一个FileInputStream对象,如果发生FileNotFoundException异常,就表示没有找到规则文件,就直接返回。
  • 然后使用另一个try-catch-finally语句,尝试解析文件的内容,如果发生XmlPullParserException或IOException异常,就表示读取过滤规则时出错,就打印一条错误信息,最后无论是否发生异常,都尝试关闭文件输入流,如果发生IOException异常,就表示关闭文件时出错,就打印一条错误信息。
  • 在try语句中,创建一个XmlPullParser对象,用于解析XML文件的内容,然后设置输入源为文件输入流,使用默认的编码格式,然后开始解析XML文件,并检查根元素的标签是否为rules。
  • 然后获取XML文件的初始深度,然后使用一个while循环,在当前深度范围内,查找下一个元素的开始标签,如果找到,就继续循环,否则,就跳出循环。
  • 在循环中,根据当前元素的标签名,选择相应的IntentResolver对象,用于存储和查询不同类型的过滤规则,如果找到了匹配的IntentResolver对象,就创建一个Rule对象,用于存储当前元素的过滤规则,然后使用一个try-catch语句,尝试从当前元素的属性和子元素中读取过滤规则的条件和动作,如果发生异常,就打印一条错误信息,然后继续循环。
  • 在try语句中,使用一个for循环,遍历Rule对象的所有IntentFilter对象,每个IntentFilter对象都是一个FirewallIntentFilter类型的实例,用于定义过滤规则的匹配条件,比如动作、类别、数据等,然后将每个IntentFilter对象添加到IntentResolver中,用于后续的过滤和查询。

这段代码是IntentFirewall类的一个私有方法,用于从文件中读取过滤规则,并将其添加到相应的IntentResolver中,它使用了XmlPullParser对象来解析XML文件的内容,然后使用Rule对象和IntentFilter对象来存储和管理过滤规则的条件和动作。

 static Filter parseFilter(XmlPullParser parser) throws IOException, XmlPullParserException {String elementName = parser.getName();FilterFactory factory = factoryMap.get(elementName);if (factory == null) {throw new XmlPullParserException("Unknown element in filter list: " + elementName);}return factory.newFilter(parser);}
  • 这个方法的参数是一个XmlPullParser类型的对象,表示用于解析XML文件的解析器,它抛出了IOException和XmlPullParserException两种异常,表示可能发生的输入输出错误和解析错误。
  • 这个方法的返回值是一个Filter类型的对象,表示根据XML文件中的元素创建的过滤器,过滤器是用于定义过滤条件的接口。
  • 这个方法首先调用parser对象的getName方法,获取当前元素的标签名,然后将其赋值给一个字符串变量,名为elementName。
  • 然后使用factoryMap对象的get方法,根据elementName作为键,从哈希映射中获取对应的值,这个值是一个FilterFactory类型的对象,表示用于创建和管理过滤器的工厂,然后将其赋值给一个FilterFactory类型的变量,名为factory。
  • 如果factory变量为null,表示没有找到匹配的过滤器工厂,就抛出一个XmlPullParserException异常,表示在过滤器列表中存在未知的元素,异常的信息包含了elementName的值。
  • 如果factory变量不为null,表示找到了匹配的过滤器工厂,就调用factory对象的newFilter方法,传入parser对象作为参数,从当前元素的属性和子元素中创建一个新的过滤器对象,然后将其返回。

这段代码是一个静态的方法,用于根据XML文件中的元素创建一个过滤器对象,它使用了一个哈希映射来存储过滤器工厂的映射,然后根据元素的标签名来查找和创建过滤器,如果没有找到匹配的过滤器工厂,就抛出一个异常。

    private static class Rule extends AndFilter {private static final String TAG_INTENT_FILTER = "intent-filter";private static final String ATTR_BLOCK = "block";private static final String ATTR_LOG = "log";private final ArrayList<FirewallIntentFilter> mIntentFilters =new ArrayList<FirewallIntentFilter>(1);private boolean block;private boolean log;@Overridepublic Rule readFromXml(XmlPullParser parser) throws IOException, XmlPullParserException {block = Boolean.parseBoolean(parser.getAttributeValue(null, ATTR_BLOCK));log = Boolean.parseBoolean(parser.getAttributeValue(null, ATTR_LOG));super.readFromXml(parser);return this;}@Overrideprotected void readChild(XmlPullParser parser) throws IOException, XmlPullParserException {if (parser.getName().equals(TAG_INTENT_FILTER)) {FirewallIntentFilter intentFilter = new FirewallIntentFilter(this);intentFilter.readFromXml(parser);mIntentFilters.add(intentFilter);} else {super.readChild(parser);}}public int getIntentFilterCount() {return mIntentFilters.size();}public FirewallIntentFilter getIntentFilter(int index) {return mIntentFilters.get(index);}public boolean getBlock() {return block;}public boolean getLog() {return log;}}
  • 这段代码定义了一个私有的静态的内部类,名为Rule,继承了AndFilter类,用于表示一个过滤规则,包括过滤条件和过滤动作。
  • 这个类定义了两个私有的静态的最终的字符串常量,分别是TAG_INTENT_FILTER和ATTR_BLOCK,值分别是"intent-filter"和"block",用于表示XML文件中的元素的标签和属性。
  • 这个类定义了另外两个私有的静态的最终的字符串常量,分别是ATTR_LOG和ATTR_BLOCK,值分别是"log"和"block",用于表示XML文件中的元素的属性。
  • 这个类定义了一个私有的最终的ArrayList变量,名为mIntentFilters,类型为ArrayList,值为一个新的ArrayList对象,用于存储过滤规则的所有IntentFilter对象,IntentFilter对象是用于定义过滤条件的对象,比如动作、类别、数据等。
  • 这个类定义了两个私有的布尔变量,分别是block和log,用于表示过滤动作,block为true表示阻止Intent的传递,log为true表示记录Intent的信息。
  • 这个类重写了AndFilter类的readFromXml方法,用于从XML文件中读取过滤规则的条件和动作,它接收一个XmlPullParser类型的参数,表示用于解析XML文件的解析器,它抛出了IOException和XmlPullParserException两种异常,表示可能发生的输入输出错误和解析错误。
  • 这个方法首先调用parser对象的getAttributeValue方法,传入null和ATTR_BLOCK作为参数,获取当前元素的block属性的值,然后使用Boolean类的parseBoolean方法,将字符串值转换为布尔值,然后赋值给block变量。
  • 然后调用parser对象的getAttributeValue方法,传入null和ATTR_LOG作为参数,获取当前元素的log属性的值,然后使用Boolean类的parseBoolean方法,将字符串值转换为布尔值,然后赋值给log变量。
  • 然后调用父类的readFromXml方法,传入parser对象作为参数,从当前元素的子元素中读取过滤条件,比如AndFilter,OrFilter,NotFilter,StringFilter等,然后将它们添加到过滤条件的列表中。
  • 最后,返回当前的Rule对象,表示读取完成。
  • readChild:重写了AndFilter类的readChild方法,用于从XML文件中读取过滤规则的子元素,它接收一个XmlPullParser类型的参数,表示用于解析XML文件的解析器,它抛出了IOException和XmlPullParserException两种异常,表示可能发生的输入输出错误和解析错误。
    这个方法首先判断当前元素的标签名是否等于TAG_INTENT_FILTER常量,这是一个字符串常量,值为"intent-filter",用于表示XML文件中的IntentFilter元素的标签,IntentFilter元素是用于定义过滤条件的元素,比如动作、类别、数据等。
    如果当前元素的标签名等于TAG_INTENT_FILTER常量,就表示当前元素是一个IntentFilter元素,就创建一个FirewallIntentFilter类型的对象,名为intentFilter,传入当前的Rule对象作为参数,表示这个IntentFilter属于这个Rule,然后调用intentFilter对象的readFromXml方法,传入parser对象作为参数,从当前元素的属性和子元素中读取IntentFilter的内容,然后将intentFilter对象添加到mIntentFilters变量中,这是一个ArrayList类型的变量,用于存储当前Rule的所有IntentFilter对象。
    如果当前元素的标签名不等于TAG_INTENT_FILTER常量,就表示当前元素是一个其他类型的过滤条件元素,比如AndFilter,OrFilter,NotFilter,StringFilter等,就调用父类的readChild方法,传入parser对象作为参数,从当前元素的属性和子元素中读取过滤条件的内容,然后将它们添加到过滤条件的列表中。总结:用于从XML文件中读取过滤规则的子元素,它根据当前元素的标签名,判断是一个IntentFilter元素还是一个其他类型的过滤条件元素,然后分别处理它们,将它们添加到当前Rule的过滤条件的列表中。

这段代码是一个私有的静态的内部类,是一个表示过滤规则的类,它继承了AndFilter类,定义了过滤条件和过滤动作,可以从XML文件中读取和创建。

private static class FirewallIntentFilter extends IntentFilter {private final Rule rule;public FirewallIntentFilter(Rule rule) {this.rule = rule;}}
  • 这段代码定义了一个私有的静态的内部类,名为FirewallIntentFilter,继承了IntentFilter类,用于表示一个过滤器,它可以匹配Intent的属性,比如动作、类别、数据等。
  • 这个类定义了一个私有的最终的Rule类型的变量,名为rule,用于表示这个过滤器所属的过滤规则,过滤规则是用于定义过滤条件和过滤动作的类,比如阻止或记录Intent的传递。
  • 这个类定义了一个公共的构造方法,接收一个Rule类型的参数,表示要创建的过滤器所属的过滤规则,然后将其赋值给rule变量,表示初始化过滤器的状态。

这段代码是一个私有的静态的内部类,用于表示一个过滤器,它继承了IntentFilter类,定义了一个过滤规则的变量,提供了一个构造方法,用于创建和初始化过滤器的对象。

private static class FirewallIntentResolverextends IntentResolver<FirewallIntentFilter, Rule> {@Overrideprotected boolean allowFilterResult(FirewallIntentFilter filter, List<Rule> dest) {return !dest.contains(filter.rule);}@Overrideprotected boolean isPackageForFilter(String packageName, FirewallIntentFilter filter) {return true;}@Overrideprotected FirewallIntentFilter[] newArray(int size) {return new FirewallIntentFilter[size];}@Overrideprotected Rule newResult(FirewallIntentFilter filter, int match, int userId) {return filter.rule;}@Overrideprotected void sortResults(List<Rule> results) {// there's no need to sort the resultsreturn;}}

这个类重写了IntentResolver类的以下方法:

  • allowFilterResult:用于判断是否允许将过滤器的结果添加到目标列表中,它接收一个FirewallIntentFilter类型的参数,表示要添加的过滤器,和一个List类型的参数,表示目标列表,它返回一个布尔值,表示是否允许添加。这个方法的逻辑是,如果目标列表中已经包含了过滤器所属的规则,就返回false,表示不允许重复添加,否则,就返回true,表示允许添加。
  • isPackageForFilter:用于判断一个包名是否适用于一个过滤器,它接收一个字符串类型的参数,表示要判断的包名,和一个FirewallIntentFilter类型的参数,表示要判断的过滤器,它返回一个布尔值,表示是否适用。这个方法的逻辑是,直接返回true,表示任何包名都适用于任何过滤器,不需要进行过滤。
  • newArray:用于创建一个指定大小的FirewallIntentFilter类型的数组,它接收一个整数类型的参数,表示要创建的数组的大小,它返回一个FirewallIntentFilter类型的数组,表示创建的数组。这个方法的逻辑是,使用new关键字,创建一个FirewallIntentFilter类型的数组,传入size参数作为数组的长度,然后返回这个数组。
  • newResult:用于创建一个新的过滤规则的结果,它接收一个FirewallIntentFilter类型的参数,表示匹配的过滤器,一个整数类型的参数match,表示匹配的结果,和一个整数类型的参数userId,表示用户的ID,它返回一个Rule类型的对象,表示创建的结果。这个方法的逻辑是,直接返回过滤器所属的规则,表示这个规则是匹配的结果。
  • sortResults:用于对过滤规则的结果进行排序,它接收一个List类型的参数,表示要排序的结果列表,它没有返回值。这个方法的逻辑是,直接返回,表示不需要对结果进行排序。

这是IntentFirewall类的一个私有的静态的内部类,用于存储和查询不同类型的过滤规则,它重写了IntentResolver类的一些方法,用于实现自定义的过滤逻辑。

public interface AMSInterface {int checkComponentPermission(String permission, int pid, int uid,int owningUid, boolean exported);}

这个接口定义了一个方法,名为checkComponentPermission,用于检查一个组件的权限,它接收以下参数:

  • permission:一个字符串类型的参数,表示要检查的权限的名称,比如android.permission.INTERNET等。
  • pid:一个整数类型的参数,表示要检查的进程的ID,比如1234等。
  • uid:一个整数类型的参数,表示要检查的用户的ID,比如1000等。
  • owningUid:一个整数类型的参数,表示拥有该组件的用户的ID,比如1001等。
  • exported:一个布尔类型的参数,表示该组件是否是可导出的,即是否可以被其他应用访问,比如true或false等。

这个方法的返回值是一个整数类型的值,表示检查的结果,比如PackageManager.PERMISSION_GRANTED表示允许访问,PackageManager.PERMISSION_DENIED表示拒绝访问等。

这是是一个公共的接口,用于表示ActivityManagerService的接口,它定义了一个方法,用于检查一个组件的权限,它接收一些参数,表示要检查的权限、进程、用户、组件等信息,它返回一个值,表示检查的结果。

boolean checkComponentPermission(String permission, int pid, int uid, int owningUid,boolean exported) {return mAms.checkComponentPermission(permission, pid, uid, owningUid, exported) ==PackageManager.PERMISSION_GRANTED;}
boolean signaturesMatch(int uid1, int uid2) {PackageManagerService pm = (PackageManagerService)ServiceManager.getService("package");return pm.checkUidSignatures(uid1, uid2) == PackageManager.SIGNATURE_MATCH;}

这是ntentFirewall类的两个私有方法,用于检查组件的权限和签名,它们分别是:

  • checkComponentPermission:用于检查一个组件的权限,它接收一个字符串类型的参数,表示要检查的权限的名称,和四个整数类型的参数,分别表示要检查的进程的ID,用户的ID,拥有该组件的用户的ID,以及该组件是否是可导出的,它返回一个布尔值,表示是否允许访问。这个方法的逻辑是,调用mAms对象的checkComponentPermission方法,传入相同的参数,然后判断返回值是否等于PackageManager.PERMISSION_GRANTED常量,这是一个整数常量,表示允许访问的结果,如果相等,就返回true,否则,就返回false。mAms对象是一个AMSInterface类型的变量,表示ActivityManagerService的接口,用于管理和调度系统中的四大组件。
  • signaturesMatch:用于检查两个用户的签名是否匹配,它接收两个整数类型的参数,分别表示要检查的两个用户的ID,它返回一个布尔值,表示是否匹配。这个方法的逻辑是,定义一个PackageManagerService类型的变量,名为pm,然后调用ServiceManager类的getService方法,传入一个字符串常量,表示要获取的服务的名称,这个常量是"package",表示要获取的是PackageManagerService,这是一个用于管理和安装应用的服务,然后将返回值强制转换为PackageManagerService类型,然后赋值给pm变量。然后调用pm对象的checkUidSignatures方法,传入两个用户的ID作为参数,然后判断返回值是否等于PackageManager.SIGNATURE_MATCH常量,这是一个整数常量,表示签名匹配的结果,如果相等,就返回true,否则,就返回false。

这两个方法用于检查组件的权限和签名的方法,它们分别调用ActivityManagerService和PackageManagerService的接口,然后根据返回值判断是否允许访问或匹配。

相关文章:

简单介绍一下Android里面的IntentFirewall

源码链接 https://android.googlesource.com/platform/frameworks/base//633dc9b/services/java/com/android/server/firewall/IntentFirewall.java 源码如下&#xff1a; package com.android.server.firewall; import android.content.Intent; import android.content.Inte…...

Stable Diffusion 3 发布及其重大改进

1. 引言 就在 OpenAI 发布可以生成令人瞠目的视频的 Sora 和谷歌披露支持多达 150 万个Token上下文的 Gemini 1.5 的几天后&#xff0c;Stability AI 最近展示了 Stable Diffusion 3 的预览版。 闲话少说&#xff0c;我们快来看看吧&#xff01; 2. 什么是Stable Diffusion…...

【后端】springboot项目

文章目录 1. 2.3.7.RELEASE版本搭建1.1 pom文件1.1.1 方式一1.1.2 方式二 1.2 启动类1.3 测试类 2. 引入Value乱码问题解决 【后端目录贴】 1. 2.3.7.RELEASE版本搭建 1.1 pom文件 1.1.1 方式一 <parent><groupId>org.springframework.boot</groupId><…...

React Native调用摄像头画面及拍照和保存图片到相册全流程

今天主要做了一个demo,功能很简单,就是调用手机摄像头画面,并且可以通过按钮控制拍照以及将图片保存到手机相册的功能,接下来我将从创建项目开始一步一步完成这个demo,各位只需要复制粘贴即可 创建React Native项目 npx react-native init yx_rnDemo --version 0.70.6 // 这里…...

Kubernetes基本部署概念

文章目录 命名空间&#xff08;Namespaecs&#xff09;查看命名空间查看带有命名空间对象下资源 文件存储持久卷&#xff08;pv&#xff0c;Persistent Volumes&#xff09;卷容量卷模式&#xff08;volumeMode&#xff09;访问模式&#xff08;accessModes&#xff09;回收策略…...

QT c++ 海康红外热像仪

//本文描述2通道海康通道红外热像仪预览和抓图 #include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); userID-1; …...

OpenAI 的 GPTs 提示词泄露攻击与防护实战:防御卷(一)

前面的OpenAI DevDay活动上&#xff0c;GPTs技术的亮相引起了广泛关注。随着GPTs的创建权限开放给Plus用户&#xff0c;社区里迅速涌现了各种有趣的GPT应用&#xff0c;这些都是利用了Prompt提示词的灵活性。这不仅展示了技术的创新潜力&#xff0c;也让人们开始思考如何获取他…...

中科大计网学习记录笔记(十五):可靠数据传输的原理

前前言&#xff1a;看过本节的朋友应该都知道本节长度长的吓人&#xff0c;但其实内容含量和之前的差不多&#xff0c;老师在本节课举的例子和解释比较多&#xff0c;所以大家坚持看完是一定可以理解透彻的。本节课大部分是在提出问题和解决问题&#xff0c;先明确出现的问题是…...

五种多目标优化算法(MOGWO、MOJS、NSWOA、MOPSO、MOAHA)性能对比(提供MATLAB代码)

一、5种多目标优化算法简介 1.1MOGWO 1.2MOJS 1.3NSWOA 1.4MOPSO 1.5MOAHA 二、5种多目标优化算法性能对比 为了测试5种算法的性能将其求解9个多目标测试函数&#xff08;zdt1、zdt2 、zdt3、 zdt4、 zdt6 、Schaffer、 Kursawe 、Viennet2、 Viennet3&#xff09;&#xff0…...

力扣:93. 复原 IP 地址

回溯&#xff1a; 1.先定义一个接收的集合&#xff0c;之后再定义一个记录小数点的变量。之后编写回溯函数&#xff0c;终止条件为小数点的个数为3时&#xff0c;同时要判断最后一段的组合的值是否属于ip地址的范围。之后再用for循环来遍历ip地址的组合&#xff0c;先判断组合…...

利用序列化和反序列化实现深拷贝

利用序列化和反序列化可以实现对象的深拷贝,具体步骤如下: 将要深拷贝的对象序列化为字节流。从字节流中反序列化出一个新的对象,即完成了深拷贝。下面是一个示例代码: import java.io.*;class MyClass implements Serializable {private static final long serialVersion…...

【AHK】68键键盘键位布局优化/esc改退格键/回车键

本人习惯使用~作为退格键&#xff0c;但是由于keychron 68键的布局只能用esc平替~来修改&#xff0c;然后也将回车键通过alt和大小写锁定键一起触发 esc::bs ;次步骤与下面步骤相对应&#xff0c;如果是用send bs方式则下面的不生效^esc:: ;通过建立 保留esc功能 send {esc} re…...

计算机体系架构初步入门

&#x1f3ac;个人简介&#xff1a;一个全栈工程师的升级之路&#xff01; &#x1f4cb;个人专栏&#xff1a;高性能&#xff08;HPC&#xff09;开发基础教程 &#x1f380;CSDN主页 发狂的小花 &#x1f304;人生秘诀&#xff1a;学习的本质就是极致重复! 目录 1 计算机五大…...

常见的序列化数据结构方法及其优缺点汇总

文章目录 1. JSON (JavaScript Object Notation)2. XML (eXtensible Markup Language)3. YAML (YAML Aint Markup Language)4. Protobuf (Protocol Buffers)5. MessagePack6. BSON (Binary JSON)7. Avro8. Thrift9. CBOR (Concise Binary Object Representation) 将常见的序列化…...

华清远见嵌入式学习——驱动开发——作业1

作业要求&#xff1a; 通过字符设备驱动分步注册过程实现LED驱动的编写&#xff0c;编写应用程序测试&#xff0c;发布到CSDN 作业答案&#xff1a; 运行效果&#xff1a; 驱动代码&#xff1a; #include <linux/init.h> #include <linux/module.h> #include &l…...

小苯的IDE括号问题(CD) -----牛客小白月赛87(双链表)

C题&#xff1a;C-小苯的IDE括号问题&#xff08;easy&#xff09;_牛客小白月赛87 (nowcoder.com) D题&#xff1a; D-小苯的IDE括号问题&#xff08;hard&#xff09;_牛客小白月赛87 (nowcoder.com) C题代码&#xff1a; #include<bits/stdc.h>using namespace std…...

Redis如何修改key名称

点击上方蓝字关注我 近期出现过多次修改Redis中key名字的场景&#xff0c;本次简介一下如何修改Redis中key名称的方法。 1. 命令行方式修改在Redis中&#xff0c;可以使用rename命令来修改Key的名称。这个命令的基本语法如下&#xff1a; RENAME old_key new_key 在这里&#…...

浅谈redis之SDS

SDS 什么是SDSSDS结构len的作用free的作用buf的作用简单示例 SDS机制重新分配内存分配内存机制小于1MB情况大于1MB情况为什么这样分配 惰性释放内存 什么是SDS SDS&#xff1a;全名 simple dynamic string&#xff0c;意为简单动态字符串&#xff0c;作为redis里的一种数据结构…...

数据结构知识点总结-线性表(1)-线性表的定义、基本操作、顺序表表示

线性表 定义 线性表是具有相同数据类型的N&#xff08;N>0&#xff09;个元素的有限序列&#xff0c;其中N为表长&#xff0c;当N0时线性表是一张空表。 线性表的逻辑特征&#xff1a;每个非空的线性表都有一个表头元素和表尾元素&#xff0c;中间的每个元素有且仅有一个直…...

Spring Boot 手写starter!!!

原因&#xff1a;为什么要手写starter&#xff1f;&#xff1f;&#xff1f; 原因&#xff1a;简化功能。 实例&#xff1a;以分页为例&#xff1a;写一个starter。 1.首先定义一个PageX注解。 Target({ElementType.METHOD}) Retention(RetentionPolicy.RUNTIME) Documented p…...

移动端自动化常用的元素定位工具 介绍

在移动端自动化测试和开发中&#xff0c;元素定位是非常关键的一步。以下是一些常用的工具和技术来帮助开发者或测试工程师在移动设备上定位元素&#xff1a; 1. **UiAutomator**: - **UiAutomator** 是 Android 官方提供的自动化测试框架。它可以用来编写测试脚本&…...

问题:Spark SQL 读不到 Flink 写入 Hudi 表的新数据,打开新 Session 才可见

博主历时三年精心创作的《大数据平台架构与原型实现&#xff1a;数据中台建设实战》一书现已由知名IT图书品牌电子工业出版社博文视点出版发行&#xff0c;点击《重磅推荐&#xff1a;建大数据平台太难了&#xff01;给我发个工程原型吧&#xff01;》了解图书详情&#xff0c;…...

数学建模资料分享

1. 往年各赛题的优秀论文 可以用来参考一下论文是怎么写的。参考论文的结构&#xff0c;格式&#xff0c;思路等等。 链接&#xff1a;https://pan.baidu.com/s/1WG2t4-x9MjtaSgkq4ue5AQ?pwdnlzx 提取码&#xff1a;nlzx --来自百度网盘超级会员V4的分享 2.论文模板 链接&a…...

应用配置管理

一、Pod 配置管理 可变配置用 ConfigMap&#xff1b; 敏感信息用 Secret&#xff1b; 身份认证用 ServiceAccount 这几个独立的资源来实现的&#xff1b; 资源配置用 Resources&#xff1b; 安全管控用 SecurityContext&#xff1b; 前置校验用 InitContainers 这几个在 …...

This dependency was not found解决方法

问题如上(前端代码)&#xff0c;我是引用js文件出的问题&#xff0c;无法找到api/userManage模块。 解决&#xff1a;没感觉哪有问题&#xff0c;把后面加了个/&#xff0c;就解决了&#xff0c;代表src目录&#xff0c;应该是目录和目录之间应该有/作为分割&#xff1a;...

基于SpringBoot的停车场管理系统

基于SpringBootVue的停车场管理系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatis工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 前台首页 停车位 个人中心 管理员界面 摘要 摘要&#xff1a;随着城市化进程的…...

SQL库操作

1、创建数据库 概念 创建数据库&#xff1a;根据项目需求创建一个存储数据的仓库 使用create database 数据库名字创建 数据库层面可以指定字符集:charset/character set 数据库层面可以指定校对集:collate 创建数据库会在磁盘指定存放处产生一个文件夹 创建语法 create …...

物麒平台根据入耳出耳状态使能或禁止触摸按键实现方法

是否需要申请加入数字音频系统研究开发交流答疑群(课题组)?可加我微信hezkz17, 本群提供音频技术答疑服务,+群赠送语音信号处理降噪算法,蓝牙耳机音频,DSP音频项目核心开发资 料, 1 消息发送 2 消息处理 3 宏开关 4 代码 #include "app_main.h" #include &q…...

CAS5.3使用JPA实现动态注册服务

cas同时支持cas协议和OAuth2协议,官方默认是通过扫描json文件的形式注册客户端服务,但是此种方式需要重启服务才能生效,此次我们将使用JPA来完美实现动态注册服务,如果不知道cas如何部署,可以擦看之前的文章 cas-client基于CAS协议客户端搭建-CSDN博客 cas-server5.3自定义密…...

unity ui界面优化

优化一个比较复杂的界面&#xff0c;里面有多个rt和组件。 在初次打开这个界面的时候会发生1s多的卡顿&#xff0c;还是非常严重的。 分析 通过profiler分析 1.打开界面时卡顿。 分析&#xff1a;除了update和dotween相关逻辑&#xff0c;主要在于打开时的lua function调用…...