gpt4 book ai didi

android - Android 的 UriMatcher 的问题

转载 作者:IT王子 更新时间:2023-10-28 23:35:36 26 4
gpt4 key购买 nike

在对我之前的问题的回答中,有人指出 Android 类 UriMatcher 中存在一些固有缺陷(因为没有更好的词)。任何人都可以查明 UriMatcher 的已知问题吗?我正在设计一个依赖 UriMatcher 正确匹配我的 Uris 的内容提供程序(而不是我想的不正确)。已知问题是否有解决方法?还是有更好的匹配 Uris 的策略?

例子:

这是设置我的 UriMatcher 的代码

private static final int MEMBER_COLLECTION_URI = 1;
private static final int MEMBER_SINGLE_URI = 2;
private static final int SUBMATERIAL_COLLECTION_URI = 3;
private static final int SUBMATERIAL_SINGLE_URI = 4;
private static final int JOBNAME_COLLECTION_URI = 5;
private static final int JOBNAME_SINGLE_URI = 6;
private static final int ALL_MEMBERS_URI = 7;
private static final int ALL_SUBMATERIAL_URI = 8;

static
{
//return the job and fab for anything matching the provided jobName
// JobNames/jobName
uriMatcher.addURI(JobMetaData.AUTHORITY, "JobNames/*/",
JOBNAME_SINGLE_URI);
//return a collection of members
// jobName/member/attribute/value
uriMatcher.addURI(JobMetaData.AUTHORITY, "*/member/*/*/",
MEMBER_COLLECTION_URI);
//return a single member
// jobName/member/memberNumber
uriMatcher.addURI(JobMetaData.AUTHORITY, "*/member/*/",
MEMBER_SINGLE_URI);
//return a collection of submaterial
// jobName/submaterial/attribute/value
uriMatcher.addURI(JobMetaData.AUTHORITY, "*/submaterial/*/*",
SUBMATERIAL_COLLECTION_URI);
//return a single piece of submaterial
// jobName/submaterial/GUID
//GUID is the only way to uniquely identify a piece of submaterial
uriMatcher.addURI(JobMetaData.AUTHORITY, "*/submaterial/*",
SUBMATERIAL_SINGLE_URI);
//Return everything in the member and submaterial tables
//that has the provided attribute that matches the provided value
// jobName/attribute/value
//not currently used
uriMatcher.addURI(JobMetaData.AUTHORITY, "JobNames/",
JOBNAME_COLLECTION_URI);
//return all members in a job
uriMatcher.addURI(JobMetaData.AUTHORITY, "*/members/",
ALL_MEMBERS_URI);

}

添加另一个 Uri:

private static final int MEMBER_COLLECTION_URI = 1;
private static final int MEMBER_SINGLE_URI = 2;
private static final int SUBMATERIAL_COLLECTION_URI = 3;
private static final int SUBMATERIAL_SINGLE_URI = 4;
private static final int JOBNAME_COLLECTION_URI = 5;
private static final int JOBNAME_SINGLE_URI = 6;
private static final int ALL_MEMBERS_URI = 7;
private static final int ALL_SUBMATERIAL_URI = 8;
//ADDITIONAL URI
private static final int REVERSE_URI = 9;

static
{
//return the job and fab for anything matching the provided jobName
// JobNames/jobName
uriMatcher.addURI(JobMetaData.AUTHORITY, "JobNames/*/",
JOBNAME_SINGLE_URI);
//return a collection of members
// jobName/member/attribute/value
uriMatcher.addURI(JobMetaData.AUTHORITY, "*/member/*/*/",
MEMBER_COLLECTION_URI);
//return a single member
// jobName/member/memberNumber
uriMatcher.addURI(JobMetaData.AUTHORITY, "*/member/*/",
MEMBER_SINGLE_URI);
//return a collection of submaterial
// jobName/submaterial/attribute/value
uriMatcher.addURI(JobMetaData.AUTHORITY, "*/submaterial/*/*",
SUBMATERIAL_COLLECTION_URI);
//return a single piece of submaterial
// jobName/submaterial/GUID
//GUID is the only way to uniquely identify a piece of submaterial
uriMatcher.addURI(JobMetaData.AUTHORITY, "*/submaterial/*",
SUBMATERIAL_SINGLE_URI);
//Return everything in the member and submaterial tables
//that has the provided attribute that matches the provided value
// jobName/attribute/value
//not currently used
uriMatcher.addURI(JobMetaData.AUTHORITY, "JobNames/",
JOBNAME_COLLECTION_URI);
//return all members in a job
uriMatcher.addURI(JobMetaData.AUTHORITY, "*/members/",
ALL_MEMBERS_URI);
//ADDITIONAL URI
uriMatcher.addURI(JobMetaData.AUTHORITY, "*/reverse/*",
REVERSE_URI);

}

最后一个 Uri 无法识别: uriMatcher.match(uri)

在上一个问题(前面提到过)中,建议我将有问题的 Uri 移到对 UriMatcher.put(String, int) 的调用的顶部。这解决了之前的问题(让我嘴里的味道不好)。使用此代码尝试相同的解决方案会导致当前的第一个 Uri (JOBNAME_SINGLE_URI) 无法识别。我相当确定问题不在我的代码中(我已经设法使用 Uris 创建了一个工作的 ContentProvider 并在此问题之前调试了它们的所有问题),而是 Android 中 Uri 匹配的问题.

更新:

public final static String AUTHORITY = "dsndata.sds2mobile.jobprovider";

示例 Uri:
content://dsndata.sds2mobile.jobprovider/SDS2MobileDemo/reverse/C_1

最佳答案

有三个规则没有很好的记录,但对于理解 UriMatcher 的匹配机制至关重要:

  1. UriMatcher 尝试将整个 Uri 与模式进行匹配。很像 java.util.regex.Matcher 的 matches() 方法,它仅在整个区域序列与匹配器的模式匹配时才返回 true(与 find() 方法对部分匹配返回 true 相比)。
  2. 通配符仅应用于一个路径段,这意味着 * 或 SDS2MobileDemo/* 永远不会匹配 SDS2MobileDemo/reverse/C_1 但 */*/* 或 */*/C_1 会。
  3. 一旦找到路径段的匹配项,它就不会找到该特定路径段的任何替代匹配项。

以下是一些使用以下网址的示例:content://dsndata.sds2mobile.jobprovider/SDS2MobileDemo/reverse/C_1

前两条规则很容易理解:

  • SDS2MobileDemo/*/* 将匹配
  • */reverse/* 将匹配
  • */* 不会匹配,因为它只匹配两个路径段
  • SDS2MobileDemo 不匹配,因为它只匹配一个路径段

第三条规则有点难以理解。如果您按此确切顺序添加以下 Uris:

  • */错误/C_1
  • SDS2MobileDemo/reverse/C_1

然后它将找不到匹配项,因为这会转换为以下(伪)代码:

if ("*".matches("SDS2MobileDemo")) {    
// tries to match the other parts but fails
}
else if ("SDS2MobileDemo".matches("SDS2MobileDemo")) {
// will never be executed
}

如果你颠倒顺序,(伪)代码变成:

if ("SDS2MobileDemo".matches("SDS2MobileDemo")) {    
// tries to match the other parts and succeeds
}
else if ("*".matches("SDS2MobileDemo")) {
// will never be executed
}

现在就最初的问题而言。SDS2MobileDemo/reverse/C_1 将与 */reverse/* 匹配,但不是例如JobNames/reverse/C_1 因为那个会沿着 JobNames/* 路径...同样很明显,将 */reverse/* 移到顶部不是解决方案,因为所有其他不以 * 开头的模式将不再匹配。只要不知道哪个模式应该匹配哪个 Uris,就真的不知道正确的解决方案是什么。

关于android - Android 的 UriMatcher 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5030094/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com